[トップページ] / [サンプル一覧へ]

2009-03-07 三流解説 VBA IE デバック用 Webページのソースを表示する プログラム

Excel UserForm に WebBrowserを貼り、
デバック用のツールの作成を開始しました。
サンプルファイル:[IE_SRC0307.zip]←今回作ったサンプルの IE_SRC0307.xls です。
最新情報と作成履歴は→[更新履歴と最新を表示]


03/07 バグ修正と要望への対応

本来なら、バグ・不具合から修正するんだけど、 今回は(今回も?)、処理し易い要望から手をつけます。。。 ※そして、あとに大問題だけが残りハマるのかなぁ。  食べ易いところから食べて食い散らかし、  あとに残った無残な大皿料理にならないといいんだけど・・・

要望001 : UserFormの起動ボタンがほしい

>要望001 : UserFormの起動ボタンがほしい > > 内容 > VBAの編集画面から実行 じゃなくて > シートに貼ったボタンからUserFormを起動できないか? .Show で UserFormを表示できるので、 標準モジュールに .Show を行うモジュールを書きます。
Sub open_test()
    UserForm1.Show
End Sub
↑このモジュールをシートに貼ったボタンから起動するようにしました。 作成手順

要望002 : URLの初期値を自由に設定したい

>要望002 : URLの初期値を自由に設定したい > >内容 >現在、Googleが初期値でセットされているが、 >シートに設定値を書き、参照するなどして、 >自由にテスト用の初期ページを設定したい。 セルのB6に書かれた値を初期値として利用します。 フォームの初期処理のイベント UserForm_Initialize で Range("B6") の値を代入後、 .Navigate で ページに飛ばしただけですが。。
Private Sub UserForm_Initialize()
    Me.txtURL.Text = Range("B6") 'URL初期値
    Me.WebBrowser1.Navigate Me.txtURL.Text
End Sub
こんな感じで セルの値を初期値として使うと、 プログラムの変更無く、いろいろな動作ができます。 ※設計段階、初めから考えとけって?  う〜ん、ここらへんが、設計者のセンスの有無って感じかなぁ・・・  もちろん、私は、設計力の無い 三流プログラマーです。 他の処理でも、セルに初期値やパラメーターを書き込み、 モジュールから参照すると意外と便利ですよ。 作成手順

Web の イベント発生順をチェックしてみる。

次は、やっと、バグ・不具合の調査に入ります。 >バグ001 : Yahooのスポーツのソースが表示されない > >内容 > http://www.yahoo.co.jp/ を URLへ入力後、スポーツを選択する >表示されるはずのHTMLソースが表示されない debug.print を 入れて WebBrowser イベント発生順をテストしてみます。 ※下記、単純にイベントに Debug.Print を 入れました。
Private Sub WebBrowser1_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean)
    Debug.Print vbCrLf & "BeforeNavigate2 " & URL
End Sub

Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
    Me.txtHTML_SRC.Text = Me.WebBrowser1.Document.all(0).innerHTML
    Me.txtURL.Text = Me.WebBrowser1.Document.URL
    
    Debug.Print "DocumentComplete set----"
    
End Sub

Private Sub WebBrowser1_DownloadBegin()
    Debug.Print "_DownloadBegin"
End Sub

Private Sub WebBrowser1_DownloadComplete()
    Debug.Print "DownloadComplete"
End Sub

Private Sub WebBrowser1_NavigateComplete2(ByVal pDisp As Object, URL As Variant)
    Debug.Print "NavigateComplete2"
