スポンサーリンク

Excel VBAでIEを自動操作する際,COMイベントを利用する方法 (WithEventsでブラウザの挙動を細かく把握する)


Excel VBAで,InternetExplorer.Applicationなどの「COMオブジェクト」のイベントを利用する方法。


下記のエントリでは,WSH(JScript/VBScript)からIEを自動操作する際,

「COMアプリケーションイベント」を利用する方法を紹介した。

ブラウザのビジー状態を判定するための,より良い方法 (WSHでIEを自動操作する際,COMのアプリケーションイベントを利用する)
http://language-and-engineering.hatenablog.jp/entry/20100410/p1

  • WScript.CreateObject()の第二引数を使えば,COMオブジェクトのイベントを扱うことが可能


これと同じことをExcel VBAで実現したい場合,方法がWSHとは少し異なる。

すぐ動作可能な,わかりやすいVBAのサンプルコードを下記に掲載する。

' ツール→参照設定 から,
' 「Microsoft Browser Helpers」に
' チェックを入れて参照設定しておくこと。
' 参照設定をしないと「ユーザ定義型は定義されていません。」のエラーになる

' IEを変数として定義
Public WithEvents objIE As InternetExplorer


' メイン
Sub hoge()
    ' イベント検知機能付きのIEを起動する
    Set objIE = CreateObject("InternetExplorer.Application")
        ' CreateObjectの第二引数は,
        ' WSH(JScript/VBScript)だとCOMイベントの接頭辞として利用できるが,
        ' VBやVBAの場合はリモートサーバー名として認識されるため,
        ' 「リモートサーバーがないか、使用できる状態ではありません」
        ' のエラーになる。
    
    ' 空の画面を開く
    objIE.Visible = True
    objIE.Navigate "about:blank"
End Sub


' IEを閉じた時のQuitイベントをフックする
Private Sub objIE_OnQuit()
    ' Excelの画面上にメッセージを表示する
    MsgBox "IEを閉じました"
    Set objIE = Nothing
End Sub

上記のVBAコードを実行すると,まずIEが起動する。

そのIEを閉じると,閉じた時のCOMイベントのリスナが実行される。


同じように,Webページのドキュメントのロード完了を判定するために

DocumentCompleteとかDownloadCompleteイベントを検知させれば,

VBAでもIEのビジー状態の判定をうまく実装する事ができるだろう。

VBAとWSHのソースコードの比較・解説

WSHとVBAでは,CreateObject関数の第二引数の解釈の仕方が異なる。

VB6・VBA関数メモ:CreateObject関数 | フィロの村note
http://note.phyllo.net/?eid=1106215

  • VBAでのCreateObject(Class As String, [ServerName As String]) の仕様:第二引数のServerNameはネットワークサーバ名

もしVBAで,CreateObject関数の第二引数を

間違えてWSH風にコーディングしてしまうと,おかしな事になる。


「オブジェクトを指すための接頭辞」で名前を付けたつもりが,

「ネットワーク上のサーバー名」として解釈されてしまい,通信の結果エラーとなり

  • 「リモート サーバーがないか、使用できる状態ではありません」

というエラーメッセージが出る。


それ関係のエラーに遭遇して苦労している大勢の人たち:

既に開いているIE(タイトル名はgoo)を取得したい | Visual BasicのQ&A【OKWave】
http://okwave.jp/qa/q2653777.html

  • CreateObject("InternetExplorer.Application", "goo")の第二引数でエラー


