[三流君] [VBAで楽しく] [VBA IE 操作]
−−> No.108 IE アプリケーションのイベントを横取りする

IE アプリケーションのイベントを横取りする

概要:

Dim WithEvents IE As InternetExplorer
と
WithEventsキーワードを使って、
IE_NewWindow2(ppDisp As Object, Cancel As Boolean)
と書き、IEのイベントに対して、処理を書いてみました。
テストで下記のようなダウンロード終了時に発生するイベントを書いてみました。
Private Sub WebBrowser0_DocumentComplete(ByVal pDisp As Object, URL As Variant)
    'タイトルの代入
    Me![txtTITLE] = Me.WebBrowser0.Document.Title
    'HTMLの代入
    Me![txtHTML] = Me.WebBrowser0.Document.body.innerhtml
End Sub

※メルマガ記事ではオブジェクトの参照設定をしていませんができれば、下記を参考に参照設定してください。
[Microsoft Internet Controls,Microsoft HTML Object Library を参照設定する](このほうが開発時、操作時に楽)
また、VistaとIE7の場合は、 [IE7 操作 Vistaで失敗]も参考にしてください。

リンク 分類: [Document(文章)からデータを取得] / [Form入力処理] / [Linkリンク情報] / [Image画像情報] / [Frameフレーム処理] サンプル: [IEを使ったVBAのサンプル] / [小さなVBAでIE操作のコード]

メルマガ発行内容

やっと、下記、メルマガで発行した内容です。何かの参考となれば幸いです。
過去のメルマガ[IE操作系の記事一覧]もヨロシクです。

<IE アプリケーションのイベントを横取りする>

どうも、三流プログラマーのKen3です。 今回は、 IEで発生するイベントを横取りしてみます。 いつものように、たいした解説、回答内容じゃないので、 暇つぶしに休み時間などに拾い読みしてください。

/* * 1.今回のキッカケ */

メールで下記の質問をもらいました。 ---- >アクセスからIEにはsendkeys を使ってデータを >移動できますが、その逆を考えているのですが >うまい方法はありませんでしょうか. > >IE フォーム から アクセスのフォーム >また、テーブルに直接でも間接でも宜しい >のですが? ---- IEのデータを取るのかぁ、、、タイミングがなぁ・・・

/* * 2.調べごと、下準備 */

以前、ランキングページからデータを取り込む処理で、 No.52 InternetExplorer.application .document.body.innerText http://www.ken3.org/backno/backno_vba11.html#52 を参照
Sub ie_get_itext() 'VBA052で解説

    Dim objIE    As Object  'IEオブジェクト参照用

    'インターネットエクスプローラーのオブジェクトを作る
    Set objIE = CreateObject("InternetExplorer.application")
    objIE.Visible = True '見えるようにする(お約束)

    'ランキングのページに飛ぶ
    objIE.Navigate "http://www.ken3.org/cgi-bin/lime/limemgr.cgi"

    '表示されるまで待つ、10秒後にエラーを判断する
    Dim time10 As Date  '時刻格納用
    time10 = DateAdd("s", 10, Now())  '現在から10秒後を計算
    Do While objIE.Busy = True   'ビジー、読み込み中の間
        DoEvents
        If time10 < Now() Then   '10秒経過したか?
            MsgBox "タイムアウトです"
            Exit Sub
        End If
    Loop

    'innerTextを取出す
    Dim strTEXT As String
    strTEXT = objIE.document.body.innerText  '変数に代入
    Debug.Print strTEXT  'イミディエイトにも表示
    
    'UserFormを開く(確認用)
    frmINFO.txtINFO.Value = strTEXT  'HTMLを代入
    frmINFO.Show  'フォームを開く

