Excel VBAで実用ツール(Internet Explorer編)

2024-01-07

■Internet Explorerを利用して、HTML文書の内容を表示するツール

Microsoftのサポートが終了しようとしている状況の中、今さらInternet Explorer(IE)でもないと思うものの、Excel VBAから簡単にブラウザを操作できるため、IEを利用してHTML文書の内容を表示するツールをご紹介します(※)。

(※)単にHTML文書を参照するだけであればIEは不要ですが、スクリプトを使用してHTMLを動的に生成している場合には、ブラウザを動かさないと実際の(生成後の)HTML文書を参照することができません。
⇒ブラウザを使用せずにHTML文書を参照する方法については、Excel VBAでオブジェクト指向プログラミング(HTMLドキュメント編)を参照して下さい。

IEを利用してHTML文書の内容を取得する処理の大まかな流れは、以下の通りです。
(1)Shell関数でIEを起動し、Sleep関数で待機
(2)ShellオブジェクトでIEのWindowを検索し、Internet ControlsでInternetExplorerオブジェクトを取得
(3)Internet ExplorerからHTML文書を取得し、HTMLDocumentオブジェクトで内容を参照

各項目の詳細を順にご説明します。

Shell関数でIEを起動し、Sleep関数で待機

Excel VBAのShell関数でIEを起動し、WindowsのSleep関数で3000ミリ秒待機する、というのが標準的な処理方式のようです。

  1. Declare Sub Sleep Lib “kernel32" (ByVal dwMilliseconds As Long)   '標準モジュールの宣言部で定義
  2. Shell “IEのパス URL", vbNormalFocus
  3. Sleep 3000

Shell関数はExcel VBAに内蔵されている関数で、使用法は以下の通りです。

(Shell関数の使用法)

  • Shell(pathname, [windowstyle])

Shell関数実行時の戻り値は、実行したプログラムのタスクIDです。
引数として指定できる項目は下表の通りで、指定必須の引数はpathnameだけです。

(Shell関数の引数)

引数 説明
pathname(必須) 実行するプログラムのパスを指定
windowstyle ウィンドウのスタイルを指定
0:vbHide
1:vbNormalFocus
2:vbMinimizedFocus
3:vbMaximizedFocus
4:vbNormalNoFocus
6:vbMinimizedNoFocus

SleepはWindowsの中心的なモジュールである、kernel32.dllで提供されている関数で、使用法は以下の通りです。
⇒使用するためには、標準モジュールの宣言部で定義する必要があります。

(Sleep関数の使用法)

  • Sleep(milliseconds)

引数として、実行を中断する時間をミリ秒単位で指定します。

(参考)WshShellオブジェクトのRunメソッドまたはExecメソッドによるIEの起動

Shell関数の代りにWshShellオブジェクトのRunメソッドまたはExecメソッドを使用して、IEを起動することも可能です。
⇒WshShellオブジェクトの詳細については、Excel VBAで実用ツール(FSO、dirコマンド、WshShellオブジェクト編)を参照して下さい。

