ウインドウのタイトルを元に起動中のIEを取得するFunction
前回
の続き。
ページのURLや、HTMLソースが分からないときがある。
Webアプリで移動した先のページなんかの場合だ。たいていアドレスバーが切られていたりするし、右クリックしても、ショートカットキー([Ctrl]+[U])を押してもソースが表示されない。
そんな場合にどうするか。
ウインドウが開いているのだから、それを頼りにIEオブジェクトを取得し、そのHTMLドキュメントオブジェクトから取得すれば良い。
そのためには、まず起動中のIEを取得する必要がある。
この件についてはコチラのページを大いに参考にさせていただいた。
既に開かれているInternetExplorerを取得する(起動済みIEオブジェクトの取得)
開いているウインドウを片っ端から調べ、それが「Internet Explorer」であり、かつウインドウのタイトルが一致していればオブジェクトとして取得する、というやり方。
コード
前回のMicrosoft HTML Object Library、Microsoft Internet Controlsに加え、Microsoft Shell Controls And AutomationとMicrosoft 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プロパティの値をイミディエイト・ウインドウに表示させるコード。
ちなみに、実行時は、ステップ実行で読み込み待ちの時間を調整した。
ページを読み込んで準備完了になるまでに次のコードを実行したりするとエラーになるので、本来はいろいろチューニングしないといけないんだけれど、めんどくさいので省略。
実行結果
上記コード中の※のところにブレークポイントを設定して、十分に待ち時間を取って実行した。

このとおり、ウインドウのタイトルと、ページのURLが表示されている。
WebアプリのページURLが分からないときは、この方法で取得が可能。
実は、ページのHTMLソースも、この時点で取得できたも同然だったりする。
そのあたりは次回。