初めてのIE操作(2)~起動中のIEを取得するFunction

ウインドウのタイトルを元に起動中のIEを取得するFunction

前回

akashi-keirin.hatenablog.com

の続き。

ページのURLや、HTMLソースが分からないときがある。

Webアプリで移動した先のページなんかの場合だ。たいていアドレスバーが切られていたりするし、右クリックしても、ショートカットキー([Ctrl]+[U])を押してもソースが表示されない。

そんな場合にどうするか。

ウインドウが開いているのだから、それを頼りにIEオブジェクトを取得し、そのHTMLドキュメントオブジェクトから取得すれば良い。

そのためには、まず起動中のIEを取得する必要がある。

この件についてはコチラのページを大いに参考にさせていただいた。

既に開かれているInternetExplorerを取得する(起動済みIEオブジェクトの取得)

開いているウインドウを片っ端から調べ、それが「Internet Explorer」であり、かつウインドウのタイトルが一致していればオブジェクトとして取得する、というやり方。

コード

前回のMicrosoft HTML Object LibraryMicrosoft Internet Controlsに加え、Microsoft Shell Controls And AutomationMicrosoft Scripting Runtimeにチェックを入れている。

リスト1 標準モジュール
Public Function getIEByTitle( _
                  ByVal targetTitleKey As String) As InternetExplorer
  Dim ieApp As New InternetExplorer
  Dim shellApp As New Shell
  Dim shellWin As Object
  For Each shellWin In shellApp.Windows    '……(1)'
    If shellWin.Name = "Internet Explorer" Then    '……(2)'
      On Error Resume Next    '……(3)'
      If InStr(1, shellWin.Document.Title, targetTitleKey) > 0 Then    '……(4)'
        If Err.Number = 0 Then    '……(5)'
          Set ieApp = shellWin
          Exit For
        End If
      End If
      On Error GoTo 0    '……(6)'
    End If
  Next
  If ieApp Is Nothing Then Exit Function
  Set getIEByTitle = ieApp    '……(7)'
End Function

Shellオブジェクトを使って、Windowsの「エクスプローラー」にアクセスする、というやり方。

(1)の

For Each shellWin In shellApp.Windows

で、Windowsの「エクスプローラー」に当たるものをしらみつぶしにする。

変数shellWinに入るのはInternetExplorer型のオブジェクトとは限らない(通常の「エクスプローラー」(フォルダを開いた時のアレ)の場合がある)ので、Object型にしている。

ここからForループ内部。

まず(2)の

If shellWin.Name = "Internet Explorer" Then

で、変数shellWin内のオブジェクトのNameプロパティの文字列を調べる。

オブジェクトの正体がIEオブジェクトなら、「Internet Exprorer」が返る。通常のエクスプローラーオブジェクトなら、「エクスプローラー」が返る。

Internet Explorer」以外の値が返っているならさっさと次へ行く。「Internet Explorer」が返っているなら第一関門突破。Then以下へ進む。

(3)で

On Error Resume Next

として、エラーが出ても無視して次へ進むようにしている。これは、(4)の

If InStr(1, shellWin.Document.Title, targetTitleKey) > 0 Then

を評価する際に、変数shellWinオブジェクトにDocumentプロパティがなかったりするとエラーになってしまうため。

エラーが出たからといってここで止まってしまっては、求めているShellのウインドウにたどり着けない。

本題に戻る。(4)の

If InStr(1, shellWin.Document.Title, targetTitleKey) > 0 Then

では、変数shellWinに入っているオブジェクトからDocumentオブジェクトを取得、そのTitleプロパティの文字列に、引数で渡したtargetTitleKeyの文字が含まれているかどうかを調べている。

含まれていれば、InStr関数が1以上の整数を返すので、Then以下に進む。

(5)からの4行

If Err.Number = 0 Then
  Set ieApp = shellWin
  Exit For
End If

では、エラーが出ていないか調べて、大丈夫だったら現在のshellWinを返り値用の変数ieAppにセットしてForループから脱する。

今にして思えば、エラーの状態を調べるというのは不要かも知れない……。

ちなみに、次のループに進む前に(6)の

On Error GoTo 0

エラーをリセットしておく。

最後に(7)の

Set getIEByTitle = ieApp

で捕まえたIEオブジェクトをreturnしておしまい。

使ってみる

次のコードで実行。

スト2 標準モジュール
Public Sub test()
  Dim targetIE As New InternetExplorer
  With targetIE
    .Visible = True
    Call .Navigate("http://akashi-keirin.hatenablog.com/entry/2018/12/16/001606")
    Do While .Busy Or _
             .readyState <> READYSTATE_COMPLETE
      DoEvents
    Loop
  End With
  Set targetIE = getIEByTitle("素人が")    '……※'
  Debug.Print targetIE.Document.Title    '……※'
  Debug.Print targetIE.Document.locationURL
End Sub

リスト1のgetIEByTitleメソッドにキーワード「"素人が"」を渡して、起動中のIEオブジェクトを捕まえ、そのDocumentオブジェクトのTitleプロパティとlocationURLプロパティの値をイミディエイト・ウインドウに表示させるコード。

ちなみに、実行時は、ステップ実行で読み込み待ちの時間を調整した。

ページを読み込んで準備完了になるまでに次のコードを実行したりするとエラーになるので、本来はいろいろチューニングしないといけないんだけれど、めんどくさいので省略。

実行結果

上記コード中の※のところにブレークポイントを設定して、十分に待ち時間を取って実行した。

f:id:akashi_keirin:20181216202031j:plain

このとおり、ウインドウのタイトルと、ページのURLが表示されている。

WebアプリのページURLが分からないときは、この方法で取得が可能。

実は、ページのHTMLソースも、この時点で取得できたも同然だったりする。

そのあたりは次回。

参考

akashi-keirin.hatenablog.com

akashi-keirin.hatenablog.com

akashi-keirin.hatenablog.com