End Sub
ポイントは、 ~~~~~~~~~~~ Set objIE = CreateObject("InternetExplorer.application") objIE.Visible = True '見えるようにする(お約束) を作って、 '表示されるまで待つ、10秒後にエラーを判断する Dim time10 As Date '時刻格納用 time10 = DateAdd("s", 10, Now()) '現在から10秒後を計算 Do While objIE.Busy = True 'ビジー、読み込み中の間 DoEvents If time10 < Now() Then '10秒経過したか? MsgBox "タイムアウトです" Exit Sub End If Loop と 表示されるまで、じっと、.Busyをストーカーのように観察して 彼女が読み込み待ちじゃなくなったら(笑)or10秒であきらめ(笑) つかさず、声をかけ(オイオイ) strTEXT = objIE.document.body.innerText '変数に代入 で、変数に表示結果を代入してます。 これは、プログラムは上から下への基本通りなんで、 プロパティなど、難しいけど、理解すれば簡単です。 流れは、 ・IEのオープン --------- CreateObject("InternetExplorer.application") ・IEで指定ページを開く - objIE.Navigate "URLのとび先を指定" ・読み込み待ち ---------- objIE.Busy = True ・データを代入 ---------- strTEXT = objIE.document.body.innerText と上から下にチェックしながら流れます。 今回の処理は、たぶん、 IE(HTML)のフォームで条件を入力、検索を行う、 検索結果をAccessのテーブルに代入する。 そんな、流れだと思います。 問題ないじゃん?なにか?問題あるの? 条件を入力して、終了したタイミングが取れないんですよ。 条件入力後、SUBMIT後、データを受け取ったら・・・がよくわからない。 ※IEで入力して、結果が得られる、それを横取りしたいので。

/* * 3.IEのイベントを横取りする */

http://msdn.microsoft.com/msdnmag/issues/02/04/ednote/default.aspx ここ見ても、よくわからないんだけど、 英語は、イヤだよ・・・ Dim WithEvents IE As InternetExplorer
Private Sub StartIE
    Set IE = CreateObject("InternetExplorer.Application.1")
    IE.Visible = True
End Sub
You have to create the Internet Explorer object with the WithEvents keyword, which lets you hook its events in your code. Next, you can hook this object's NewWindow2 event:
Private Sub IE_NewWindow2(ppDisp As Object, Cancel As Boolean)

Set IEx = CreateObject("InternetExplorer.Application.1")

   Set ppDisp = IEx
   IEx.Visible = False

End Sub
Private Sub IEx_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, _
  Flags As Variant, TargetFrameName As Variant, PostData As Variant, _ 
  Headers As Variant, Cancel As Boolean)
' Figure out whether the URL requested is on the banned list
' If it is, never show the window or navigate to the site.
' Otherwise, let it through normally.
End Sub
なんだこれ?の Dim WithEvents IE As InternetExplorer を探る、 http://www.microsoft.com/japan/msdn/library/ja/vblr7/html/vakeyWithEvents.asp WithEvents を 見るが、イマイチ。。。 宣言されるオブジェクト変数がイベントを発生させることのできる クラス インスタンスを参照することを示すキーワードです。 へっ?なに?まぁ、わかんないから書いてみよう。 さてと、どうしましょうかねぇ。 テストで新しいウインドウを開くイベントを横取りしてみます。 '忘れずに、MicroSoft Internet Controls を参照設定してください Dim WithEvents IE As InternetExplorer
Private Sub コマンド1_Click()

    '普通にIEのオブジェクトを作成する
    Set IE = CreateObject("InternetExplorer.Application")
    IE.Visible = True '可視をON
    IE.GoHome  '初期ページに移動する

End Sub
'こんなんで、横取りできるの?
Private Sub IE_NewWindow2(ppDisp As Object, Cancel As Boolean)
    MsgBox "新しいウインドウを開こうとしてます"
End Sub
で、無事、右ボタンを押して新規ウインドウを起動すると、 新しいウインドウを開こうとしてます とメッセージが表示されました。 Dim WithEvents IE As InternetExplorer と WithEventsキーワードを使って、 IE_NewWindow2(ppDisp As Object, Cancel As Boolean) と書くだけでOKです。 おっと、これは、 Set IE = CreateObject("InternetExplorer.Application") と、IEのアプリを外側に起動した場合です。 挿入・ActiveXコントロールで Microsoft Web Browser コントロールをフォームに貼った場合は、 もっと簡単で、 フォームのロードイベントで表示して、
Private Sub Form_Load()
    'フォームのロードイベントでGoHomeしてみる
    Me![WebBrowser0].GoHome  '初期ページへ移動