VBAでIEをコントロールしたいです。 Set objIE = CreateObject("InternetExplorer....
http://detail.chiebukuro.yahoo.co.jp/...

  • CreateObject("InternetExplorer.Application", "IE_")の第二引数でエラー


308-1 | Wscript.CreateObjectが使えないんです。 - VB初心者友の会 - Q&A掲示板(第2)過去ログ
http://www.gizcollabo.jp/vbtomo/log/a...

  • VB環境のCreateObjectの第二引数は、サーバー名の指定に使われます。ここにマシン名を指定することにより、リモート マシン上でオブジェクトを作成できます。ただしこれはVB6の場合で,VB5には第二引数がありません


VBの命令から、ブラウザの更新ボタンを制御するには?
http://homepage1.nifty.com/MADIA/vb/v...

  • VBScriptは、CreateObjectの第2引数を使ってイベントプロシージャ名を決定しますが、VBは「WithEventsキーワード」を使って宣言した変数によって、イベントを受け取ります


このエラーメッセージ(実行時エラー 462)の意味:

2 回目のコード実行時に Excel のオートメーションが失敗する
http://support.microsoft.com/kb/17851...

  • Excel.Applicationのオートメーションを組んだ時に,自動操作の対象オブジェクトと,そうでないオブジェクトに分かれて実装してしまった場合に,片方への参照が残ったままになってしまい,2回目の実行時に「実行時エラー '462': リモート サーバーがないか、使用できる状態ではありません。」のエラーになる。エラーを再現するコード付き


教えて!保険市場 - VBAのChangeFileOpenDirectoryの部分がうまくいきません
http://oshiete.hokende.com/qa2455648....

  • LAN内のフォルダに格納されているファイルを開く処理を実装する際に,ExcelとWordの自動操作の部分で「実行時エラー'462' リモートサーバーがないか、使用できる状態ではありません。」のエラー


Error 462:The remote server machine does not exist or is unavailable-VBForums
http://www.vbforums.com/showthread.ph...

  • you are trying to connect to a remote SQL / Server.If the Server is not found then you will get the msg like this(サーバが見つからないだけ)


excel vba - Error 462 in VBA : remote server machine not found - Stack Overflow
http://stackoverflow.com/questions/54...

  • Word.Applicationでオートメーションを組む時にも同様のエラーが発生しうる


VBAでは,WSHと違って,IEのCOMイベントを検出するためのキーワードは「CreateObject」ではない。

VBE上で特定のライブラリへの参照設定をした上で,「WithEvents」キーワードを使うのである。


VBAのWithEventsでIEのイベントをキャッチする,簡単なサンプルコード集:

InternetExplorerのイベントを取得する / 初心者備忘録
http://www.ka-net.org/office/of33.htm...

  • 「Microsoft HTML Object Library」「Microsoft Internet Controls」への参照設定を使った,簡単なサンプルコード


VBA interacting with new IE window
http://www.mrexcel.com/forum/excel-qu...

  • 「Microsoft Internet Controls」または「Microsoft Browser Helpers」に参照設定する簡単なサンプルコード


42032-0 | WithEventsの使い方について - VB初心者友の会 - Q&A掲示板過去ログ
http://www.gizcollabo.jp/vbtomo/log/a...

  • 「As InternetExplorer」で宣言したプロシージャ外のIEは,パブリック変数である必要がある


三流君VBA:IE アプリケーションのイベントを横取りする
http://www.ken3.org/vba/backno/vba108...


クラスモジュールを使うなど応用的なコード:

トキドキドキンドットコム :: VBAでInternet Explorerの画面遷移をイベントドリブン的に制御する
http://tokidokidokin.com/2010/05/vba%...

  • IEがドキュメントの読み込みを完了したことを確認する判断が難しい。WScriptのCreateObjectとVBAのCreateObjectは仕様が異なるので、VBAだと同様の方法は使えない
  • VBAでInternet Explorerのイベントを補足する為に、クラスモジュールを使うサンプルコード


クラスモジュール に WithEvents で IE操作のコードを書いてみた - ken3memo (三流君)
http://d.hatena.ne.jp/ken3memo/201106...


Orator's IO » ブログアーカイブ » IEのイベントを参照設定なしで受け取る
http://vb-user.com/wp/2012/12/22/96.html

  • イベントを受け取るためにAddHandler ステートメントやWithEvents を使う場合,参照設定なしで COM (ActiveX)のイベント通知を受け取る方法
  • VBの場合は,Visual Studio上でIConnectionPoint インターフェイスを利用する

補足

Yahoo知恵袋で質問に回答する時,自分のブログ上に書かれている有益な情報を紹介しづらい件について:

宣伝行為及び回答の仕方 回答に自分のブログのURL(質問の内容に合っているの...
http://detail.chiebukuro.yahoo.co.jp/...

  • 「blogを知恵袋で貼り付けるのも禁止です。よく宣伝じゃないとか開き直る人がいますが,貼り付けた時点で宣伝と見なされますからご注意下さい」
  • 「知恵袋では小遣いサイトを装った業者が多い。宣伝だけでなく、自作自演もある。質問を立ててからサイトを紹介するなど」


知恵袋でお小遣いサイトなどを宣伝するのは犯罪ですか? ブログで宣伝するのはい...
http://detail.chiebukuro.yahoo.co.jp/...

  • 「質問の内容に沿っていて、かつ質問者さんだけでなくほかの回答者さんが見ても、参考になるモノであれば、自分のサイトのURLだったとしても問題ないのでは」
  • 「よろしければご覧下さいなど,おことわりの文章でも添えておけば、宣伝目的のSPAM行為とは思われないのでは」

関連する記事:

ブラウザの自動操作の最大の問題,「タイムアウト」を克服するには
http://language-and-engineering.hatenablog.jp/entry/20100403/p1


Excel VBAのマクロで,IEを自動操作しよう (DOMセレクタ関数をVBAで自作)
http://language-and-engineering.hatenablog.jp/entry/20090710/p1


JavaScriptの動かないコード (中級編) clickイベントを強制的に発生させたい (fireEvent/createEventの使い方)
http://language-and-engineering.hatenablog.jp/entry/20090907/p1


JavaScriptの動かないコード (中級編) イベント強制発生までの遅延時間をなくしたい
http://language-and-engineering.hatenablog.jp/entry/20090909/p1