(Runメソッドの使用例)

  1. Dim wsh As IWshRuntimeLibrary.WshShell
  2. Set wsh = New IWshRuntimeLibrary.WshShell
  3. wsh.Run “""IEのパス URL"""
  4. Sleep 3000

(Execメソッドの使用例)

  1. Dim wsh As IWshRuntimeLibrary.WshShell
  2. Dim res As WshExec
  3. Set res = wsh.Exec(“IEのパス URL")
  4. Sleep 3000

ShellオブジェクトでIEのWindowを検索し、Internet ControlsでInternetExplorerオブジェクトを取得

前項の処理を実行すると、別のプロセスでIEが起動されますので、ShellオブジェクトでIEのウィンドウを検索し、Internet ControlsでInternetExplorerオブジェクトを取得します。

ShellオブジェクトはMicrosoftから提供されている、WindowsのシェルAPI機能を含むオブジェクトで、Windowsメソッドにより開いているウィンドウのコレクションを取得することができます。

また、Internet ControlsはInternet Explorerの構成要素であり、プログラムからIEの機能を利用するために必要なDLLです。

行番号7のIF文について、筆者は「If win.Name = “Windows Internet Explorer" Then」と記述していますが、「If win.Name = “Internet Explorer" Then」としているサンプル・コーディングをよく見掛けますので、IEのバージョンによって差異があるのかも知れません。

  1. Dim sh As Shell32.Shell
  2. Dim win As Object
  3. Dim ie As SHDocVw.InternetExplorer
  4. Set sh = New Shell32.Shell
  5. For Each win In sh.Windows
  6.     If win.Name = “Windows Internet Explorer" Then
  7.         Set ie = win
  8.         Exit For
  9.     End If
  10. Next

上記のコーディング例では、IEのウィンドウを検索した後、行番号8で「Set ie = win」としていますが、以下のように最初からウィンドウをInternetExplorerオブジェクト(として定義したオブジェクト変数)に代入しても大丈夫です。
行番号6のTypeName関数は、Excel VBAに内蔵されている関数です。

  1. Dim sh As Shell32.Shell
  2. Dim ie As SHDocVw.InternetExplorer
  3. Set sh = New Shell32.Shell
  4. For Each ie In sh.Windows
  5.     If TypeName(ie.document) = “HTMLDocument" Then
  6.         Exit For
  7.     End If
  8. Next

ShellオブジェクトおよびInternet Controlsの参照設定方法は、以下の通りです。

(Shellオブジェクトのライブラリ参照設定)
Visual Basic Editor(VBE)のファイルメニューから[ツール]-[参照設定]を選択し、参照設定ダイアログでMicrosoft Shell Controls And Automationのチェックボックスにチェックを入れ、[OK]ボタンを押下します。
⇒実行時バインディングを行う場合は、「Set sh = CreateObject(“Shell.Application")」のように記述します。

(Internet Controlsのライブラリ参照設定)
Visual Basic Editor(VBE)のファイルメニューから[ツール]-[参照設定]を選択し、参照設定ダイアログでMicrosoft Internet Controlsのチェックボックスにチェックを入れ、[OK]ボタンを押下します。
⇒実行時バインディングを行う場合は、「Set ie = CreateObject(“InternetExplorer.Application")」のように記述します。

Internet ExplorerからHTML文書を取得し、HTMLDocumentオブジェクトで内容を参照

前項の処理で取得したInternetExplorerオブジェクトのDocumentプロパティでHTML文書を取得できますので、後はHTMLDocumentオブジェクトを使用して、操作することが可能になります。
⇒HTMLDocumentオブジェクトの詳細は、Excel VBAでオブジェクト指向プログラミング(HTMLドキュメント編)を参照して下さい。

HTML文書のタグ要素に対して処理を行う場合、以下のようにコーディングします。

  1. Dim doc As MSHTML.HTMLDocument
  2. Dim tag As MSHTML.IHTMLElement
  3. Set doc = ie.document
  4. For Each tag In doc.all
  5.     HTMLのタグ要素に関する処理
  6. Next

上記のコーディング例では、InternetExplorerオブジェクトのDocumentプロパティをHTMLDocumentオブジェクトに代入していますが、この代入処理を省略することも可能です。

  1. Dim tag As MSHTML.IHTMLElement
  2. For Each tag In ie.document.all
  3.     HTMLのタグ要素に関する処理
  4. Next

サンプル・プログラム

行番号10でIEを起動し、行番号11で待機した後、行番号12~17でIEのWindowを検索し、Internet ControlsでInternetExplorerオブジェクトを取得したうえ、行番号19~25の繰返し処理でHTML文書の全てのタグ要素をExcelシートに書き出しています。

  1. Dim sht As Worksheet
  2. Dim sh As Shell32.Shell
  3. Dim ie As SHDocVw.InternetExplorer
  4. Dim tag As MSHTML.IHTMLElement
  5. Dim rcnt As Long
  6. Private Sub Sample1()
  7.     Set sht = ActiveSheet
  8.     sht.Cells.Clear
  9.     Shell “C:\Program Files\Internet Explorer\iexplore.exe https://xxx", vbNormalFocus
  10.     Sleep 3000
  11.     Set sh = New Shell32.Shell
  12.     For Each ie In sh.Windows
  13.         If TypeName(ie.document) = “HTMLDocument" Then
  14.             Exit For
  15.         End If
  16.     Next ie
  17.     rcnt = 0
  18.     For Each tag In ie.document.all
  19.         rcnt = rcnt + 1
  20.         sht.Cells(rcnt, 1) = “'" & TypeName(tag)
  21.         sht.Cells(rcnt, 2) = “'" & tag.tagName
  22.         sht.Cells(rcnt, 3) = “'" & tag.outerHTML
  23.         sht.Cells(rcnt, 3).WrapText = False
  24.     Next tag
  25.     Set tag = Nothing
  26.     Set ie = Nothing
  27.     Set sh = Nothing
  28. End Sub

■Internet Explorerを利用して、Webページを自動で操作するツール

前項のサンプル・プログラムで全てのタグ要素を参照していますので、何らかの方法でタグ要素を特定し、Clicメソッドを実行することにより、Webページをプログラムで操作することができます。

汎用的なプログラムを作成することは難しいですが、特定のWebページに特化したプログラムであれば、簡単に作成することができますので、次項でタグ要素の特定方法とサンプル・プログラムをご紹介します。

タグ要素の特定方法

HTMLDocumentオブジェクトではタグ要素を取得するためのメソッドが提供されていますので、ID属性、クラス名、タグ名、タグ要素名を指定して、タグ要素(IHTMLElementオブジェクトまたはIHTMLElementコレクション)を取得することができます(下表参照)。
⇒HTMLDocumentオブジェクトの詳細については、Excel VBAでオブジェクト指向プログラミング(HTMLドキュメント編)を参照して下さい。

(HTMLDocumentオブジェクトのタグ要素を取得するメソッド)

getElementByIdメソッド
説明 タグ要素のID属性を指定して、1つのタグ要素を取得
定義 Function getElementById(v As String) As IHTMLElement
getElementsByClassNameメソッド
説明 タグ要素のクラス名を指定して、タグ要素のコレクションを取得
定義 Function getElementsByClassName(v As String) As IHTMLElementCollection
getElementsByNameメソッド
説明 タグ名を指定して、タグ要素のコレクションを取得
定義 Function getElementsByName(v As String) As IHTMLElementCollection
getElementsByTagNameメソッド
説明 タグ要素名を指定して、タグ要素のコレクションを取得
定義 Function getElementsByTagName(v As String) As IHTMLElementCollection
getElementsByTagNameNSメソッド
説明 名前空間(Name Space)とタグ要素名を指定して、タグ要素のコレクションを取得
定義 Function getElementsByTagNameNS(pvarNS As Variant, bstrLocalName As String) As IHTMLElementCollection

これらのメソッドでタグ要素を取得できない(特定できない)場合は、前掲のサンプル・プログラムの要領で全てのタグ要素を参照し、タグ要素に含まれる特定の文字列や参照しているURL、ファイル名など、何らかの方法でタグ要素を特定します。

「For Each tag In ie.document.all~Next tag」のような記述で処理を行った場合、全てのタグ要素を参照できる訳ですが、タグ要素がネスト構造(入れ子)になっているため、最初の要素はHTML文書全体(<html>~</html>)、次の要素はヘッド部分(<head>~</head>)というように、外側のタグ要素から内側のタグ要素へ順に返って来ますので、誤って大きな塊を特定してしまわないように(変な場所をクリックしてしまわないように)タグ要素の特定方法に留意する必要があります。
⇒前掲のサンプル・プログラムでHTML文書の内容を表示し、実際の中身を見てタグ要素の特定方法を考えるしかありません。

サンプル・プログラム

あるサイトを自動的に閲覧するツールを作成しましたので、サンプル・プログラムとしてご紹介します。

このサイトは、トップ・ページにコンテンツの目次があって、項目を選んでクリックすると該当すると、1000ページ以上あるコンテンツの1ページ目に遷移するんですが、各ページには「前ページ」と「次ページ」しかないので、1ページずつクリックして動かすしかありませんでした。
「一通り全部のページを閲覧したいが、1000回も手でクリックするのはイヤ」なので、以下のプログラムを作ってボーっと眺めた、という経緯です。

行番号11でIEを起動し、行番号12で待機した後、行番号13~18でIEのWindowを検索し、Internet ControlsでInternetExplorerオブジェクトを取得しています。
行番号19~25の繰返し処理はトップ・ページに関する処理で、行番号21で参照したいコンテンツ名を含むタグ要素を検索し、行番号22でクリックしています。
行番号30~41の繰返し処理は遷移先のページに関する処理(※)で、行番号33で「次ページ」の部分の画像ファイル名を含むタグ要素を検索し、行番号34でクリックしています。

(※)行番号30~41の繰返し処理を固定で1000回繰返すようにしていますが、実際のHTML文書ではコンテンツの各ページに全体のページ数を表す情報を持っていたため、先にその情報を持っているタグ要素を検索してページ数を取得した後、この繰返し処理を行うようにしていました。

  1. Dim sht As Worksheet
  2. Dim sh As Shell32.Shell
  3. Dim ie As SHDocVw.InternetExplorer
  4. Dim tag As MSHTML.IHTMLElement
  5. Dim sStr As String
  6. Dim i As Integer
  7. Private Sub Sample2()
  8.     Set sht = ActiveSheet
  9.     sht.Cells.Clear
  10.     Shell “C:\Program Files\Internet Explorer\iexplore.exe https://xxx", vbNormalFocus
  11.     Sleep 3000
  12.     Set sh = New Shell32.Shell
  13.     For Each ie In sh.Windows
  14.         If TypeName(ie.document) = “HTMLDocument" Then
  15.             Exit For
  16.         End If
  17.     Next ie
  18.     For Each tag In ie.document.all.tags(tagName:="a")
  19.         wStr = tag.getAttribute(strAttributeName:="href")
  20.         If InStr(wStr, “コンテンツ名") Then
  21.             tag.Click
  22.             Exit For
  23.         End If
  24.     Next tag
  25.     Do While ie.Busy = True
  26.         DoEvents
  27.     Loop
  28.     For i = 1 To 1000
  29.         For Each tag In ie.document.all.tags(tagName:="img")
  30.             wStr = tag.outerHTML
  31.             If InStr(wStr, “xxx.png") > 0 Then
  32.                 tag.Click
  33.                 Exit For
  34.             End If
  35.         Next tag
  36.         Do While ie.Busy = True
  37.             DoEvents
  38.         Loop
  39.     Next i
  40.     Set tag = Nothing
  41.     Set ie = Nothing
  42.     Set sh = Nothing
  43. End Sub

国本温子(著),緑川吉行(著),できるシリーズ編集部(著)
出版社:インプレス
発売日:2022/3/23
単行本(ソフトカバー):A5判/912ページ

大村あつし(著),古川順平(著)
出版社:技術評論社
発売日:2021/1/9
単行本(ソフトカバー):A5判/800ページ

高橋宣成(著)
出版社:技術評論社
発売日:2019/11/25
単行本(ソフトカバー):B5変形判/576ページ

実用ツール

Posted by hides