End Sub
Private Sub WebBrowser0_NewWindow2(ppDisp As Object, Cancel As Boolean)
    MsgBox "新しいウインドウを開こうとしてます"
End Sub
で、同じ処理できました。 新規ウインドウを開いたテスト結果↑ WithEventsのキーワード無くて、 ~~~~~~~~~~ WebBrowser0_NewWindow2(ppDisp As Object, Cancel As Boolean) で動いたのは、意外だったけど。 あっ、当たり前なのかも? だって、ボタンだったら、 ボタンのコントロール名_Click で、クリック処理ですよね。 フォームに貼ったMicrosoft Web Browser コントロールのイベントだからか。 ってことは、他のイベントも選択可能かも。 VBAの編集画面で選択してみる。 ↑コントロールの選択 ↑イベントの選択

/* * 4.読み込み完了のイベントを横取りしてみる */

話を戻してと、 やりたいのは、IE上で検索したデータ結果を取り出したい? なので、IEで検索まではユーザーに勝手に操作してもらう。 ユーザーが検索すると、画面の更新(データの読み込み)が発生して、 その後、読み込みが完了する。 読み込み完了、そんなイベントを探ってみます。 DocumentCompleteってイベントがあるらしい。 チッまた英語かよ・・なんか疲れた(笑) http://msdn.microsoft.com/workshop/browser/webbrowser/reference/events/documentcomplete.asp Syntax Private Sub object_DocumentComplete( _ ByVal pDisp As Object, _ ByVal URL As Variant) Parameters object Object expression that resolves to the objects in the Applies To list. pDisp Object that specifies the top-level or frame WebBrowser object corresponding to the event. URL String that specifies the URL, Universal Naming Convention (UNC) file name, or pointer to an item identifier list (PIDL) of the loaded document まぁ、読めないものはショウガナイ、まずはテストしてみます。 _DocumentComplete のイベントが発生したら、.TitleとBodyの中身をテキストボックスに代入してみます。
Private Sub WebBrowser0_DocumentComplete(ByVal pDisp As Object, URL As Variant)
    'ダウンロード終了時に発生すると仮定して
    'タイトルの代入
    Me![txtTITLE] = Me.WebBrowser0.Document.Title
    'HTMLの代入
    Me![txtHTML] = Me.WebBrowser0.Document.body.innerhtml
End Sub
読み込みが完了した時点で、 タイトルとbodyのソースをテキストボックスへ代入してます。

/* * 5.終わりの挨拶 */

今回は、 IE アプリケーションのイベントを横取りする 方法でした。 _NewWindow2 で、新規ウインドウのイベント、 _DocumentComplete で、読み込み完了のイベント、 そんなイベントを横取りしてみました。 パターン1は、WithEventsキーワードを使って、 Dim WithEvents IE As InternetExplorer と IE_NewWindow2(ppDisp As Object, Cancel As Boolean) みたいに、書くだけ。 パターン2は フォームに貼ったMicrosoft Web Browser コントロールのイベントだから 普通に、 WebBrowser0_DocumentComplete WebBrowser0_NewWindow2 など、イベントを記述可能なことをテストしました。 IEで画面が更新された=_DocumentCompleteのドキュメントが読み込まれた と判断して、ユーザーが任意のタイミングで検索した結果を受け取るタイミング を作り出してます。 あとは、力技や、出力結果のHTMLを見て(解析して)、 データを抜き出せば、なんとかなると思います。 サンプルファイルは、 http://www.ken3.org/vba/lzh/vba108.lzh にdb108.mdb(Access2000版)が保存されています。 が、 Microsoft Web Browser コントロールをフォームに貼っているので、 バージョン違いなどで動かない可能性があります。 テストでエラーが発生しても、怒らないでくださいね。 何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。

VBA クラスモジュール に IE操作 の コード を テストで書いてみた

クラスモジュールの正しい使い方、書き方を知らないので、なんか、長いだけの変な解説動画です。

動作ファイルとソースは クラスモジュール に WithEvents で IE操作のコードを書いてみた] をみてください。

Excelのシートにコードを書く

参照設定後、シートにWithEventsを使ってコードを書いてみた

↑こんな方法もあります。
コードは[Dim WithEvents objIE As InternetExplorer Excelシートに書いたコードでイベントを拾う]をみてください。