End Sub
こんな感じで仕掛けました。 下記、イミディエイト ウインドウに表示された、順番です。 BeforeNavigate2 http://www.yahoo.co.jp/ _DownloadBegin DownloadComplete _DownloadBegin NavigateComplete2 BeforeNavigate2 http://www.yahoo.co.jp/ NavigateComplete2 DownloadComplete DocumentComplete set---- BeforeNavigate2 http://www.yahoo.co.jp/_ylh=X3oDMTB0NWxnaGxsBF9TAzIwNzcyOTYyNjUEdGlkAzEyBHRtcGwDZ2Ex/r/c14 _DownloadBegin NavigateComplete2 DownloadComplete DocumentComplete set---- 順番の最後は、DocumentComplete で いいみたいです。 う〜ん、なんだろうなぁ。 タイミングが取れないので、 ボタンを1つ作り、ボタンを押したら、ソースをセットする。 そんな感じでテストしてみます。
Private Sub CommandButton1_Click()
    Me.txtHTML_SRC.Text = Me.WebBrowser1.Document.all(0).innerHTML
End Sub
↑単純に、ボタンを押したタイミングで、 .Document.all(0).innerHTML を セットする。。。 ところが、これでもセットされませんでした。。。 う〜ん、、、 たまたま、右クリックして http://sports.yahoo.co.jp/ ソースを見ると、 1: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 〜〜〜 2: <html lang="ja"> 3: <head> と、1行目に私が見慣れない!DOCTYPE HTML PUBLIC〜が書いてありました。 もしかして、これ?が原因。 Document.all(0) だと、空白を指している??? ヘッダーが取れないのですが、 Document.Body で、<Body>から</Body>までのデータを取れるので、
Private Sub CommandButton1_Click()
    Me.txtHTML_SRC.Text = Me.WebBrowser1.Document.body.innerHTML
End Sub
と、.Document.body.innerHTML で テストしてみました。 ボタンを押すと、やっと、データがセットされました。 原因は、イベントの順番やイベントの取りこぼし じゃなくて、 .Document.all(0).innerHTML が、カラだった、みたいです。 気に入らないけど、 .Document.body に 直します
Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
    Me.txtHTML_SRC.Text = Me.WebBrowser1.Document.Body.OuterHTML
    Me.txtURL.Text = Me.WebBrowser1.Document.URL
    
    Me.Caption = Me.WebBrowser1.Document.Title  'タイトルをフォームに
    Debug.Print "DocumentComplete set----"
    
End Sub
あっ、ついでに、 Document.Body.OuterHTML で 外側のタグを含むHTMLをセットして、 Me.Caption = Me.WebBrowser1.Document.Title で タイトルを表題に表示しました ヘッダ情報が取れないと、意味が無い・・・と、言われそうな予感もしますが。。。 .Bodyに修正して逃げた

.Document.all(0)がHTMLのトップだと思い込む三流君

野球見てたんで、日付が変わって3/8 バグ修正って、ハマると、イヤですね。 .Document.all(0) が 頭なので、 <HTML>のルートと思い込んでいたせいで、 http://sports.yahoo.co.jp/ ヤフーのスポーツのデータが取れなかった。。。 で、イベントのタイミングを疑って、違う方向に[あたり]をつけるし。。。 デバッグの目星・[あたり]をつけるセンスが無いんですね(涙) デバッグの流れ? なんて言ってないで、昨日は、
Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
    Me.txtHTML_SRC.Text = Me.WebBrowser1.Document.body.OuterHTML
    Me.txtURL.Text = Me.WebBrowser1.Document.URL
    Me.Caption = Me.WebBrowser1.Document.Title  'タイトルをフォームに
    Debug.Print "DocumentComplete set----"
End Sub
と、 Document.body.OuterHTML ドキュメントの.Bodyタグのソースをセットしてました。 原因が >1: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 〜〜 >2: <html lang="ja"> >3: <head> と、1行目に私が見慣れない!DOCTYPE HTML PUBLIC〜が書いてありました。 もしかして、これ?が原因。 Document.all(0) だと、空白を指している??? なら、Document.all(1)は?って、話になってくるのかなぁ?
Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
    Me.txtHTML_SRC.Text = Me.WebBrowser1.Document.all(0).OuterHTML
    If Len(Trim(Me.txtHTML_SRC.Text)) = 0 Then
        Me.txtHTML_SRC.Text = Me.WebBrowser1.Document.all(1).OuterHTML
    End If
    
    Me.txtURL.Text = Me.WebBrowser1.Document.URL
    
    Me.Caption = Me.WebBrowser1.Document.Title  'タイトルをフォームに
    Debug.Print "DocumentComplete set----"
    
End Sub
↑If Len(Trim(Me.txtHTML_SRC.Text)) = 0 で 判断して、 Me.txtHTML_SRC.Text = Me.WebBrowser1.Document.all(1).OuterHTML とセットしたけど、ここであらたな問題が・・・ 1行目や2行目にコメント <!-- コメント --> があると、all(0)やall(1)で、拾えないみたい。。。 う〜ん、困った。。。 で、行った処置は、 .tagname で タグの名前が取れるので、 If Me.WebBrowser1.Document.all(n).tagname = "HTML" Then で判断して、n番目が決まるので、 Me.txtHTML_SRC.Text = Me.WebBrowser1.Document.all(n).OuterHTML でデータをセットした、そんな感じです・・・う〜ん、なんかカッコ悪いけど。。。
Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
    Dim n As Integer
    For n = 0 To 99
        'タグがHTMLかチェック
        If Me.WebBrowser1.Document.all(n).tagname = "HTML" Then
            Me.txtHTML_SRC.Text = Me.WebBrowser1.Document.all(n).OuterHTML
            Exit For   'ループを抜ける
        End If
    Next n
    
    Me.txtURL.Text = Me.WebBrowser1.Document.URL
    
    Me.Caption = Me.WebBrowser1.Document.Title  'タイトルをフォームに
    Debug.Print "DocumentComplete set----"
    
End Sub
さてと、なんとか、クリアしたのかなぁ・・・ .tagname = "HTML"を見て判断

要望003 : HTMLソースを読み込み前(_BeforeNavigate2) でクリア

>要望003 : HTMLソースを読み込み前にクリアしてみては? > >内容 >読み込みに時間のかかるwebページだと、 >前のソースが残っていて、切り替えがわかりにくい。 >読み込み前にソースのエリアをクリアするなど、 >わかりやすい表示にしてください。 読み込み前に ソースのエリア Me.txtHTML_SRC を クリアしたいので、 _BeforeNavigate2 の イベントで、 XXXX(URL) を読み込み中とメッセージを代入しました。
Private Sub WebBrowser1_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean)
    Me.txtHTML_SRC.Text = URL & "を読み込み中"
    Debug.Print vbCrLf & "BeforeNavigate2 " & URL
End Sub
↑が走ってから、読み込みが完了すると、 _DocumentComplete ↓の イベントが走り、 ソースのエリア Me.txtHTML_SRC に 探したHTMLタグの.OuterHTMLをセットします。 ↓ここは変えてません。
Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
    Dim n As Integer
    For n = 0 To 99
        'タグがHTMLかチェック
        If Me.WebBrowser1.Document.all(n).tagname = "HTML" Then
            Me.txtHTML_SRC.Text = Me.WebBrowser1.Document.all(n).OuterHTML
            Exit For   'ループを抜ける
        End If
    Next n
    
    Me.txtURL.Text = Me.WebBrowser1.Document.URL
    
    Me.Caption = Me.WebBrowser1.Document.Title  'タイトルをフォームに
    Debug.Print "DocumentComplete set----"
    
End Sub
こんな感じで、1行追加しただけで、操作者にやさいしシステムになります。 ※初めの設計時に入れとけよ・・・って話もありますが・・・ (_BeforeNavigate2)をテスト

テキストボックスのカーソル .SelStart .SelLength を テスト