ページフッター リンクや広告、質問送信など

三流解説を読んでいただき、どうもです。ここから下は、三流君宛のメッセージ送信や 三流君のホームページの紹介・案内です
目的の情報が見つかったか?少々心配しつつ、、、※質問や感想は、気軽に送ってくださいね。

[三流君 VBAでWebBrowser IEを操作する] / [三流君 VBAで楽しくプログラミング] / [AB型の変わり者 三流プログラマー Ken3 三流君Top]

大分類:[Document.Forms(入力処理)] / [Document.Links(リンク情報)] / [Document.Images(画像情報)] / [Document.Frames(フレーム処理)]
サンプル・例題:[過去のメルマガ記事一覧] / [少し大きなIE操作サンプル] / [小さなコードでIE操作の動作確認]

F1でヘルプを見たり、デバック時にDebug.Print使ったり、イミディエイト ウインドウで簡単な確認したり。
なれると当たり前に操作している方法が↓かなぁ。
[F1ヘルプ マクロ記録ほか]・・・基本のF1を押してヘルプを見る方法など
[実行時エラー、デバッグモード]・・・デバッグの流れを簡単に(ハマった時はツライけど)
[イミディエイト ウインドウ と Debug.Print]・・・プログラム作成時に便利なイミディエイト ウインドウ
[VBA ウォッチ式とSTOPを使ってみた]・・・STOPで止め、ウォッチ式でオブジェクトの中身を確認する方法など
[参照設定のお話]・・・設定すると便利な(設定しないと使えない)、参照設定のお話

項目別に↓にプログラマーの本音?それとも建て前?的な記事をまとめました。お探しのジャンルを選択してください。
[プログラムは心? spirit]・・・プログラマー 心・気質・魂
[学ぶ study]・・・学習、技術の取得
[仕様書 doc]・・・仕様書・設計書関係の話

項目別に↓に人気の記事をまとめてみました。お探しのジャンルを選択してください。
[VBAでIE ウェブブラウザーを操作]・・・VBAでIE,WebBrowserを操作する サンプルです
[MSアクセス から エクセル を呼ぶ Excel.Application]・・・AccessからExcelを操作したりデータの書き出しなどです
[アウトルック メールの操作 Outlook.Application]・・・VBAからOutlookを使い、メール関係を処理するサンプルです
↑上記3つみたいなCreateObjectで他のアプリケーションを操作するサンプルが人気です。

Excel関係:
[エクセル ユーザーフォームを操作する]・・・エクセルでユーザーフォームを作成して入力などを行ってます
[エクセルからアクセスを操作する]・・・ExcelからAccessのマクロを起動してみました、
[エクセル関係 関数、その他]・・・その他Excel関係です

Access関係:
[アクセス ユーザーフォーム/サブフォーム 操作]・・・アクセスでフォームを使ったサンプルです
[アクセス レポート操作]・・・レポートを操作してみました
[アクセス クエリーやその他関数]・・・あまりまとまってませんが、スポット的な単体関数の解説です

その他:VBAの共通関数やテキストファイルの操作など
[テキストファイルの操作(Open,Close,Print,Input)]・・・普通のテキストファイルを使ったサンプルです

Blog:[三流君の作業日記]/ [objIEを使用したサンプルコードを見る]/ 広告-[通販人気商品の足跡]

質問や要望など メッセージを送る(三流君に連絡する)

三流プログラマーのKen3 が 皆さんの質問にお答えします
と カッコつけて言っても、実力不足ですべての質問に回答することはできないのが現実なのですが、できる範囲で 三流的な逃げ手 や 解決方法 を探します(回答します)。

感想や質問・要望・苦情など 三流君へメッセージを送る。
時間的余裕のある要望・質問・苦情の場合は、下記のフォームからメッセージを送ることができます。

あなたのお名前(ニックネーム):さん
返信は?: 不用(HP更新を待つ) , E-mail→ アドレス:に返事をもらいたい



(感想や質問・要望 メッセージはHPで記事に載せることがあります。)

急ぎで連絡がほしい、そんな時は:[三流君連絡先]に連絡してください。



[トップページへ 戻る] / [VBA TOP] / [WebBrowser IEの操作 TOPへ]