バグの修正 や 要望の検討・修正を行っていると、 新たなバグ や 要望が発生したり ※おぃおぃ、勘弁してくれよ、終わらないよ。。。 要望004 : HTMLソースを選択したらカーソルを先頭にしてほしい 内容 読み込み完了後、HTMLソースの表示エリアをクリックすると、 カーソルが後ろにあり不便。 普通ソースは頭から読むので、頭にカーソルを持ってこれないか? 単純に、データセット時に、 テキストボックス.SelStart と テキストボックス.SelLength をセットして、実験してみました。
Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
    Dim n As Integer
    For n = 0 To 99
        'タグがHTMLかチェック
        If Me.WebBrowser1.Document.all(n).tagname = "HTML" Then
            Me.txtHTML_SRC.Text = Me.WebBrowser1.Document.all(n).OuterHTML
            Exit For   'ループを抜ける
        End If
    Next n
    'カーソルのセット
    Me.txtHTML_SRC.SelStart = 2
    Me.txtHTML_SRC.SelLength = 3
    
    Me.txtURL.Text = Me.WebBrowser1.Document.URL
    
    Me.Caption = Me.WebBrowser1.Document.Title  'タイトルをフォームに
    Debug.Print "DocumentComplete set----"
    
End Sub
↑少し、変ですが、こんな感じでカーソルが頭の行に来ました。。。 ↓TextBox .SelStart .SelLength の実験

URL入力後のチェックを入れる

バグ002 : URL入力時、変更無しの時、再度読み込みに行く・・・ 内容 URL入力エリアに入る。(フォーカスを移す) 何もURLを修正していないのに、 再度 読み込み処理 が走ってしまう。 処置 WebBrowser1.Document.URL で 現在処理中のURLが取れるので、 単純に If文で 入力値 = 現在の文章URL がきいて、 同じ場合、何もしないで(.Navigateで移動しない)関数を抜けます
Private Sub txtURL_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    If Me.txtURL = Me.WebBrowser1.Document.URL Then
        Exit Sub  'そのまま抜ける
    End If
    Me.WebBrowser1.Navigate Me.txtURL.Text  'ページ移動
End Sub
↑なんか、If文使っただけだけど・・・  まぁ、これくらいは、仕様書に書いてなくてもやらないとなぁ。。。 やっぱり三流

戻るボタン(機能)を追加 .GoBack の実行

要望005 : 戻る ボタンを作ってほしい 内容: 戻るのボタンを作り、 前のページに表示を戻したい。 処置: http://www.microsoft.com/japan/windows/products/winfamily/ie/quickref.mspx に ショートカット 一覧があります。 >ホーム ページに移動する Alt + Home >前のページに移動する Alt + ← (左方向キー) >次のページに移動する Alt + → (右方向キー) >Web ページを更新する F5 この操作をマニュアルに載せといて。 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ で、済ませて、(と、上司は言った) プログラムを修正しないのも一つの手なのですが、 今回は、サービスでボタンを追加します。 ※おいおい 勝手に機能を追加して、上司に確認取ったのかよ???  工期が遅れ気味なのに よけいなこと するなよ!!!  機能を追加したら、仕様書の修正(設計書・テスト仕様書)など、大変だろ。 簡単な修正なのにやらないつもりか? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 修正は簡単でも 仕様書などの修正コストが・・・? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ システム化・プログラムって、 家を建てるのと違って、 材料費がPCやOS,アプリを台数分 導入したら、 あとは、開発費の人件費だけだから、 現場で相手先と仲良くなると、追加機能を受けたくもなるんですよ。 ※これが建築だったら、建材を追加しないとできません  と、わかりやすいんだけど、  システム開発は、下っ端プログラマーの裁量でいくらでも(←は、いいすぎか) プログラマーが自発的に修正したって話 と 営業や設計者が 客先の要求を丸呑みして機能が増えていく そんなパターンもあるし、 どこかで線を引いたり、 材料費・建材費はかからないけど、 人件費がかかることを忘れずに。 人件費の増大 = 開発人数増えなきゃ 残業の増加でカバー 要求丸呑み これがデスマーチの一つの要素かなぁ。 まぁ、いろいろな立場がありますから。もめても みなさんはむくれないでね。 いつものように脱線しましたが、 別に機能を増やしても、私の腹は痛まないので、 修正します。 ※だからぁ、作業量が増えるんだろ・・・修正はコストを考えてね。 で、肝心の行った処置は ^^^^^^^^^^^^^^^^^^^^^^ .GoBack の メソッドで戻る処理が可能なので、 ボタンを1つ追加して、
Private Sub btnBACK_Click()
    Me.WebBrowser1.GoBack   '戻る
End Sub
としました。。。※ボタン追加と1行でできますが、追加時はよく考えてね。。。 ↓文句を言いつつ.GoBackを入れる↓

同系機能 .GoHome(ホームへ移動) .GoForward(次のページ) .Refresh(更新) を使う

要望006 : 更新やホームの移動系ボタンを作ってほしい 内容: 戻るのボタン(前のページに移動)が簡単に作れるなら、 >ホーム ページに移動する Alt + Home >前のページに移動する Alt + ← (左方向キー) >次のページに移動する Alt + → (右方向キー) >Web ページを更新する F5 のボタンも作ってよ? 処置: まぁ、考え方としては、1つできたら、あとは同じの同系機能 WebBrowser1.GoBack '戻る の周りを調べて対応すれば、OKかなぁ。 .GoHome .GoForward .Refresh を使いました。 ※後で仕様書の修正 テストケースを増やしたり 後始末が大変だぁ 修正後、テストでバグを見つけました。 バグ003 : 戻る ボタンを押し続けると エラーが発生する。 内容:やっちまった、って感じです。 戻るページが無いのに .GoBack メソッドを実行しようとした罰(おぃおぃ)です 処置:On Error Resume Next 'エラーを無視 で対応しました。※今回はエラーを単純に無視しました。 いろいろあったけど、ボタン4つ作成して、動作のメソッドをそれぞれ発行しました。
Private Sub btnBACK_Click()
    On Error Resume Next    'エラーを無視
    Me.WebBrowser1.GoBack   '戻る
End Sub

Private Sub btnHOME_Click()
    Me.WebBrowser1.GoHome    'ホームへ移動
End Sub

Private Sub btnNEXT_Click()
    On Error Resume Next    'エラーを無視
    Me.WebBrowser1.GoForward    '次へ移動
End Sub

Private Sub btnUpdate_Click()
    Me.WebBrowser1.Refresh   'F5 更新ボタン
End Sub
作成とエラー画像→

仕様書の修正

忘れちゃいけない、仕様書の修正・・・ かっこつけ 修正してたら バグを出す。 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 最後まで、三流らしかったですね じゃなくって、忘れちゃいけないのが、 仕様書の修正・・・ プログラム作成後にも修正しといてね。 これが、意外と面倒なんだってば。 デスマーチをスタミナ切れてヘトヘトでやっとコールしたのに、 まだ、この作業が残っていたか・・・って感じです。 ※だから、手抜きの仕様書が世の中に多かったりするんだけど。 初期の仕様と比べてみる(笑) ここから、書き足す。※忘れずに、速めに。

終わりの挨拶

実行サンプルと修正した仕様書は:[IE_SRC0307.zip]←今回作ったサンプルの IE_SRC0307.xls です。
最新情報と作成履歴は→[最新情報・経過を表示]


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

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

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

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

感想や質問・要望・苦情など 三流君へメッセージを送る。
時間的余裕のある要望・質問・苦情の場合は、下記のフォームからメッセージを送ることができます。
あなたのお名前(ニックネーム):さん
返信は?: 不用(HP更新を待つ) , E-mail→ アドレス:に返事をもらいたい



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

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

IE関係、VBA関係 の 三流君のホームページの紹介・案内

[IE操作 三流解説のトップページへ 戻る] / [IE操作の三流サンプル一覧へ 戻る]

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

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を使用したサンプルコードを見る]/ 広告-[通販人気商品の足跡]



[トップページへ 戻る] / [サンプル一覧へ 戻る]