IEのサポートがWindows11で完全終了してしまいましたね。(2021/10/05冒頭に追記)
そんな感じで下記の質問が来たので対応策の参考になれば

下記いただいた質問
>ExcelVBAでデータを集め、競輪予想を作っています。



>さて最近、IEのサポート終了が告知されていますが
>WEBからのデータ取得はどのような対処がベターなのでしょうか?ご意見をお聞かせください。

ベター、ベスト、イロイロな考え方がありますが、
1.MSXML2.XMLHTTP などでHTMLを取得して、CreateObject("htmlfile") を使う
下記の例題動画、なんだか私の解説はイマイチだった・・・やはり、素直にSelenium VBAなのかなぁ。
と思いつつ、冒頭で Set objHTML = CreateObject("MSXML2.XMLHTTP")
でHTMLを取得して、使ったサンプルを紹介してみたり

IEサポート終了後の世界 MSXML2.XMLHTTPとCreateObject("htmlfile")を使用してJRAオッズ取得 ワイドのオッズ取得に挑戦してみた

目次
10:08 2.ワイドのオッズを押す
11:55 2.1 strレースを探し、頭出し?
18:47 3.オッズのテーブルを判断して、Excelにワイドオッズを取得
21:37 3.1 tableのcaptionで判断
28:30 4.ワイドの一番人気を探す
31:17 元に戻って、2.4 2回目以降は、レースを選択
他の動画を見る(YouTubeで再生リストを見る)
↑も参考になれば・・無事に移行できるといいですね。 三流プログラマー Ken3
※ソースコードは[MSXML2.XMLHTTPとCreateObject("htmlfile")を使用してJRAオッズ取得]を見てアレンジしてください。

はじめは[WebBrowserを参照設定]から入り
[VBAでIE操作解説]やってます。
よく使う.Document:の解説から
[.Forms]で入力処理
[.Links]でリンク情報取得
[.Images]で画像の情報
[.Frames]でフレーム処理
[.Script]でスクリプト処理
...など、まだまだ抜けてますが、
手探りで[ヘルプ IEのオブジェクトを探る]
IE,WebBrowser:
[IE プロパティ(各種設定)]
[IE メソッド(イロイロな動作)]
[IE イベント(発生後処理)]
[VBAでIE操作(TOP)]
小さな[IE操作のサンプル]でTEST
次に[少し大きなIEを使ったサンプル]
にチャレンジしたり
[IE関係記事一覧]

[VBA(TOP)]
[三流君(TOP)]

全ての質問には、答えられませんが、リクエストや質問があったら、[作者(三流君)に質問する] から 気軽に送ってください

魚拓 三流君VBAでIE操作 2009-06-01に履歴として残す

2009/06/01 までに書いた IE関係の記事です。
更新するたびに、前のほうが良かったと言われるのですが、
現在の最新解説は、
http://www.ken3.org/cgi-bin/group/vba_ie.asp
↑を見てください。

ちなみに、前のほうが良かったと言われる記事
2009-02-01:[過去の解説 vba_ie_20090201.asp]
2008-05-01:[過去の解説 vba_ie_20080501.asp]
2007-08-31:[過去の解説 vba_ie_20070831.asp]
2007-05-20:[過去の解説 vba_ie20070520.asp]
もあわせてみてください。
(↑だんだん、解説が劣化している?もしかして書き直さない過去の解説の方がよかったかも?(笑))

2009/06/01に書いていた記事

挨拶:VBAで(ExcelやAccessなどから)InternetExplorer WebBrowserを操作してみたいと思います。

初めの入り口は 大きく2つじゃないですが、
1.Set オブジェクト変数 = CreateObject("InternetExplorer.Application") と 変数に代入してから オブジェクト変数.メソッド 変数.プロパティ みたいに使う方法
※参照設定すると便利なので [IE Web Browser を使う場合の参照設定] を 見てください。
次の方法は、
2.ExcelのUserFormにWebBrowserのコントロールを貼り コントロール名.メソッド コントロール名.プロパティ
※実際の貼り付け方、手順は [番外編 Excel UserForm に IEを貼る] を 見てください。
まぁ、どちらから入っても .メソッド .プロパティ を 探らないといけないのですが。。

脱線すると、google検索のワンダーホイールって面白い
↓私のよく使う変数 objIEで検索すると
objIEの結果をワンダーホイールで表示
↑なかなか、楽しめそうです。※関連項目の全てが線でつながらないけど(全てつながるとかなり面白いのに。)
googleってすげぇなぁ。

おっと話を元に戻して、下記 IE操作のサンプルです。
と言っても、単純に情報をひっぱっただけです。(値のセットや選択、ボタンを押す動作などは入っていません(ページヘッダの大分類リンク先から目的の処理を見てください。)
私のテスト環境は、Excel2003 OS:XP SP3 IE8 でテストしました。
まずは、参照設定など、実行して遊んでみてください。
'参照設定 Microsoft Internet Controls(Microsoft Browser Helpers)
'Microsoft HTML Object Library の 2つを忘れずに

'参照設定の方法は、 http://www.ken3.org/cgi-bin/group/vba_ie_object.asp をみてください。

Sub ie_test()  'IE操作のサンプルプログラム

    Dim strURL As String  'URL入力用
    strURL = InputBox("URLを指定", "URL入力", "http://ie.vba-ken3.jp/test/")

'InternetExplorer
'> 001 参照設定をしましよう。参照設定をすると
'(As HTMLXXXX など型宣言すると、プロパティやメソッドを探るのが楽ですよ)
'↓こんな感じで → [動画でAs InternetExplorerを定義すると楽ですよ]を説明
    Dim objIE   As InternetExplorer  'IEオブジェクト参照用
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

'> 002 最大化 と 指定場所へ表示をテストする。
'↓→動画解説 [試行錯誤の動画、なんとか表示位置を指定できた] そんな動画です。
    'IE 画面サイズの調整(表示場所とサイズ)
    objIE.FullScreen = False '= Trueで最大化します。
    objIE.Top = 200    '左上 Y 表示場所の指定
    objIE.Left = 100   '左上 X
    objIE.Width = 800  '横の幅
    objIE.Height = 600 '縦の高さ

'> 005 指定したページを表示させるには .navigate
'↓→動画解説 [.navigate を 使い、ページを表示させるサンプル動画です。]
    '指定したページを表示
    objIE.navigate strURL   '文字列でURLを渡す

    '表示完了を待つ .readyState と .Busy を見る
    While objIE.readyState <> READYSTATE_COMPLETE Or objIE.Busy = True 'IEがBusyの間 待つ
        DoEvents
    Wend
    DoEvents

    '6〜999行を消す、結果表示エリアをクリア
    Rows("6:999").Select
    Selection.Delete Shift:=xlUp

'IEなどのブラウザは、URL:xxx.htmlなどを読み込み後、
'HTML文章を解析して画面に表示してくれます。HTMLはタグ付きのテキスト文章です。
'いろいろなタグがあります。 Body本文や Aアンカー(リンク) Form(入力フォーム)
'・・・ まぁ、先が長いけど、なれると感じがわかってくると思います。

'Document
'> 003 HTML文章にアクセス あと表示待ちを入れてね。
'↓→動画解説[F2オブジェクトブラウザを使い As HTMLDocumentを探る]そんな試行錯誤を少し

    'ドキュメント、HTML文章にアクセスする
    Dim objDOC As HTMLDocument
    
    Set objDOC = objIE.document 'IEの文章をセット
    Debug.Print "URL = " & objDOC.URL
    Debug.Print "タイトル = " & objDOC.Title

    'BODY タグに.bodyで アクセス .innerTextでテキスト .outerHTMLでHTMLの表示
    Debug.Print objDOC.body.innerText   'BODYテキスト(タグ抜き、ベタなテキスト)
    Debug.Print objDOC.body.outerHTML   'BODY の HTMLタグ付き

'Document.Links
'> 007 リンク情報を取り出す .Links .Length .href .innertext
'[リンク情報の抜き出し 試行錯誤の操作]← 動画です。
'↓で簡単に書いてるけど、本当は↑みたいにハマってます。
    'リンク情報にアクセスする Document.Links
    Dim objLINK As HTMLAnchorElement 'リンクのオブジェクト
    Dim n As Integer
    Dim y As Integer
    
    Cells(8, "A") = "'リンクの数は.Links.Length = " & objDOC.Links.Length

    y = 9
    Cells(y, "A") = "'番号"
    Cells(y, "B") = "'.href=リンク先"
    Cells(y, "C") = "'.innertext=アンカーテキスト"
    Cells(y, "D") = "'.outerHTML=HTMLタグ付き"

    y = 10
    For n = 0 To objDOC.Links.Length - 1
        Set objLINK = objDOC.Links.Item(n) 'リンクのn番目を代入
        Cells(y, "A") = n    '番号
        Cells(y, "B") = "'" & objLINK.href 'リンク先
        Cells(y, "C") = "'" & objLINK.innerText 'アンカーテキスト
        Cells(y, "D") = "'" & objLINK.outerHTML 'HTMLタグ付き
        
        y = y + 1
    Next
'↑リンクの解説 Document.Linksの続きは[Document.Linksをさわる]をみてください。

'Document.Forms
'> 008 フォーム情報 .forms .Length .action .Name .ID .outerHTML
'[ウォッチ式などで Formを探ってみた] ←試行錯誤のデバック操作動画です。
    '入力フォーム FORMタグの情報を取り出す。
    Dim objFORM   As HTMLFormElement   'フォームのオブジェクト
    Dim TAGInput  As HTMLInputElement  'INPUTのタグ
    Dim TAGSelect As HTMLSelectElement 'SELECTのタグ
    Dim TAGOption As HTMLOptionElement 'OPTIONのタグ
    Dim TAGTEXTAREA As HTMLTextAreaElement 'TEXTAREAのタグ
    
    Dim x As Integer
    Dim i As Integer

    y = y + 1
    Cells(y, "A") = "フォームの数 .forms.Length は " & objDOC.forms.Length
    
    y = y + 1
    Cells(y, "A") = "番号"
    Cells(y, "B") = "'objFORM.action"
    Cells(y, "C") = "'objFORM.Name"
    Cells(y, "D") = "'objFORM.ID"
    Cells(y, "E") = "'objFORM.outerHTML"
    
    y = y + 1
    For n = 0 To objDOC.forms.Length - 1
        Set objFORM = objDOC.forms(n)  'Formのn番目を代入
        
        Cells(y, "A") = n    '番号
        Cells(y, "B") = "'" & objFORM.action 'Action 飛び先
        Cells(y, "C") = "'" & objFORM.Name   '名前
        Cells(y, "D") = "'" & objFORM.ID     'ID
        Cells(y, "E") = "'" & objFORM.outerHTML 'HTML
        Rows(y).RowHeight = 120  '行の高さを強引に120にする。
        y = y + 1 'セット位置を+1する
        
        '中のITEM タグごと探る
        For x = 0 To objFORM.Length - 1

        '> 009 TYPE=INPUT .TagName .Name .ID .outerHTML .Value 
        'As HTMLInputElement TYPE=INPUT を探ってみた] ←試行錯誤の操作動画
            If objFORM.Item(x).tagName = "INPUT" Then 'INPUTのタグか?
                Set TAGInput = objFORM.Item(x)  'FORMのアイテムを代入
                
                'タグの名前.tagName とタイプ.Type
                Cells(y, "B") = "'" & TAGInput.tagName & " " & TAGInput.Type
                
                Cells(y, "C") = "'" & TAGInput.Name   '名前
                Cells(y, "D") = "'" & TAGInput.ID     'ID
                Cells(y, "E") = "'" & TAGInput.outerHTML 'HTML
                Cells(y, "F") = "'" & TAGInput.Value 'VALUE 値
                
                y = y + 1 'セット位置を+1する
            End If

        '> 011 TEXTAREA .TagName .Name .outerHTML .Value Input.type
        '[As HTMLTextAreaElement TYPE=TEXTAREA を探ってみた] ←試行錯誤の操作動画
            If objFORM.Item(x).tagName = "TEXTAREA" Then 'TEXTAREAのタグか?
                Set TAGTEXTAREA = objFORM.Item(x)  'FORMのアイテムを代入
                Cells(y, "B") = "'" & TAGTEXTAREA.tagName   'タグの名前
                
                Cells(y, "C") = "'" & TAGTEXTAREA.Name   '名前
                Cells(y, "D") = "'" & TAGTEXTAREA.ID 'ID
                Cells(y, "E") = "'" & TAGTEXTAREA.outerHTML 'HTML
                Cells(y, "F") = "'" & TAGTEXTAREA.Value 'VALUE 値
                
                y = y + 1 'セット位置を+1する
            End If

        '> 010 TYPE=SELECT .TagName .Name .ID .outerHTML .Value 
        '[As HTMLSelectElement TYPE=SELECT を探ってみた] ←試行錯誤の操作動画
            If objFORM.Item(x).tagName = "SELECT" Then 'SELECTのタグか?
                Set TAGSelect = objFORM.Item(x)  'FORMのアイテムを代入
                Cells(y, "B") = "'" & TAGSelect.tagName   'タグの名前
                
                Cells(y, "C") = "'" & TAGSelect.Name   '名前
                Cells(y, "D") = "'" & TAGSelect.ID     'ID
                Cells(y, "E") = "'" & TAGSelect.outerHTML 'HTML
                Cells(y, "F") = "'Value=" & TAGSelect.Value 'VALUE 値
                Cells(y, "G") = "'selectedIndex=" & TAGSelect.selectedIndex '選択されている場所
                
                y = y + 1 'セット位置を+1する

                'SELECTタグの下にはOPTIONタグがあるので、
                For i = 0 To TAGSelect.Options.Length - 1
                    Set TAGOption = TAGSelect.Options(i)  'FORM SELECTのアイテムを代入
                    Cells(y, "B") = "'" & TAGOption.tagName   'タグの名前
                    
                    Cells(y, "C") = "'.nodeName=" & TAGOption.nodeName   '名前
                    Cells(y, "D") = "'" & TAGOption.ID     'ID
                    Cells(y, "E") = "'" & TAGOption.outerHTML 'HTML
                    Cells(y, "F") = "'Value=" & TAGOption.Value 'VALUE 値
                    Cells(y, "G") = "'.Selected=" & TAGOption.Selected '選択の有無
                    
                    y = y + 1 'セット位置を+1する
                Next i

            End If
        Next x
        
    Next
'↑フォームの解説 Document.Formsの続きは[Document.Formsをさわる]をみてください。
'(FORMに実際にデータをセットしたり、選択したり、ボタンを押したり。。)

'Document.Images
'> 012 イメージ情報 HTMLIMG .src .title .outerHTML
'↓→ 動画解説 http://www.youtube.com/watch?v=fv35XppOD_0
    'イメージ、画像を探る
    Dim objIMG As HTMLImg  'イメージ、図
    
    y = y + 1
    Cells(y, "A") = "images.Length は " & objDOC.images.Length
    y = y + 1
    
    Cells(y, "A") = "no"
    Cells(y, "B") = "'.src"   'URL
    Cells(y, "C") = "'.Title" 'タイトル
    Cells(y, "D") = "'.outerHTML" 'HTML

    y = y + 1
    
    For n = 0 To objDOC.images.Length - 1 'イメージ数ループする。
        Set objIMG = objDOC.images(n)   'n番目のイメージを代入
        Cells(y, "A") = n
        Cells(y, "B") = "'" & objIMG.src   'URL
        Cells(y, "C") = "'" & objIMG.Title 'タイトル
        Cells(y, "D") = "'" & objIMG.outerHTML 'HTML
        
        y = y + 1
    Next
'↑イメージ・画像の解説 Document.Imagesの続きは[Document.Imagesをさわる]をみてください。

'Document.Frames
    'フレームをチェックする。
    ' http://www.ken3.org/vba/test116.html ← テスト用フレームページ
    Dim objHTML As HTMLDocument     '※フレームの先はHTMLドキュメントなので。
    y = y + 1
    Cells(y, "A") = "frames.Length は " & objDOC.frames.Length
    y = y + 1

    Cells(y, "A") = "No frames(n)"
    Cells(y, "B") = "URL"
    Cells(y, "C") = "Title"
    Cells(y, "D") = ".body.outerHTML"
    y = y + 1

    '↓これだと、孫フレーム(フレームの中のフレーム)にたどり着けないけど。
    For n = 0 To objDOC.frames.Length - 1 'フレーム数ループする。
        Set objHTML = objDOC.frames(n).document   'n番目のフレームを代入(フレームの先を代入する感じ)
        Cells(y, "A") = n
        Cells(y, "B") = "'" & objHTML.URL       'URL
        Cells(y, "C") = "'" & objHTML.Title     'タイトル
        Cells(y, "D") = "'" & objHTML.body.outerHTML 'HTML
        Rows(y).RowHeight = 120  '行の高さを強引に120にする。
        y = y + 1
    Next
'↑フレーム処理の解説 Document.Framesの続きは[Document.Framesをさわる]をみてください。

'> 004 終了処理は 単純に .Quitで。
'↓→動画解説 http://www.youtube.com/watch?v=cMaYAAI8h3k
    '終了処理 テストの時は、↓確認して、残しておくと便利ですよ。
    If MsgBox("IEを閉じますか?", vbYesNo) = vbYes Then '終了確認
        objIE.Quit  '.Quitで閉じる
    End If
    Set objDOC = Nothing  '使用したオブジェクト変数もキレイにしてね。
    Set objIE = Nothing

End Sub

その他・よくある処理とサンプル:
・Webページからファイルをダウンロードしたい、
名前をつけて保存 や 対象をファイルに保存、そんな操作時は、
[No.120 URLDownloadToFile APIを使用してWebからファイルをダウンロードしてみた]
を見てください。APIと言ってますが意外と簡単ですよ(キャッシュの問題があるけど)

・Webから表 TABLE データを取り出したい(Webクエリーがあるけど、自分で取得したい)
そんな処理のサンプルは↓
[VBA IE Webページの表を取り込む]
[VBA IE JRA IPATのページから単勝の表を取り込む ]
↑手前味噌サンプルですが、表の取り込みでアレンジして使ってみてください。

・全てのIEを終了させたい、と、よく質問をいただきます。
[起動しているIEを全て閉じたい]
↑で、For Each objWindow In objShell.Windows で ループさせ、.Quitで閉じました。
・新しく開かれたIEを操作したい と、これまたよく質問をいただきます。
[新しく開かれたIEを探す]
↑で、プログの記事をVBA IEから登録で、公開日時を指定 で 新規に起動する、新しいウインドウ(IE)を捕まえる そんな処理にチャレンジしてみたり。
もしかしたら、WebBrowserのイベントで捕まえる、こっちのほうが操作し易いかなぁ。
[新規のウインドウ(IE)が起動する イベントを見る。
http://ken3-info.blog.ocn.ne.jp/objie/2009/04/ie_9b6c.html
]
↑WebBrowser1のNewWindow2 新しくウインドウが作られる処理で、
Set ppDisp = Me.WebBrowser2
と1つ呪文を書きます。(呪文ってオイ、、、)
ドンドン、ウインドウが複数立ち上がっていく↓そんな場合は、さらに?
[また 新しいウインドウが起動した(情報ウインドウを捕まえる)
http://ken3-info.blog.ocn.ne.jp/objie/2009/04/post_3cd7.html
]
↑これも同じだけど、※WebBrowser1 → WebBrowser2で受け取り、さらに開いたら → WebBrowser1 なんか変だけど。

未解決や問題点:
・↑の新規IEと勘違いされるんだけど(私が質問を勘違いするんだけど)
JavaScriptから出力される Aleatやconfirm の確認・メッセージ などで処理が止まる。OK はい などを押したいけど、何かいい方法ありませんか?
と、かなり質問をいただくが、三流なのでうまい・イイ回避方法が見つかってません。ゴメンなさい。スミマセン。
・画像を自動でアップしたいので INPUTタグTYPE FILEにファイル名を入れたい。
↑これも、セキュリティを突破できてません。

あと、Vistaが普及していない・・と言っても20%以上ぐらいは普及?しているので、
私のIE操作サンプルが動かない↓と苦情が多くなってきたり。
・OS:Vista と IE7 だと.Navigateで失敗したり・・うまくIE制御ができません。
[IE7 操作 Vista保護モードで失敗]
↑姑息な回避方法を考えたりしたけど、なかなかしっくりきてなかったり。

全ての質問には、答えられませんが、リクエストや質問があったら、
[作者(三流君)に質問する] から 気軽に送ってください


InternetExplorer オブジェクト プロパティ メソッド の 探り方

読者の声:テメエの(三流プログラマーの) くどい説明、わかりにくいサンプル、手前味噌・自己満足のリンクを見るよりも、自分で調べるから、正式な資料やヘルプのURL と 調べ方・操作方法を書いてくれれば 自分で見て調べるからさ、さっさと教えな。

そうですか、、、私がIE操作、プロパティメソッドを探る方法 を ネタばらしすると(もうネタバレしちゃうの?もっとひっぱろうよ、ページをたらいまわしにしようぜ(おぃぉぃ))

プログラム作成前準備として、
・[参照設定] ・・・ HTML Object Library と Microsoft Internet Controls を設定してから組み始めるのが正解かなぁ。
・[F2を押して、オブジェクトブラウザで遊ぶ]・・・ ↑参照設定後、F2オブジェクトブラウザを使ってみたり。

開発時、デバック時など、ハマりながら操作する感じは、
・[STOPで止め ウォッチ式 を使う]・・・プログラムを途中で止めて objIEの変数の中を直接見にいったり

MSDNとGoogle検索:F1のヘルプが効けば一番楽なんだけど、IE系の説明・ヘルプが出ないので
・[三流君 が MSDN で InternetExplorer の 資料を探す] ・・・ まぁ英語のページは嫌いだけど、MSDNから頑張って探したり
↑だとツライので、最近はGoogleの検索を主に使っていたり↓
・[番外編 GoogleでoIE,objIE,WebBrowserをKeyWordにして検索]・・・検索のキーワードがなかなか思いつかないと思うので私のお気に入りのキーワードを紹介します。(読者の声:だったら先に書けよ)

こんな感じで、探ってます。目新しい画期的な回答で無くスミマセン。

※私、三流君を踏み台にして、読者の皆さんは、羽ばたいて下さい。
[後輩に追い越される三流な先輩]←こんな感じで後から来た皆さんに追い越されれるなぁ と思いつつ(笑)
※※三流解説・三流コードが少しでも参考になったらうれしいなぁ〜

手前味噌のサンプルとリンク:
下記、評判の悪い、三流プログラマーの 手前味噌 くどい説明です。
お時間のあるときに、参考程度に見てください。
・[過去のメルマガIE記事]・・・メルマガで書いた記事。こっちが好きな少数派も居たりして?
・[IEの操作 ブログ記事]・・・小さな単位で抜き出してBlogにUPしただけ
・[IEを使った三流サンプル] ・・・ 少し長めのサンプル、JRAオッズ取り込みほか

声がうわずって、[え〜と]、[こんな感じ] の単語連発で 間が悪く 聞き取りにくい
・[恥ずかしい解説動画(VBA IE動画解説)]・・・YouTubeに解説、操作動画アップしてます。
さらにひどい、
読者説明よりも SEOが目的 なのか知らないが、
・[変なブックマーク(WebBrowser系)]・・・はてなブックマーク使ってみました。使い易いですね。

さて、IE操作 Documentの森・WebBrowserの山を頼りないガイドの三流君と一緒にさまよってみましょうか!!!
このページ 三流プログラマー的解説がIE操作方法(プロパティやメソッド)の入り口として何かの参考・お役に立てれば幸いです。

やっと メニュー おしながき 目次

ページ内が無駄に長いので、ページ内の目次を作りました
ページ内 分類と目次
大分類詳細
[Document.Allをさわる]
Webに記載(表示)されているデータを取り出したいのでDocument.allオブジェクトにイロイロな方法でアプローチ、アクセスしてデータを取得したIE操作の解説です
  • [IEの起動] : CreateObject("InternetExplorer.application")でブラウザを起動させました
  • [.Navigateで開く] : 次に目的のページを開くために.Navigateメソッドでページを移動しました
  • [.Allで文章にアクセス] : ページが無事表示されたらテストでDocument.all(番号) で 文章にアクセス .Document.All(0).InnerTEXTなどのテストを行いました
  • [All.Length] : Document.All.Length で タグ(要素)の数がわかるので 0から.Length-1までループさせ、.TagName タグの名称 や .OuterHTML .InnerText .InnerHTML を シートに書き出してみました
  • [For Each IN でループ] : For Each objTAG In objIE.Document.all で ループを作りデータを処理してみました。
  • [表(TABLE)からデータを抜く] : 表示されたページのTABLE(表)からデータを抜きたいと思います※イロイロな方法があって迷いますが
  • [.TagName] : .TagNameでタグの名前が取得できるので、名称が<TR>で改行、<TD,TH>で次の列、そんなDocument.all から .tagname で判断して自分でセットする泥臭い方法でデータを抜いてみました
  • [.ExecWBメソッド] : .ExecWBメソッドを使って 全て選択,コピー の コマンドを発行してデータをExcelシートに貼り付けましたてみました
  • [createControlRange] : ↑上記の全体コピーは使いにくかったので、document.body.createControlRange を使い、指定したテーブルをシートに貼り付けてみました。
  • [.tags("タグの名称")] : document.all(n)で.tagnameが指定したタグなら・・・そんな処理で便利な方法があって Set objTABLE = objIE.document.all.tags("TABLE")でTABLEのみを抜く(指定したタグを抜く)ことができました
[Document.Formsをさわる]
Web上の入力フォームにデータをセットしたいので、Document.FormsオブジェクトにイロイロなアプローチでアクセスしてデータをセットしたIE操作の解説です
[Document.Formsを操作する]
  • [事前準備] : 操作したい入力フォームを手作業でいじってみたり、FORMのソースを表示したり、事前準備を行います
  • テキスト入力と送信 [.Submitで送信] : .Busy.ReadyStateを見て表示の完了を待ってから.Document.Forms(0).Item("MEMO").Value = 値でデータをセット後、.Submitメソッドでデータを送信しました。

  • ラジオボタンの選択 [INPUT RADIO(ラジオボタン)] : 次は、ラジオボタン INPUT TYPE="RADIO"を操作してみました。
  • [.Nameと.Value] : テストで Forms(0) を For Eachで探り、.Name.Valueを表示しました。
  • [.Checked] : 目的のオブジェクトが見つかったら.Checked = Trueとして、ラジオボタンを選択状態にしました。
  • [.Click] : 単純にオブジェクトが見つけて.Clickメソッドでオブジェクトをクリックして押してみました。

  • ドロップダウン▼の選択 [SELECT OPTION 選択] : FORM SELECT OPTION の攻略(選択)サンプル
  • [Option .Selected] : 選択なので単純に Optionタグを探しOptionタグ.Selected = Trueをセットしました。
  • [Select .Value] : もっと素直になって 選択したい値がわかっているのでSELECTタグ.Value = 選択したい値でセットしました。

  • リストボックス複数選択 [SELECT 複数OPTIONの選択] : SELECT Size=nで複数表示されたリストボックスから、Ctrl+クリックで複数のOPTIONデータを選択する方法
  • [.tags("OPTION")で探す] : 該当するOPTIONのデータを探したかったので、For Each objOPTION In objIE.Document.tags("OPTION")で選択データを探しobjOPTION.Selected = Trueを複数セットしました。

  • [□レ チェックボックス] : まず、実際のINPUT TYPE="CHECKBOX"のパターン2つ(HTML FORM)を抜き出しました。
  • [.Checkedを付ける] : Name="XXXX"が個々に違う場合(CHECKBOXに1つ1つ別の名前が付いている場合)、入力フォームを表示してから、素直に Document.Forms(0).Item("名前")でオブジェクトが特定できるので、あとは.Checked = Trueで選択状態にしました。objIE.Document.Forms(0).Item("VBA").Checked = Trueみたいな感じで意外と簡単でした。
  • [.Valueで探す] : 次に、CHECKBOXのName="XXXX"が同じでValue="ZZZZ"が違う入力フォームの場合、.Valueで判断してから、.CheckedをTrueにしました
  • [Document.getElementsByNameで探す] : Name="XXXX"がわかっているなら、便利な取得方法があって、Document.getElementsByName("名前")で指定した名前(.Name)のオブジェクトを取り出せます。

  • 名前付きのボタンを押す [Form外のボタンを押す(.Click)] : <Form>が無く<INPUT type="button" onclick="Javaで作った関数"> だけで作られたボタンを.Clickで押し JavaScriptを起動しました
  • [名無しのボタンを押す(.Click)] : INPUT type="button" に name="名前"> と名前が付いていない場合、.Valueなど他の値を利用してオブジェクトを特定しで.Click操作したお話です

[Document.Linksをさわる]
ネットはリンクでつながってます、そんなリンク情報を扱いたかったので、Document.Linksオブジェクトにイロイロなアプローチでアクセスしてリンク情報を取得したIE操作の解説です
[Document.Linksを操作する]
  • [リンク先を取り出すテスト] : 表示したページのリンク先の情報をセルに書き出すテストプログラムを作ってみます。(URLを受け取り、ページを表示させ、リンク先をセルに書き出します。)
  • [Links.Length] : Document.Links.Lengthでリンクの数がわかるので、Document.Links(i)とi番目にアクセス可能です
  • [.Href] : .Hrefでリンク先と他のタグでも使うことの多い.OuterText .OuterHTML .InnerText .InnerHTMLなど知っているプロパティを説明しました。
  • [For Each 変数 In objIE.Document.Links] : いつもよく使っている For i = 0 To objIE.Document.Links.Length - 1のループをFor Each objLINK In objIE.Document.Linksのループに書き換えてテストしてみました。お好みでどうぞ。
  • [.QuitでIEの終了] : objIE.Quitで、Set objIE = CreateObject("InternetExplorer.application") で作成した IEを終了、閉じることができます。開発中やデバッグ中はIEをそのまま残しておいたほうが何かと便利なのですが、処理が終わったら.QuitでIEを閉じることができます。

↑動作イメージがつかめたらたたき台とて改良したり遊んでみてください


[#Document][ページ内のTOPへ戻る]

Documentオブジェクトの山からデータをイロイロな方法で抜く

下記↓、私のASP解説のテストページなのですが、ここの表からデータを抜いてみたいと思います
[http://www.ken3.org/cgi-bin/test/test028-2.asp]
↑test028-2.asp 感想データをORDER BY ID DESC で IDの降順で表示↓
IDF_TITLEF_MEMOWriteTime
6026説明が下手理解が難しい・・・2008/05/04 4:57:50
6025解らん使えないサイトだな2008/05/03 5:23:24
5968oktest2008/03/02 13:30:49
5696aa2007/09/19 19:04:19
5675IE操作UWSC使用が正解 変な記事書き続けるなボケ2007/09/09 23:31:41
5505てすとできるかな?2007/05/30 18:02:13
こんな感じのテーブルからデータを抜いてみます
動くサンプル:[Documentの山からテーブルデータを抜くサンプル 20080513_IE_TEST.zip]←Excel2003の.xlsファイルです。解凍後実行しながら下記の解説を見てみてください

処理の流れ・仕様は
1.IEを起動する CreateObject("InternetExplorer.application")
2.目的のURL(test28-2.asp)を開く .Navigate
3.テーブルからデータを抜く(Excelのシートにセットする)
なんて感じの3行おまかせ仕様で(笑)


[#Create_IE][ページ内のTOPへ戻る]

1.CreateObject("InternetExplorer.application")

OS XP で IE6(IE7)の起動 CreateObject で 起動させるのは意外と簡単で
CreateObject("InternetExplorer.application")
で、IEを起動しています。まずは、ここからかな。
読者の心の声:イマイチ何?言ってんだか?わからないのですが・・・ 三流君の説明聞くより、コード見たほうがハヤイって?

CreateObjectで起動する方法(XPやIE6の場合)は簡単で、


Sub ie_test()
    Dim objIE    As Object  'IEオブジェクト参照用
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)
End Sub
↑とにかくコレを貼り付けて実行してみてください。
CreateObject("InternetExplorer.application")でIEを起動させobjIEの変数に代入して、objIE.Visible = True 他のVBAでもおなじみの.VisibleプロパティをTrueにしてます。
読者の声:一言で言えよ、起動して可視(見えるように)しただけだろ。

※サンプルで私がよく使う好きな方法は、Set objIE = CreateObject("InternetExplorer.application")なのですが、Vista IE7の保護モードだと.Navigateで失敗したり・・[三流君 Vista IE7の修正でハマる(小細工で逃げる)] ← Vista IE7の人はこちらも見てください。


[#Document_Navigate][ページ内のTOPへ戻る]

2.URLを開く(.open)じゃなくって、.Navigateなんですよ

CreateObject("InternetExplorer.application")なんて感じで、無事にIEのオブジェクトを作成できたら、次は指定したURL(目的のサイト)を開きたいですよね。
まぁ、文章でもなんでもたいていは開く処理が必要ですよね。

Workbooks.Open Filename みたいに.Open?
それとも、.URLOpen?
ハヤク、IEでURLを開くメソッドを教えろコラ!!

アナタ、先走りますねぇ、想像力豊かでガマン汁出てるよ(オイオイ)じゃなくって、メソッドの名前を勝手に.URLOpenとか創造するなんて先走り過ぎ。※まぁ、予測・予想する能力もプログラマーとしてはとても大切で必要なんですが・・・([愚痴系 No.181 TimeAddって関数を予想する力? ]を暇な時にでも読んでみてください)

感覚は文章やブックを開く感覚でURLを開くOpenなのですが、URLを開く命令は.Navigateです。
今回作成して代入したオブジェクトがobjIEなので、
objIE.Navigate "http://〜(URLを文字列で)" って感じです。
データ表示のURL[http://www.ken3.org/cgi-bin/test/test028-2.asp]を開く(飛ばす)には、
下記のような命令を1行書きます(.Navigateメソッドを実行します)。

Sub ie_test_Navigate()

    Dim objIE    As Object  'IEオブジェクト参照用
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定した文字列のURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test028-2.asp"

End Sub
ねっ、簡単に目的のURLを開くことができたでしょ。
読者の声:だから一言で言えよ .Navigate URL文字列 でOKだろ。説明が無駄に長いんだよ。


[#Document_All][ページ内のTOPへ戻る]

3.開いた文章 Document に アクセスする

無事にページを開くことができたので、データを抜き出したいと思います。
イロイロな方法があるので(わざと回り道をしますが)自分に合った方法で取り出してみてください。

.Navigateメソッドで"http://www.ken3.org/cgi-bin/test/test028-2.asp"の文章を開くことができました。文章じゃねぇだろ?といったアナタへ
test028-2.aspへアクセスするとIIS WebServer が HTML から 始まる タグで囲われた文章(Document)を返してくれるので、まぁ広い意味でタグ付きの文章を開くって感じなんですよ。

タグ付きの文章?HTMLの文法に詳しくないのですが

<html><head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=x-sjis">
<META NAME="keyword" content="三流君,三流プログラマー,IE操作,objIE">
<title>三流君VBAでIE操作 InternetExplorer.Applicationを操作する</title>
</head>
<body bgcolor=#ffffff text=#000000><A NAME="TOP"></A>
<h1>三流君VBAでIE操作 InternetExplorer.Applicationを操作する</h1>
<p>文章など・・・</p>
<h2>データはDocumentの山からイロイロな方法で抜く</h2>
<p>文章など・・・</p>
<h3>テーブルは・・・</h3>
<TABLE Border='1'>
<TR><TH>ID</TH><TH>F_TITLE</TH><TH>F_MEMO</TH><TH>WriteTime</TH></TR>
<TR><TD>6026</TD><TD>説明が下手</TD><TD>理解が難しい・・・</TD><TD>2008/05/04 4:57:50</TD></TR>
<TR><TD>6025</TD><TD>解らん</TD><TD>使えないサイトだな</TD><TD>2008/05/03 5:23:24</TD></TR>
<TR><TD>5968</TD><TD>ok</TD><TD>test</TD><TD>2008/03/02 13:30:49</TD></TR><TR>
<TR><TD>5505</TD><TD>てすと</TD><TD>できるかな?</TD><TD>2007/05/30 18:02:13</TD></TR>
</TABLE>
  ・
  ・
  ・
</body></html>
など <html>〜</html>を受け取って IE(ブラウザ)さんが解析して表示をしてくれる。そんなイメージです。

Document.all(番号) で 文章にアクセスする

先走らないでここで深呼吸、一呼吸おいて、
VBAでExcelのブック・シート・セルへデータをセットする場合、下記のように
シート--範囲
Sheets("Sheet2").Range("B3").Value = "値 B列3行目です"

シート--セル(y,x)
Sheets("Sheet3").Cells(5, 4).Value = 1234
Sheets(シート名).Rangeや.Cellsでオブジェクトへアクセスして、.Valueなどプロパティに値をセットしていると思います。

HTMLの文章データを取り出す場合、オブジェクトの構造が
IEアプリの下 -- .Document(文章/ドキュメント) -- .all(n番目 or 項目名)
と.All.プロパティ で たどり着くことができるので(ほかにも表現方法はあるのですが今回はこれで)
objIE.Document.All(0).イロイロなプロパティ で 値を取り出してみます
(htmlドキュメント の ALL(0番目)頭 を 探って見たいと思います)

.InnerTEXT プロパティ と .InnerHTML プロパティを使ってみた

実際に文章 Documentオブジェクトに.InnerTEXTプロパティ と .InnerHTMLプロパティを使ってアクセスしてみたいと思います。
アクセス方法は簡単で、
objIE.Document.All(0).InnerTEXT
objIE.Document.All(0).InnerHTML

.InnerHTMLプロパティ.InnerTextプロパティから値を取り出して使用することができます。(テストで画面に表示してみたいと思います。)
※MsgboxでDocument.All(0).InnerHTML と Document.All(0).InnerTextを表示させて違いを確認しました。

Sub ie_test_Document_All_innerTEXT()

    Dim objIE    As Object  'IEオブジェクト参照用
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定した文字列のURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test028-2.asp"

    '手抜きで2秒待つ(オブジェクトの展開時間を待つ)
    Application.Wait Time:=Now + TimeValue("00:00:02")  '2秒間 ボーっとする

    '文章をMsgboxで表示する
    MsgBox objIE.Document.All(0).InnerTEXT
    MsgBox objIE.Document.All(0).InnerHTML

End Sub
.InnerTEXT プロパティでテキスト文章が.InnerHTMLプロパティで<タグ></タグ>付きのデータが表示されたと思います。

操作手順と実行結果の動画:VBA IE Document All innerTEXT の テスト その1

素朴な疑問 なぜ 2秒待つの

手抜きで2秒待つ(オブジェクトの展開時間を待つ)
↑何だコレ、手抜きって?、そもそも、なぜ2秒?
なぜ、待つかと言うと、いきなりさわるとビックリするでしょ?(オイオイ、何言ってんだおっさん)
表示待ちを入れないで いきなりオブジェクトに触りに行くと(ドキュメントなどのオブジェクトにアクセスすると) 相手の心の準備ができていないみたいで(オブジェクトの展開処理が間に合わないみたいで)、どこ見てんのよ(古)と怒られるじゃなかった、 実行時エラー Document メソッドは失敗しました ・・・など、エラーで怒られるんですよ。
エラーの画像→[http://ken3-info.blog.ocn.ne.jp/screen/2007/05/ie__debe.html]
なので、objIE.Navigate 後に相手の準備ができるが確認します。
手抜きの2秒はじゃなくてもっとチャントシタ行儀作法があるので後ほど。
えっ、今説明しないの?はい、アトで・・・気になる人は先に→[.ReadyStateと.Busyで待つ]を見てください

操作手順と実行結果の動画:IE 実行時エラー Document メソッドは失敗しました


[#Document_All_Length][ページ内のTOPへ戻る]
Document.Allのオブジェクトにアクセスする .Length と For Eachでまわす方法

今度は始めの0番目を表示だけじゃなくて、データを新しいシートに書き出してみます。

Document.All.Lengthでデータ数 添え字 All(i) でアクセス

バカの一つ覚えのExcelとの比較を一つ、ブック内のシート名を表示するテストプログラムを書きます。

Sub TEST_SHEET_NAME()
    'シートの名前をテストで表示する
    Dim i As Integer   'カウンター、添え字
    For i = 1 To ActiveWorkbook.Sheets.Count
        MsgBox i & " シートの名前 " & ActiveWorkbook.Sheets(i).Name
    Next i
End Sub

ActiveWorkbook.Sheets.Count
で、ブックのシート数が取れるので、ループで1からシート数分まわし、
ActiveWorkbook.Sheets(i).Name
で、i番目のシートの名前(.Name)を表示してます。

読者の声:だから何?、ドキュメント内のオブジェクト数は、objIE.Document.All.Countと言いたいの?感覚的にExcel VBAに慣れた人は.Countを使うと決め付けたいの??でも、要素の数は.Lengthなんでしょ?

あまり怒らないでくださいよ、タグ(Item)の数(要素の数)は.Countじゃなくて.Lengthです、配列も0から始まるので、
For i = 0 To objIE.Document.All.Length - 1
XXXX = "'" & objIE.Document.All(i).InnerTEXT
XXXX = "'" & objIE.Document.All(i).InnerHTML
Next i
と、i=0から初めて、.Length - 1までのループとしてます

Sub ie_test_Document_All_Length()

    Dim i As Integer  'カウンター
    Dim objIE    As Object  'IEオブジェクト参照用
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定した文字列のURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test028-2.asp"

    '手抜きで2秒待つ(オブジェクトの展開時間を待つ)
    Application.Wait Time:=Now + TimeValue("00:00:02")  '2秒間 ボーっとする

    '新規のブックを追加して、.InnerTEXTと.InnerHTMLを吐き出す
    Workbooks.Add  '新規ブックを追加
    
    Range("A1") = "NO.i番目"  '見出しのセット
    Range("B1") = "TypeName関数の結果"
    Range("C1") = ".TagName タグの名前"
    Range("D1") = ".OuterHTML 外側含むHTML"
    Range("E1") = ".InnerText 内側のTEXT"
    Range("F1") = ".InnerHTML 内側のHTML"
    Columns("A:G").ColumnWidth = 20 '列幅を20に変更
    
    'ループさせDocumentを書き出す
    For i = 0 To objIE.Document.All.Length - 1
        'データをセルへセットする
        Cells(i + 2, "A") = i 'i番目
        Cells(i + 2, "B") = "'" & TypeName(objIE.Document.All(i)) 'TypeNameでオブジェクトのタイプを表示
        
        Cells(i + 2, "C") = "'" & objIE.Document.All(i).TagName   'タグの名前
        Cells(i + 2, "D") = "'" & Left(objIE.Document.All(i).OuterHTML, 256) '頭から256文字だけセット
        Cells(i + 2, "E") = "'" & Left(objIE.Document.All(i).InnerText, 256)
        Cells(i + 2, "F") = "'" & Left(objIE.Document.All(i).InnerHTML, 256)
        
    Next i

    'IEを閉じる
    objIE.Quit
    Set objIE = Nothing

End Sub

他のIEオブジェクト操作でも 配列の要素数は、パターン的に.Lengthが多いので覚えておいてください・・それが言いたかっただけなんですが、Excelを例にしてた蛇足の解説でしたね(少々反省)

読者の声:蛇足でも何でもいいから、ハヤク、次行けよ
の前にさりげなく説明無しに使っている .OuterHTML 外側含むHTML とか TypeName関数 とか .TagName タグ や .Quit?

TypeName関数 を 使うと変数の中身のタイプを知ることができます。知ってどうする?の?
たとえば、HTMLTable や HTMLTableRow , HTMLTableCell を検索して例題を探すとか

.OuterHTMLは自分自身、外側を表示してくれるので解析時はこっちを使うと良かったり。
<TR><TD>DATA</TD><TD>DATA2</TD></TR>
↑オブジェクトにTRのデータが入っている時、
.OuterHTMLはそのまま <TR><TD>DATA</TD><TD>DATA2</TD></TR> を返し
.InnerHTMLは内側の <TD>DATA</TD><TD>DATA2</TD> を返します。
用途に応じて使い分けてください。

.TagName は そのままタグの名前を返すので、<TR>はTR <TD>はTDが返ってきます。泥臭い処理の時によく使うのかなぁ。

.Quit は 処理が終わり IEを閉じたいときに使います。 デバッグ中などはコメントアウトして そのままIEが開きっぱなしの方が確認しやすかったりしますが・・・
以上、簡単な説明でした。ぇっ、もう終わりカヨ・・・

操作手順と実行結果の動画:IE操作 Document.All.Length のテスト

.Length - 1までのループでエラーが発生する場合、指定したURLで広告などを表示していると(私のページも広告あるので)、途中で動的に要素の数が変わってしまい Document.All(i)にアクセスしに行くとエラーになったりします注意してね


[#Document_All_For_Each][ページ内のTOPへ戻る]
要素数を気にすんなよ (i)で参照 から For Each で回せば

よし、簡単なオブジェクトの説明終了、、、ここまで長かった。酔っぱらいの独り言に付き合っていただきどうもです。朝までにもう一軒飲み屋じゃなかった、オブジェクトをハシゴするぞと行きたい所ですが、あと一杯、少しだけお時間をとらせてください。

読者の声:だから、余計な会話はいいから、はやくシロ。(※←この読者の心の声もかなりの蛇足なんですが(笑)説明に必要ないでしょと思いつつ)

書き方に好みの問題もあるのですが、
objIE.Document.All(i)
と、配列(i番目)でまわす方法のほかに、
For Each 変数 In オブジェクト
なんて書き方もあります

読者の声:何言ってんだか、よくわからん。いつもの例 サンプルだせよ

えっ、いつもの蛇足の例を出して いいんですか?。では、お言葉に甘えてExcelのシートを例にして、

Sub TEST_SHEET_NAME_FOR_EACH()
    Dim objSHEET As Worksheet  'シートのオブジェクト受け取り用
    For Each objSHEET In ActiveWorkbook.Sheets
        MsgBox " シートの名前 " & objSHEET.Name
    Next
End Sub

みたいに、Dim objSHEET As Worksheetと受け取り用の変数を1つ定義して、
For Each objSHEET In ActiveWorkbook.Sheets
と記述すると、ActiveWorkbook.Sheets分だけ1つ1つ次のオブジェクトを取り出しながらループさせ、objSHEET.Nameみたいに(i)とか添え字や.Countなどの要素数を使わないで処理することができます。
頭から全てのデータをループさせる場合、このほうがスッキリとした記述かなぁ。
※三流君的には、.Length - 1のループでDocument.All(i)とか(n)、の書き方が好きだけど。

この書き方が Document.All でも 当然使えます。だってオブジェクト単位のループだしね。
For Each objTAG In objIE.Document.allで順番にobjTAGに入るので、
objTAG.OuterHTML や objTAG.InnerTEXT と書けるのでスッキリするのかなぁ。
処理によって使い分けてください。

Sub ie_test_Document_All_For_Each()

    Dim i As Integer  'カウンター
    Dim objIE    As Object  'IEオブジェクト参照用
    Dim objTAG   As Object  '1つ1つ タグのオブジェクトを入れる
    
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定した文字列のURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test028-2.asp"

    '手抜きで2秒待つ(オブジェクトの展開時間を待つ)
    Application.Wait Time:=Now + TimeValue("00:00:02")  '2秒間 ボーっとする

    '新規のブックを追加して、.InnerTEXTと.InnerHTMLを吐き出す
    Workbooks.Add  '新規ブックを追加
    
    Range("A1") = "NO.i番目"  '見出しのセット
    Range("B1") = "TypeName関数の結果"
    Range("C1") = ".TagName タグの名前"
    Range("D1") = ".OuterHTML 外側含むHTML"
    Range("E1") = ".InnerText 内側のTEXT"
    Range("F1") = ".InnerHTML 内側のHTML"
    Columns("A:G").ColumnWidth = 20 '列幅を20に変更
    
    'ループさせDocumentを書き出す
    i = 0
    For Each objTAG In objIE.Document.all
        'データをセルへセットする
        Cells(i + 2, "A") = i 'i番目 結局iは使うのかよ(笑)
        Cells(i + 2, "B") = "'" & TypeName(objTAG) 'TypeNameでオブジェクトのタイプを表示
        
        Cells(i + 2, "C") = "'" & objTAG.TagName   'タグの名前
        Cells(i + 2, "D") = "'" & Left(objTAG.OuterHTML, 256) '頭から256文字だけセット
        Cells(i + 2, "E") = "'" & Left(objTAG.InnerText, 256)
        Cells(i + 2, "F") = "'" & Left(objTAG.InnerHTML, 256)
        
        i = i + 1   'インクリメント
        
    Next

    'IEを閉じる
    objIE.Quit
    Set objIE = Nothing

End Sub

[#TABLE_TAG][ページ内のTOPへ戻る]
イロイロなTABLEタグの操作・処理

話を戻して、文章の表からデータを抜きたいんですよね、やりたいことは。 忘れてたよ

HTMLの表は、基本のパターンを書くと、

<TABLE> (テーブル開始)
 <TR>  (行開始)※1行目
   <TH>見出し1</TH>
   <TH>見出し2</TH>
   <TH>見出し3</TH>
 </TR> (行終了)

 <TR>  (行開始)※2行目
   <TD>DATA A</TD>
   <TD>DATA B</TD>
   <TD>DATA 3333</TD>
 </TR> (行終了)

 <TR>  (行開始)※3行目
   <TD>XXXXXX</TD>
   <TD>YYYYYY</TD>
   <TD>ZZZZZZ</TD>
 </TR> (行終了)

</TABLE>(テーブル終わり)
と、
<TABLE>テーブルのタグから始まり、
<TR>行の開始
<TD>列のデータ(<TH>の見出しをTDで書いているページもありです)

おおざっぱに書くと3つの組み合わせと順番です。


[#TagName][ページ内のTOPへ戻る]
.TagName <TR>で改行 <TD>でデータセットしてみる

ループで1つ1つの要素が取り出せるので、.TagName <TR>で改行 <TD>でデータセットしてみます
1.IEを起動させ 目的のサイト test028-2.asp を開きます
2.データセット用のBookを追加します
3. .TagName = <TR> で 行カウンタを+1 列カウンタを1に初期化
4. .TagName = <TD> or <TH> で .InnerText をセルにセット 列を+1 次へ
こんな感じの口答仕様書で作ってみます(4行で仕様書?当然、穴があるんだけど・・・)


'TABLE データ取り出し、TRで改行、TDの中身をセットする
Sub ie_test_Document_All_TagName_TR_TD()

    Dim x As Integer, y As Integer  '列と行カウンター
    
    Dim objIE    As Object  'IEオブジェクト参照用
    Dim objTAG   As Object  '1つ1つ タグのオブジェクトを入れる
    Dim strTNAME As String 'タグの名前を保存する
    
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定した文字列のURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test028-2.asp"

    '手抜きで2秒待つ(オブジェクトの展開時間を待つ)
    Application.Wait Time:=Now + TimeValue("00:00:02")  '2秒間 ボーっとする

    '新規のブックを追加して、.InnerTEXTを吐き出す
    Workbooks.Add  '新規ブックを追加
    
    y = 0  '行カウンターを初期化(はじめの改行で+1するので0から)
    x = 0  '列カウンターを初期化(TR 改行時に初期化するのでいらないんだけど)
    
    'Documentから.TagNameでTR TD THを判断して テキスト(.InnerText)を書き出す
    For Each objTAG In objIE.Document.all
        
        strTNAME = objTAG.TagName 'タグの名前を変数へ保存
        
        If strTNAME = "TR" Then   'TR行の開始なら
            y = y + 1   '行開始なので 行カウンターを+1
            x = 0       '列を0(頭)初期化
        End If
            
        If strTNAME = "TH" Or strTNAME = "TD" Then 'TH見出し TDデータ
            x = x + 1   '列カウンターを+1
            Cells(y, x) = "'" & objTAG.InnerText '.InnerTextをセットする
        End If
        
    Next

    '抜き出し処理が終わったので、普通はIEを.Quitで閉じる
    'objIE.Quit    'コメントにして処理しない(残しておいた方がテスト時は楽です)
    'Set objIE = Nothing

End Sub

ポイントは、特になく(オイオイ)、
For Each objTAG In objIE.Document.all で、文章から1つ1つタグを取り出し
strTNAME = objTAG.TagName でタグの名前を変数へ保存して、
単純にIf文で、TRの行のタグならyを増やし、
TH,TDならobjTAG.InnerTextでテキストを代入
そんな感じです。

実行してみると、データがセットされ完成・・と思いきや、後ろにゴミデータが入っているよ(笑)。
不具合には原因があります。
テストURL[http://www.ken3.org/cgi-bin/test/test028-2.asp]をよく見ると
データの表の下にソースコードの表(TABLE)と広告の表(TABLE)があります。
なるほどねぇ、目的のTABLE以外のTH,TDに反応してデータを書き出していたのかぁ。

操作手順と実行結果の動画:VBA IE TABLE取り出し その1 失敗バージョン

TABLEタグまで読み飛ばし、次のテーブルで抜ける

1番目のTABLEだけ、なんとか処理したいなぁ。
.TagName で /TABLEがあると便利なんだけど、無いんですよね。
泥縄式に仕様を追加してみます(朝令暮改 的な指示を出す上司・先輩はイヤですね)
1.IEを起動させ 目的のサイト test028-2.asp を開きます
2.データセット用のBookを追加します
3. .Document.all(n) はじめのTABLEがくるまでタグ(DATA)を読み飛ばします
4. .TagName = <TR> で 行カウンタを+1 列カウンタを1に初期化
5. .TagName = <TD> or <TH> で .InnerText をセルにセット 列を+1
6. .TagName = <TABLE> 次のTABLEが来たらループを抜ける
こんな処理に変更してみたいと思います


'TABLE データ取り出し、TRで改行、TDの中身をセットする
'初めのテーブルまで空読み  次のテーブルが来たら処理を抜ける
Sub ie_test_Document_All_TagName_TABLE_TR_TD()

    Dim x As Integer, y As Integer  '列と行カウンター
    Dim n As Integer, i As Integer
    Dim objIE    As Object  'IEオブジェクト参照用
    Dim objTAG   As Object  '1つ1つ タグのオブジェクトを入れる
    Dim strTNAME As String 'タグの名前を保存する
    
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定した文字列のURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test028-2.asp"

    '手抜きで2秒待つ(オブジェクトの展開時間を待つ)
    Application.Wait Time:=Now + TimeValue("00:00:02")  '2秒間 ボーっとする

    '新規のブックを追加して、.InnerTEXTと.InnerHTMLを吐き出す
    Workbooks.Add  '新規ブックを追加
    
    'はじめのTABLEまでから読みする
    For n = 0 To objIE.Document.all.Length - 1
        If objIE.Document.all(n).tagname = "TABLE" Then Exit For
    Next n
    
    y = 0  '行カウンターを初期化(はじめの改行で+1するので0から)
    x = 0  '列カウンターを初期化(TR 改行時に初期化するのでいらないんだけど)
    
    'Documentから.TagNameでTR TD THを判断して テキスト(.InnerText)を書き出す
    For i = n + 1 To objIE.Document.all.Length - 1
        
        strTNAME = objIE.Document.all(i).tagname 'タグの名前を変数へ保存
        
        If strTNAME = "TR" Then   'TR行の開始なら
            y = y + 1   '行開始なので 行カウンターを+1
            x = 0       '列を0(頭)初期化
        End If
            
        If strTNAME = "TH" Or strTNAME = "TD" Then 'TH見出し TDデータ
            x = x + 1   '列カウンターを+1
            Cells(y, x) = "'" & objIE.Document.all(i).InnerText '.InnerTextをセットする
        End If
        
        If strTNAME = "TABLE" Then   'TABLEなら(次のテーブルが現れたら)
            Exit For    'ループを強制的に抜けます
        End If
        
    Next i

    '抜き出し処理が終わったので、普通はIEを.Quitで閉じる
    'objIE.Quit    'コメントにして処理しない(残しておいた方がテスト時は楽です)
    'Set objIE = Nothing

End Sub

ポイントは、まず初めのTABLEまでデータを飛ばしたいので
変数nを使ったループを作り、
For n = 0 To objIE.Document.all.Length - 1
If objIE.Document.all(n).tagname = "TABLE" Then Exit For
Next n
Document.all(n).tagname が "TABLE" になった時点で強制的にループを抜けます。
次に、n+1番目からデータセットのループに入ります。
For i = n + 1 To objIE.Document.all.Length - 1
で、追加したのが、
If strTNAME = "TABLE" Then 'TABLEなら(次のテーブルが現れたら)
Exit For 'ループを強制的に抜けます
End If
i番目がTABLEだったら(次のテーブルが現れたら)ループを抜けて終了、こんな感じです。

操作手順と実行結果の動画:VBA IE テーブルからデータを泥臭く取り出す

Document.all から .tagname で判断して自分でセットする、そんな原始的 イヤ三流的な方法でした。嘘つきがもっとスマートな方法があるだろオイ・・と、上級読者様は突っ込まれたと思いますが、泥臭いループの練習、反面教師的ソースの例ってことでご勘弁を。


[#ExecWB][ページ内のTOPへ戻る]
コピー、貼り付けしてみたら?(.ExecWBでコマンド発行)

自分で1つ1つタグを見て?代入 そんな泥臭い方法よりも、まとめてコピペできないの?と普通の操作者は考えるよね
まぁ手作業だったら条件反射で(無意識に)
Ctrl+A全て選択 Ctrl+Cコピー Ctrl+V貼り付け
そんな操作を行うと思います。まずはIEの動作 メソッドを探って見たいと思います。

プロパティやメソッドを調べるなら、Excelのマクロ記録を使ってみたら?とよく聞きますよね、手順は→[プロパティ、メソッドの探り方 マクロ記録とF1のHelpを使う]← こんな感じです
ってことで、実際の操作を行い、マクロを記録してみます。
記録スタート
1. IEを立ち上げる
2. http://www.ken3.org/cgi-bin/test/test028-2.asp を URLに入力
3. ページが表示されたら、IE上で 編集・全て選択 編集・コピー
4. Excelに切り替えて貼り付け
記録終了(上記操作をマクロ記録してみます)

実際に記録したコードを見てみると、ダメだ記録されてない。。。
Sub Macro1()
    Sheets("Sheet2").Select
    Range("A1").Select
    ActiveSheet.PasteSpecial Format:="HTML", Link:=False, DisplayAsIcon:= _
        False
    ActiveWindow.SmallScroll Down:=-18
    Sheets("Sheet3").Select
    Range("A1").Select
    ActiveSheet.PasteSpecial Format:="テキスト", Link:=False, DisplayAsIcon:= _
        False
    Range("A5").Select
    ActiveWindow.SmallScroll Down:=-9
End Sub
残念ながら IEの起動や IE上での全てを選択・コピーのコードが記録されていません・・・

操作手順と実行結果の動画:マクロ記録でIE操作を記録できるかテストしてみた

マクロ記録に載らなかったことをいつまでも気にしていても先に進まないので、
MSDNのIEオブジェクトのメソッドを探ってみます
[InternetExplorer Object (MSDN)]
↑ここのMethods を探ってみます。
するとコマンドを発行する.ExecWB メソッド↓が見つかります。
[.ExecWB メソッド http://msdn.microsoft.com/en-us/library/aa752087.aspx]
使い方は、

object.ExecWB( _
    cmdID As OLECMDID, _
    cmdexecopt As OLECMDEXECOPT, _
    [pvaIn As Variant,] _
    [pvaOut As Variant])
object.ExecWB(cmdID(コマンドID)と , cmdexecoptを指定)するみたいですね。
どんなコマンドがあるか、
[OLECMDID http://msdn.microsoft.com/en-us/library/ms691264.aspx]をみると
12と17番の OLECMDID_COPY = 12 コピー, OLECMDID_SELECTALL = 17 セレクトオール が使えそうです。※その他、いろいろなコマンドがあるので見てください。
もう一つのパラメーター [OLECMDEXECOPT http://msdn.microsoft.com/en-us/library/ms683930.aspx]をみると
typedef enum  
{ 
    OLECMDEXECOPT_DODEFAULT        = 0, 
    OLECMDEXECOPT_PROMPTUSER       = 1, 
    OLECMDEXECOPT_DONTPROMPTUSER    = 2, 
    OLECMDEXECOPT_SHOWHELP         = 3 
} OLECMDEXECOPT; 
となっており、まぁ、DO DEFAULT の 0でいいのかなぁ。

test028-2.aspのページを表示後、全て選択(OLECMDID_SELECTALL = 17)発行後、コピー(OLECMDID_COPY = 12)を連続発行してから、Excelに貼り付けてみます。
シートを追加しながら、3パターンの貼り付けを実行してみます
'IEコマンド発行のテスト  全てを選択・コピーしてから、シートに貼り付けてみる
Sub ie_test_ExecWB()

    Dim objIE    As Object  'IEオブジェクト参照用
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定した文字列のURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test028-2.asp"

    '手抜きで2秒待つ(オブジェクトの展開時間を待つ)
    Application.Wait Time:=Now + TimeValue("00:00:02")  '2秒間 ボーっとする

    'テスト用に新規のブックを追加する
    Workbooks.Add  '新規ブックを追加
    
    '形式を選択して貼り付け HTML貼り付けのテスト
    objIE.ExecWB 17, 0  'OLECMDID_SELECTALL = 17 全てを選択
    objIE.ExecWB 12, 0  'OLECMDID_COPY = 12 コピー
    Sheets.Add          'テスト用のシートを新規追加する
    ActiveSheet.Name = "FormatHTML"  'シートに名前を付ける
    Range("A1").Select
    ActiveSheet.PasteSpecial Format:="HTML"
    
    '形式を選択して貼り付け Unicode テキスト貼り付けのテスト
    objIE.ExecWB 17, 0  'OLECMDID_SELECTALL = 17 全てを選択
    objIE.ExecWB 12, 0  'OLECMDID_COPY = 12 コピー
    Sheets.Add          'テスト用のシートを新規追加する
    ActiveSheet.Name = "FormatUnicode テキスト"  'シートに名前を付ける
    Range("A1").Select
    ActiveSheet.PasteSpecial Format:="Unicode テキスト"

    '形式を選択して貼り付け テキスト貼り付けのテスト
    objIE.ExecWB 17, 0  'OLECMDID_SELECTALL = 17 全てを選択
    objIE.ExecWB 12, 0  'OLECMDID_COPY = 12 コピー
    Sheets.Add          'テスト用のシートを新規追加する
    ActiveSheet.Name = "Formatテキスト"  'シートに名前を付ける
    Range("A1").Select
    ActiveSheet.PasteSpecial Format:="テキスト"

End Sub

操作手順と実行結果の動画:VBA IE ExecWBコマンドのテスト

う〜ん、使えそうな、使えなさそうな・・・全てじゃなくて、テーブルを指定して(範囲指定でドラックして)コピーできるといいんだけどなぁ。


[#createControlRange][ページ内のTOPへ戻る]
document.body.createControlRange を使い、テーブルを指定する

テーブルを選択 selectしたくてMSDNを探す

select Method (TextRange, controlRange)
http://msdn.microsoft.com/en-us/library/ms536735.aspx
が見つかります。

ここに、サンプルコードが2つあって、そのうちの一つが、
>function ControlRangeSelect() {
> var r = document.body.createControlRange();
> r.add(document.all.aaa);
> r.select();
>}
が、ありました。みるからにコントロールをセレクト、選択している?
この、document.all.aaa を 変更して、r.Add objIE.document.all(n) こんな感じで、.allから見つけたn番目(テーブル位置を指定)にしてみたいと思います。


'TABLEのオブジェクトをコピーして シートに貼り付けてみる
Sub ie_test_document_body_createControlRange()

    Dim objIE    As Object  'IEオブジェクト参照用
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定した文字列のURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test028-2.asp"

    '手抜きで2秒待つ(オブジェクトの展開時間を待つ)
    Application.Wait Time:=Now + TimeValue("00:00:02")  '2秒間 ボーっとする

    'はじめのTABLEまで空読みする
    Dim n As Integer
    For n = 0 To objIE.document.all.Length - 1
        If objIE.document.all(n).tagname = "TABLE" Then Exit For
    Next n

    Dim r As Object
    Set r = objIE.document.body.createControlRange
    r.Add objIE.document.all(n) '上で見つけたテーブルを指定する。
    r.Select                    'セレクト 選択
    objIE.ExecWB 12, 0          'コマンド発行 OLECMDID_COPY = 12 コピー

    'テスト用に新規のブックを追加する
    Workbooks.Add  '新規ブックを追加
    
    '形式を選択して貼り付け HTML貼り付けのテスト
    Sheets.Add          'テスト用のシートを新規追加する
    ActiveSheet.Name = "HTML形式で貼り付け"  'シートに名前を付ける
    Range("A1").Select
    ActiveSheet.PasteSpecial Format:="HTML"
    
    '形式を選択して貼り付け Unicode テキスト貼り付けのテスト
    Sheets.Add          'テスト用のシートを新規追加する
    ActiveSheet.Name = "FormatUnicode テキスト"  'シートに名前を付ける
    Range("A1").Select
    ActiveSheet.PasteSpecial Format:="Unicode テキスト"

    '形式を選択して貼り付け テキスト貼り付けのテスト
    Sheets.Add          'テスト用のシートを新規追加する
    ActiveSheet.Name = "Formatテキスト"  'シートに名前を付ける
    Range("A1").Select
    ActiveSheet.PasteSpecial Format:="テキスト"

End Sub

↑なんとか、テーブルのみを選択して貼り付けできました。まぁ、貼り付けの形式はHTML以外は使いにくいかなぁ。※罫線や文字飾りのない生データが貼り付いてくれたらうれしかったけど・・・

余談:後日(少し経ってから)興味があったので、createControlRange を さらに探すと、
プログラムでクリップボードに IMG 要素をコピーする方法
http://support.microsoft.com/kb/293125/ja
を見ると、
>この資料は、プログラムでクリップボードに( IMG Element の)
>Web ページでのイメージをコピーする方法を示します
ここにもサンプルソースがあって、
>  function copyImage(sImgID)
>   {
>      var ctrlRange = document.body.createControlRange();
>      ctrlRange.add(document.all(sImgID));
>      ctrlRange.execCommand("Copy");
>   }

んっ、.execCommand("Copy") これでコピーできるのかな?
ってことで、下記のようにプログラムを修正しました。
Sub ie_test_document_body_createControlRange22()

    Dim objIE    As Object  'IEオブジェクト参照用
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定した文字列のURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test028-2.asp"

    '手抜きで2秒待つ(オブジェクトの展開時間を待つ)
    Application.Wait Time:=Now + TimeValue("00:00:02")  '2秒間 ボーっとする

    'はじめのTABLEまで空読みする
    Dim n As Integer
    For n = 0 To objIE.document.all.Length - 1
        If objIE.document.all(n).tagname = "TABLE" Then Exit For
    Next n

    Dim r As Object
    Set r = objIE.document.body.createControlRange
    r.Add objIE.document.all(n)   '上で見つけたテーブルを指定する。
    r.Select                      'セレクト 選択(選択しなくてもコピー可能かなぁ)
    r.execCommand "Copy"          'コピーのコマンドを発行?

    'テスト用に新規のブックを追加する
    Workbooks.Add  '新規ブックを追加
    
    '形式を選択して貼り付け HTML貼り付けのテスト
    Sheets.Add          'テスト用のシートを新規追加する
    ActiveSheet.Name = "HTML形式で貼り付け"  'シートに名前を付ける
    Range("A1").Select
    ActiveSheet.PasteSpecial Format:="HTML"

End Sub
ところが、コピーの確認ダイアログが出ますね・・・
セキュリティのレベルが上がって自動実行にはツライ環境?になりましたね。う〜ん・・・
20080520001

.execCommand "Copy" でコピーする方法、惜しかったなぁ・・・カッコつけ損ねました(笑)ってことで、表のコピーはなんかカッコ悪いけど、テーブル選択後.ExecWB 12, 0とコピーのコマンドを発行してください。


[#Document_all_tags][ページ内のTOPへ戻る]
オブジェクトを指定したタグで抜くには .tags("タグ名")を使う

document.all(n)で.tagnameが指定したタグになるまで空読みとかいかにも泥臭いよね・・・
実はもっとスマートな読者様に好かれる方法があって、(読者の声:だったら先に書けよ)
.all コレクション の 中に、.tags メソッドなんて便利なメソッドがあって、
実行すると指定したタグのオブジェクトを返してくれるそんなイメージです。
※[.document .all .tags http://msdn.microsoft.com/en-us/library/ms536776.aspx]にMSDNのサンプルvar coll = document.all.tags("p");があります。
これ("p")をtableに変更してテストしてみます。


'文章 document 全体 all から指定したタグを抜き出す.tagsのテスト
Sub ie_test_document_all_tags()

    Dim objIE    As Object  'IEオブジェクト参照用
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定した文字列のURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test028-2.asp"

    '手抜きで2秒待つ(オブジェクトの展開時間を待つ)
    Application.Wait Time:=Now + TimeValue("00:00:02")  '2秒間 ボーっとする

    '.tags("TABLE") で テーブルオブジェクトを文章 document 全体 all から抜く
    Dim objTABLE As Object 'テーブルオブジェクトの格納用
    Set objTABLE = objIE.document.all.tags("TABLE")  'TABLEを指定して抜く
    
    'テーブル(0)初めのテーブルを範囲指定後、コピーする
    Dim objRANGE As Object  '範囲 ControlRange
    Set objRANGE = objIE.document.body.createControlRange  '範囲のオブジェクトを新規で作り
    objRANGE.Add objTABLE(0)    '(0)でテーブルを追加(指定する) 1番目は0からなので
    objRANGE.Select             '範囲のオブジェクトを セレクト 選択する
    objIE.ExecWB 12, 0          'コマンド発行 OLECMDID_COPY = 12 コピー
    
    'テスト用に新規のブックを追加する
    Workbooks.Add  '新規ブックを追加
    Sheets.Add     'シートを新規追加する
    ActiveSheet.Name = "test028のテーブル"  'シートに名前を付ける
    
    'TABLEデータをシートに貼り付ける
    Range("C3").Select    '先頭A1じゃ面白くないので C3をテストで選択
    ActiveSheet.PasteSpecial Format:="HTML" 'HTML形式を選択して貼り付け
    Columns("A:Z").EntireColumn.AutoFit   '手抜きでA-Zの列は時をオートで調整

    '後始末(使った食器はキレイにしてから戸棚に戻そうね)
    Set objRANGE = Nothing
    Set objTABLE = Nothing
    'objIE.Quit    '今回はコメントにして処理しない(残しておいた方がテスト時は楽です)
    'Set objIE = Nothing
    
End Sub

ポイントは、
Set objTABLE = objIE.document.all.tags("TABLE")
.tags("TABLE")を指定して抜いたオブジェクトをobjTABLEにセットします。
セットされたobjTABLEを使い、objTABLE(0)が1番目のテーブルなので、
Set objRANGE = objIE.document.body.createControlRange '範囲のオブジェクトを新規で作り
objRANGE.Add objTABLE(0) '(0)でテーブルを追加(指定する) 1番目は0からなので
objRANGE.Select '範囲のオブジェクトを セレクト 選択する
objIE.ExecWB 12, 0 'コマンド発行 OLECMDID_COPY = 12 コピー
と、して、テーブルをコピーして、HTML形式で貼り付けた、そんな感じです。

objTABLE(0)としてプログラムを組んでいると知りたいのが、配列の数ですよね、これも.Lengthで簡単に知ることができます。

    Dim objTABLE As Object 'テーブルオブジェクトの格納用
    Set objTABLE = objIE.document.all.tags("TABLE")  'TABLEを指定して抜く

    For n = 0 To objTABLE.Length - 1  '.Lengthがテーブル数なので-1する
        'テスト用シートを追加し名前をTABLE?とする
        Sheets.Add                      'のシートを新規追加する
        ActiveSheet.Name = "TABLE" & n  'TABLE0,1,2...シートに名前を付ける
    
        'テーブルを範囲指定後、コピーする
        Set objRANGE = objIE.document.body.createControlRange  '範囲のオブジェクトを新規で作り
        objRANGE.Add objTABLE(n)    '(n)で1つ1つテーブルを追加(指定する)
        objRANGE.Select             '範囲のオブジェクトを セレクト 選択する
        objIE.ExecWB 12, 0          'コマンド発行 OLECMDID_COPY = 12 コピー
    
        'TABLEデータをシートに貼り付ける
        Range("C3").Select    '先頭A1じゃ面白くないので C3をテストで選択
        ActiveSheet.PasteSpecial Format:="HTML" 'HTML形式を選択して貼り付け
    Next n
↑こんな感じで、.Lengthを使い、全てのテーブルを処理することもできます。

ループで全て回すなら、For Each を使えよ・・・と、読者様の声が聞こえたので、テストプログラムを書いてみます。
Sub ie_test_document_all_tags_for_each_in()

    Dim objIE    As Object  'IEオブジェクト参照用
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定した文字列のURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test028-2.asp"

    '手抜きで2秒待つ(オブジェクトの展開時間を待つ)
    Application.Wait Time:=Now + TimeValue("00:00:02")  '2秒間 ボーっとする

    'テスト用に新規のブックを追加する
    Workbooks.Add  '新規ブックを追加

    '.tags("TABLE") で テーブルオブジェクトを文章 document 全体 all から抜く
    Dim objTABLE As Object 'テーブルオブジェクトの格納用
    Dim objRANGE As Object  '範囲 ControlRange
    
    'objTABLE に.tags("TABLE")で取り出したオブジェクトを入れながらループ
    For Each objTABLE In objIE.document.all.tags("TABLE")  '.tags("TABLE")でテーブルタグのみ取り出す
        Sheets.Add  'テストのシートを新規追加する
    
        'テーブルを範囲指定後、コピーする
        Set objRANGE = objIE.document.body.createControlRange  '範囲のオブジェクトを新規で作り
        objRANGE.Add objTABLE    'テーブルを追加(指定する)
        objRANGE.Select          '範囲のオブジェクトを セレクト 選択する
        objIE.ExecWB 12, 0       'コマンド発行 OLECMDID_COPY = 12 コピー
    
        'TABLEデータをシートに貼り付ける
        Range("C3").Select    '先頭A1じゃ面白くないので C3をテストで選択
        ActiveSheet.PasteSpecial Format:="HTML" 'HTML形式を選択して貼り付け
    Next
    
    '後始末(使った食器はキレイにしてから戸棚に戻そうね)
    Set objRANGE = Nothing
    Set objTABLE = Nothing
    objIE.Quit    'IEを閉じる(テストでさんざん使ったから残しとかなくてもいいかな)
    Set objIE = Nothing
    
End Sub

ポイントは、
For Each objTABLE In objIE.document.all.tags("TABLE") '.tags("TABLE")でテーブルタグのみ取り出す
みたいに、For Each オブジェクト変数 In .document.all.tags("タグの名前")で1つ1つ指定したタグのオブジェクトを取り出して処理しています。
For n = 0 To objTABLE.Length - 1でループさせ
objTABLE(n)で使う方法と使い分けてイロイロと遊び、楽しんでください。

↑ここまでのXP+IE6,IE7で動くサンプルです→[Documentの山からテーブルデータを抜くサンプル 20080513_IE_TEST.zip]←Excel2003の.xlsファイルです、解凍後実行しながら、修正したりして遊んでみてください。


[#VistaIE7NG][ページ内のTOPへ戻る]

Vista IE7 Excel2007 で失敗

時代に取り残されたのか、サンプルで私がよく使う好きな方法は、Set objIE = CreateObject("InternetExplorer.application")なのですが、Vista IE7の保護モードだと.Navigateで失敗したり・・うまくIE制御ができません。※三流君被害者の会 会員を増やしていたり・・・
現状の失敗状態をお知らせします。And お勧めできない小細工方法を含めて

移動しました。続きは[Vista IE7 で動かない]を見て下さい。

Documentからデータを抜く 終わりの挨拶

まだまだ、書かないといけないDocument操作 プロパティやメソッドなどの組み合わせがあるのですが、このあたりで逃げるように失礼します(オイオイ)。更新が遅いけど温かく見守ってください 更新中 まだまだ書きかけ

いろいろな表現があって、かえって迷ってしまうかもしれませんが、数をこなすと見えてくるので、私のサンプルだけじゃなく、いろいろなサンプルを探して見てください。[番外編 GoogleでoIE,objIE,WebBrowserをKeyWordにして検索]にお勧めのキーワード検索方法を載せてます


[#Document_Froms][ページ内のTOPへ戻る]

HTML入力フォームをさわる(FORMオブジェクトにアクセス)

はじめに(あいさつ?):インターネットエクスプローラーの操作と一口に言ってもイロイロな操作があると思います。
そのうちの一つが、あるホームページ(URL)を表示して、入力フォームにデータをセットして登録ボタンを押す、この一連の流れをVBA上から行いたい・・・と日本語で書くのは簡単なんだけど、この流れをプログラムで記述してみたいと思います

初めの一歩・とっかかりとして、隣のメルマガ([ASPで遊ぶ])の宣伝を兼ねて(オイオイ) ASPとMDBで作ったデータ入力フォームにデータをセットしてみたいと思います。


[#Look_Form_SRC][ページ内のTOPへ戻る]

事前準備

VBAから、IEの入力フォームを操作する・・・と簡単に書いてますが、どこから手を付けるか、、、ですよねぇ。
まずは敵(ターゲット)を知る 事前準備からかな。
深呼吸して心を落ちつかせます(別にもともと落ち着いてるって?)
自動化の前に手動で、操作したいホームページを自分で(手作業で)操作して、処理のイメージをつかみます。
今回のターゲット → [http://www.ken3.org/cgi-bin/test/test029-2.asp]を開いて、手動でデータを入力したり、ボタンを押して、動きをチェックします

手動で操作のイメージを軽く頭に入れたら、
次に、文章(htmlなど)のソースを表示して<form>の中身を確認します。
いきなり、中身とかソースとか言われてもなぁ・・・頭の中?だらけだよ。
あっ、すいません、自分だけわかってて相手のこと考えて無くて。
目的の入力フォームの構造が知りたいので、
目的のページを表示後、
表示--ソースとするとhtmlやcgiの中身を手作業ですが確認できます。
[ソースの確認画面イメージ] ← 単純にIEのメニューから表示させているだけですが
※↑フレームやJavaScriptで細工されたページ、文字コードが違って化け文字になっている・・・など簡単に表示できない場合もありますが

繰り返すと、
・手作業で自動化したい操作を行ってみる。
・ソースを表示して、入力フォームや構造のチェックに使う準備をする
まずは、この2点です。


[#Document_Forms_Submit][ページ内のTOPへ戻る]

データセットとデータ送信(Submitボタン)のサンプル

今回は、よくあるデータ登録で、テキストボックスにデータを入力して、データ送信(Submitボタン)処理を行ってみます。

Formのデータ登録サンプル:[IE起動とデータセットのサンプル 20080527_IE_Form.zip]←Excel VBAです
↑保存後、実行しながら下記の解説を読んでみてください。

今回のターゲット(操作場所)は [http://www.ken3.org/cgi-bin/test/test029-2.asp] です。下記のような単純な入力フォームです。
データを入力して下さい。
感想を書き込んでください。
メルマガ区分選択:
ASPで遊ぶ、失敗する
VBAで楽しく
愚痴系メルマガ
コンビニのオモテとウラ
感想:


↑実際に入力したり、まずは手動で動かしてみてください。
←のソース↓下記、ターゲットの文章(test029-2.asp)から抜き出した<form>の中身(ソース)です。
  <FORM ACTION="test029-2.asp" METHOD="POST" NAME="inputTEST" id="test029">
  <INPUT TYPE="HIDDEN" NAME="NO" VALUE="0">
  <b>メルマガ区分選択:</b><br>
  <INPUT TYPE="RADIO" NAME="KUBUN" VALUE="ASP" CHECKED>ASPで遊ぶ、失敗する<br>
  <INPUT TYPE="RADIO" NAME="KUBUN" VALUE="VBA" >VBAで楽しく<br>
  <INPUT TYPE="RADIO" NAME="KUBUN" VALUE="GUCHI" >愚痴系メルマガ<br>
  <INPUT TYPE="RADIO" NAME="KUBUN" VALUE="24H" >コンビニのオモテとウラ<br>
  <b>感想:</b>
  
  <INPUT TYPE="TEXT" NAME="MEMO" SIZE=60 VALUE="VBA IE TEST"><br>
  <br>
  <INPUT TYPE="SUBMIT" NAME="btnSUBMIT" VALUE="書 込">
  <INPUT TYPE="RESET" NAME="btnRESET" VALUE="クリア">
  </FORM>

↑みたいな感じで、入力用のFORMが作られています。
この入力フォームに対して、操作(データをセット)してみたいと思います。

箇条書きの仕様書 流れを書く

最近の若者は仕様書くれとうるさいので(オイオイ)
手作業の操作をただ箇条書きにした流れを書いて渡してあげた(架空の話です、現実では通用しないのでくれぐれもマネなどせぬように...)

手動で操作した時の操作を今一度思い出してください。
まず、コンピュータの電源を入れて、ログインする(ここからやるの?)
・インターネットエクスプローラーを起動して、
・URLを入力 目的の文章・ページを表示させる(ショートカットやお気に入りの人も居るかなぁ)
・入力フォーム(画面の表示)を目で確認
・マウスやキーボードを使って入力エリアへデータをセットする。(データの入力)
・書 込(送信ボタン) を 押す
だいたいこんな感じかな。
そんなの言われなくてもわかってんだよ、しつこいなぁ、ハヤク コードの解説始めろよ※クドクてシツコイ男は嫌われるぞ

IEの起動 と ページの表示

最近流行の 高級料亭でも行っている料理の使い回し じゃないけど、解説の使い回しで、
[IEの起動] : CreateObject("InternetExplorer.application")でブラウザを起動させました
[.Navigateで開く] : 次に目的のページを開くために.Navigateメソッドでページを移動しました
上記を参考に(って言っても、URLが変わっただけですが)
Sub ie_test029_open()  'test029-2.aspを開くテスト

    Dim objIE      As Object  'IEオブジェクト参照用
    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test029-2.asp"

End Sub
上記プログラムで、
・インターネットエクスプローラーを起動して、
・URLを入力 目的の文章・ページを表示させる(ショートカットやお気に入りの人も居るかなぁ)
ここまでの操作ができました。


[#Document_ReadyState_Busy][ページ内のTOPへ戻る]

.Busy と .ReadyState を見て 表示の完了を待つ

次は、
・入力フォーム(画面の表示)を目で確認
です。コンピューターに目は付いていないので、IE Document.プロパティの値(状態変化)で判断します。
なぜ、表示完了を待つかと言うと、いきなり入れるとイタイでしょ?(オイオイ、何言ってんだおっさん)
表示待ちを入れないで いきなりオブジェクトに触りに行くと(フォームなどのオブジェクトにアクセスすると) 相手の心の準備ができていないみたいで(オブジェクトの展開処理が間に合わないみたいで)、どこ触ってんだよと怒られるじゃなかった、 実行時エラー Document メソッドは失敗しました ・・・など、エラーで怒られるんですよ。
エラーの画像→[http://ken3-info.blog.ocn.ne.jp/screen/2007/05/ie__debe.html]
なので、objIE.Navigate 後に相手の準備ができるが確認します。

いろいろな調理方法(待ち方)があるのですが、ここも私の好きな調理方法を紹介します(三流的手法を押しつけます)。
読者の声:Application.Wait Time:=Now + TimeValue("00:00:05") '5秒間待つとか秒数を増やす手抜きなんだろ?
ギク、、今回は少しまともな方法を使います、判断によさそうなプロパティが2つあるので、.Busy と .ReadyState の状態を見て読み込み完了を判断してみます。

1つ目の判断材料が.ReadyStateです。
MSDNの[.ReadyState http://msdn2.microsoft.com/en-us/library/aa752066.aspx]←を見ると、

Enum READYSTATE
    READYSTATE_UNINITIALIZED = 0
    READYSTATE_LOADING = 1
    READYSTATE_LOADED = 2
    READYSTATE_INTERACTIVE = 3
    READYSTATE_COMPLETE = 4
End Enum

と、定義されています。このプロパティがREADYSTATE_COMPLETE = 4になるまで待てばいいのかな。objIE.ReadyState <> 4と直接値の4を書いて使っています。(参照設定して objIE.ReadyState <> READYSTATE_COMPLETEと書くときれいですよ)

2つ目の判断材料が.Busyです
MSDNで.Busy プロパティ→[.Busy http://msdn2.microsoft.com/en-us/library/aa752050.aspx]を見ると
True or False なので、
Busy(忙しい?) True→忙しい、動いてる False→ヒマ、止まっている
単純に、objIE.Busy = Trueの間、ループで待ってみますか。

材料がそろったので、調理してみたいと思います。
Sub ie_ReadyState_Busy_TEST()  '表示待ちのテスト

    Dim objIE      As Object  'IEオブジェクト参照用
    
    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test029-2.asp"

    '表示完了を待つ
    While objIE.ReadyState <> 4
        Debug.Print ".ReadyState = " & objIE.ReadyState
        Debug.Print ".Busy = " & objIE.Busy  'デバッグで文字を書く
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend
    
    Debug.Print ".ReadyState = " & objIE.ReadyState
    Debug.Print ".Busy = " & objIE.Busy  'デバッグで文字を書く
    
    MsgBox objIE.Document.Forms(0).OuterHTML 'テストでForm(0)のHTMLを表示
    
End Sub
単純に、
While objIE.ReadyState <> 4で4の完了以外を回し(4になるまで回し)
もう一つ内側のループで、While objIE.Busy = True (忙しいあいだ回る?)
で、表示を待ってみました。


[#Input_Text][ページ内のTOPへ戻る]

IEのdocumentオブジェクト formを使ってhtml入力フォームにアクセスする

次の工程は、
・マウスやキーボードを使って入力エリアへデータをセットする。(データの入力)
です
※指定したURLを開き、相手の受け入れ準備も確認できたので、次はWeb上の入力フォームにデータを挿入してみたいと思います。

入力したいinputエリアは、
<INPUT TYPE="TEXT" NAME="MEMO" SIZE=20><br>
の部分です。 name=XXXX(NAME="MEMO")と定義されてます。
このnameを利用してオブジェクトを表現するには、どうするのだろう?

先走らないでここで深呼吸、一呼吸おいて(何事もあせっちゃダメよ落ち着いてね!!)
見慣れたExcelの例だと ブック・シート・セルへデータをセットする場合、下記のように
シート--範囲
Sheets("Sheet2").Range("B3") = "B列3行目です"

シート--セル(y,x)
Sheets("Sheet3").Cells(5, 4) = "y,x 5行目の4列です"
Sheets(シート名).Rangeや.Cellsでオブジェクトへアクセスしていると思います。
Htmlの入力フォームの場合、オブジェクトの階層構造が
IEアプリ--ドキュメント--フォーム--アイテム(項目)
で表すことができるので(ほかにも表現方法はあるのですが今回はこれで)
objIE.Document.Forms(0).Item("MEMO").Value = 値
htmlドキュメント フォーム(0番目) アイテム(名称:MEMO)に転記(代入)する。って感じです。
※今回Formに名前Name=が付いてるので、objIE.Document.Forms("inputTEST").Item("MEMO").Value = 値 のほうが.Forms(0)で0番目のフォームよりもカッコいいんだけど・・・(Formに名前がない場合が多いので、.Forms(0)を先にやらせてください)

下記のような感じでデータをFormのMEMOにセットすることができます
Sub ie_Forms_DataSET()  'データセットのテスト

    Dim objIE      As Object  'IEオブジェクト参照用
    
    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test029-2.asp"

    'ページが表示される 完了を待つ
    While objIE.ReadyState <> 4  'READYSTATE_COMPLETE = 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend

    'データをセットする
    'htmlドキュメント フォーム(0番目) アイテム(MEMO)に転記(代入)する
    objIE.Document.Forms(0).Item("MEMO").Value = "こんな感じでデータセット可能"

End Sub
ポイントは、
Excelなら、アプリ -- ブック(Book) -- シート(Sheet) -- セル(Cells)
のオブジェクト階層が、
アプリ -- html(Document) -- フォーム(Form) -- 入力エリア(A INPUT)
objIE.Document.Forms(0).Item("MEMO").Value
みたいな感じです。


[#Input_Submit][ページ内のTOPへ戻る]

.Submit メソッドを使って フォームの送信動作

次の工程は
・書 込(送信ボタン) を 押す
です
挿入(データをフォームにセット)できたら、次は、送信ボタン(書込や投稿)を押したいですよね・・・
実は、単純に該当フォームを.Submitなんてメソッドで できちゃったりするんですよ。
※オブジェクト.動作(メソッド) ってイメージかなぁ。

objIE.Document.Forms(0).Submit
こんな1行で、送信処理(書込や投稿)ができてしまいます。

データセット後にobjIE.Document.Forms(0).Submitを実行してみます。
Sub ie_Forms_Submit()  'データセット後 Submitボタンを押す

    Dim objIE      As Object  'IEオブジェクト参照用
    Dim strCOMMENT As String  'コメントの入力
    
    '固定文字だとつまらないので、INPUTBOXで感想をもらう
    strCOMMENT = InputBox("何か一言コメントを入れてください")
    If strCOMMENT = "" Then
        MsgBox "何か文字を入れてくださいね"
        Exit Sub  '途中で抜ける
    End If
    Application.WindowState = xlMinimized  '入力後Excelを最小化、下に下げる

    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate "'http://www.ken3.org/cgi-bin/test/test029-2.asp"

    'ページが表示される 完了を待つ
    While objIE.ReadyState <> 4  'READYSTATE_COMPLETE = 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend
    
    'データをセットする
    'htmlドキュメント フォーム(0番目) アイテム(MEMO)に転記(代入)する
    objIE.Document.Forms(0).Item("MEMO").Value = strCOMMENT
    
    'フォーム(0番目)を .Submit(送信・投稿) する
    objIE.Document.Forms(0).Submit  '送信処理

End Sub
↑strCOMMENT = InputBox で入力させ、objIE.Document.Forms(0).Item("MEMO").Value = strCOMMENTで代入後にobjIE.Document.Forms(0).Submitで送信しました。

読者の声:だからさっきから質問してるでしょ、.Submit ? Form ? F1押して表示されるExcel VBAのヘルプにそんなの一言も載ってないよ、データセットの件、なんとなくわかってきたけど、自分でも調べてみたいし、どこで調べるんだよ??
あっ、これですか・・
英語だけどMSDNの下記の項目を見るとオブジェクトの階層構造がわかりやすいと思います。
Reference for Visual Basic Developers [http://msdn.microsoft.com/en-us/library/aa752043.aspx] が 一覧で、その 下に、
document Object [http://msdn.microsoft.com/en-us/library/ms531073.aspx] をクリック 後に、
Collections を探っていくと、
forms Collection [http://msdn.microsoft.com/en-us/library/ms537457.aspx] オブジェクトがあります。
やっとFormまでたどり着けたので、
次に FORM Element | form Object [http://msdn.microsoft.com/en-us/library/ms535249.aspx]
のメソッドの中に
submit [http://msdn.microsoft.com/en-us/library/ms536771.aspx] があります。
※なかなか、探るのが大変ですが私も[三流君 が MSDN で InternetExplorer の 資料を探す]←みたいな非効率的な探し方をしたり、効率的に同じ処理を探すために検索に頼って[番外編 GoogleでoIE,objIE,WebBrowserをKeyWordにして検索]←みたいにして探ってます


[#Document_Forms_Radio][ページ内のTOPへ戻る]

ラジオボタン(INPUT TYPE="RADIO")を選択するサンプル

次は、ラジオボタン(INPUT TYPE="RADIO")を選択してみたいと思います。ラジオボタン選択後、テキストボックスにデータを入力して、書込ボタンを押す、そんな処理を行ってみます。

今回も前回同様(操作場所)は [http://www.ken3.org/cgi-bin/test/test029-2.asp] です。下記のような単純な入力フォームで メルマガ区分の4種類ラジオボタンを選択してみます。
データを入力して下さい。
感想を書き込んでください。
メルマガ区分選択:
ASPで遊ぶ、失敗する
VBAで楽しく
愚痴系メルマガ
コンビニのオモテとウラ
感想:


↑実際に入力したり、まずは手動で動かしてみてください。
←のソース↓下記、ターゲットの文章(test029-2.asp)から抜き出した<form>の中身(ソース)です。
  <FORM ACTION="test029-2.asp" METHOD="POST" NAME="inputTEST" id="test029">
  <INPUT TYPE="HIDDEN" NAME="NO" VALUE="0">
  <b>メルマガ区分選択:</b><br>
  <INPUT TYPE="RADIO" NAME="KUBUN" VALUE="ASP" CHECKED>ASPで遊ぶ、失敗する<br>
  <INPUT TYPE="RADIO" NAME="KUBUN" VALUE="VBA" >VBAで楽しく<br>
  <INPUT TYPE="RADIO" NAME="KUBUN" VALUE="GUCHI" >愚痴系メルマガ<br>
  <INPUT TYPE="RADIO" NAME="KUBUN" VALUE="24H" >コンビニのオモテとウラ<br>
  <b>感想:</b>
  
  <INPUT TYPE="TEXT" NAME="MEMO" SIZE=60 VALUE="VBA IE TEST"><br>
  <br>
  <INPUT TYPE="SUBMIT" NAME="btnSUBMIT" VALUE="書 込">
  <INPUT TYPE="RESET" NAME="btnRESET" VALUE="クリア">
  </FORM>

↑みたいな感じで、入力用のFORMが作られています。
この入力フォームに対して、操作(データをセット)してみたいと思います。

箇条書きの仕様書 流れを書く

最近の若者は仕様書くれとうるさいので(マダ言ってるよいい加減にしろよ)
手作業の操作をただ箇条書きにした流れを書いて渡してあげた(架空の話です、現実では通用しないのでくれぐれもマネなどせぬように...)
※読者からのクレーム(神の声):だったらマネできる仕様書の書き方を教えろ・公開しろって感じなんだけど。(三流作者:クレームは神の声です、検討します(←よく聞く検討しますの逃げ言葉・・・))

手動で操作した時の操作を今一度思い出してください。
・インターネットエクスプローラーを起動して、[IEの起動]
・URLを入力 目的の文章・ページを表示させる(ショートカットやお気に入りの人も居るかなぁ)[.Navigateで開く]
・入力フォーム(画面の表示)を目で確認[.ReadyStateと.Busyで待つ]
・ラジオボタンを選択する。(目的の区分を選択する)※今回の目的
・マウスやキーボードを使って入力エリアへデータをセットする。(データの入力)[Input TEXTにデータをセット]
・書 込(送信ボタン) を 押す[.Submitで送信処理]
だいたいこんな感じかな。
そんなの言われなくてもわかってんだよ、しつこいなぁ、ハヤク コードの解説始めろよ※クドクてシツコイ男は嫌われるぞ


[#Input_Radio][ページ内のTOPへ戻る]

ラジオボタンの攻略方法を紹介する

IEの起動 と ページの表示ができたら、ラジオボタンの選択を行いたいと思います。

ソースを見ると、<INPUT TYPE="RADIO"で名前もNAME="KUBUN"で一緒、VALUE=と値だけが違います。


<INPUT TYPE="RADIO" NAME="KUBUN" VALUE="ASP" CHECKED>ASPで遊ぶ、失敗する<br>
<INPUT TYPE="RADIO" NAME="KUBUN" VALUE="VBA" >VBAで楽しく<br>
<INPUT TYPE="RADIO" NAME="KUBUN" VALUE="GUCHI" >愚痴系メルマガ<br>
<INPUT TYPE="RADIO" NAME="KUBUN" VALUE="24H" >コンビニのオモテとウラ<br>

このINPUT RADIO群をいろいろとさわって、選択状態 Checkedにしてみたいと思います。

準備と確認 FORMの構成要素をFor Eachで1つ1つ取り出してみた

HTML タグなどで表現された文章、タグが階層構造になっているとか言ってました。FORMも文章の一部で、その中(<FORM>〜</FORM>まで)のイロイロなタグによって構成されています。
だから何?
えっと、Formの構成要素を1つ1つ取り出してみます。

For Each objTAG In objIE.Document.Forms(0)で1つ1つ要素をobjTAGに入れて、.Value , .Name を表示させてみました。
Sub ie_Forms_Input_Radio_001()  'Form(0)の下、構成要素を1つ1つ取り出す

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

    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test029-2.asp"

    'ページが表示される 完了を待つ
    While objIE.ReadyState <> 4  'READYSTATE_COMPLETE = 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend
    
    'データをセットする
    'htmlドキュメント フォーム(0番目) アイテム(MEMO)に転記(代入)する
    objIE.Document.Forms(0).Item("MEMO").Value = "テスト中"
    
    '※FORM(0)の下 オブジェクトを1つ1つ表示してみた
    Dim i As Integer      'カウンター
    Dim objTAG As Object  'タグのオブジェクト格納用

    Workbooks.Add  'テスト用の新規ブックを追加
    
    Range("A1") = "NO.i番目"  '見出しのセット
    Range("B1") = "TypeName関数の結果"
    Range("C1") = ".TagName タグの名前"
    Range("D1") = ".OuterHTML 外側含むHTML"
    Range("E1") = ".Value 値"
    Range("F1") = ".Name 項目に付けた名前"
    Columns("A:G").ColumnWidth = 20 '列幅を20に変更
    
    'Form(0)のオブジェクトをFor Each で書き出す
    i = 0
    For Each objTAG In objIE.Document.Forms(0)
        'データをセルへセットする
        Cells(i + 2, "A") = i 'i番目 結局iは使うのかよ(笑)
        Cells(i + 2, "B") = "'" & TypeName(objTAG) 'TypeNameでオブジェクトのタイプを表示
        
        Cells(i + 2, "C") = objTAG.TagName   'タグの名前
        Cells(i + 2, "D") = "'" & Left(objTAG.OuterHTML, 256) 'HTML 頭から256文字
        Cells(i + 2, "E") = objTAG.Value  '値
        Cells(i + 2, "F") = objTAG.Name   '名前
        
        i = i + 1   'インクリメント
    Next

End Sub
↑の実行結果↓

.Value と .NAMEが使えそうです。


[#Input_Radio_Checked][ページ内のTOPへ戻る]
ラジオボタン オブジェクトの.Checked = True

オブジェクトをどうにか特定できそうなので、実際にチェックしてみたいと思います。
名前(.NAME) が KUBUN

値(.Value) が VBA
のオブジェクトの.CheckedプロパティをTrueにしてみます。

For Each objTAG In objIE.Document.Forms(0) で回して、単純にIF文で .Name=KUBUN .Value=VBAを判断後、.Checked=Trueにしてみました。
Sub ie_Forms_Input_Radio_Checked()  '見つけたボタンのCheckedにTrueをセット

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

    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test029-2.asp"

    'ページが表示される 完了を待つ
    While objIE.ReadyState <> 4  'READYSTATE_COMPLETE = 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend
    
    'HTML Formにデータをセットする
    'htmlドキュメント フォーム(0番目) アイテム(MEMO)に転記(代入)する
    objIE.Document.Forms(0).Item("MEMO").Value = "VBAをCHKする"

    '目的のラジオボタンを探す
    'Form(0)のオブジェクトをFor Each で探る
    Dim objTAG As Object  'タグのオブジェクト格納用
    For Each objTAG In objIE.Document.Forms(0) '構成要素を1つ1つ取り出す
        '名前がKUBUN で 値がVBAのデータを探す
        If objTAG.Name = "KUBUN" And objTAG.Value = "VBA" Then '見つかったか?
            objTAG.Checked = True  '.Checked = True で チェックを付ける
            Exit For               '探し終わったのでループを抜ける
        End If
    Next
    
End Sub
For Each objTAG In objIE.Document.Forms(0)でループを作り、
If objTAG.Name = "KUBUN" And objTAG.Value = "VBA" Thenで該当オブジェクトを特定して、
見つけたオブジェクトの.CheckedプロパティにTrueをセットしただけです。(わかってしまえば意外と簡単?だった)


[#Input_Radio_Click][ページ内のTOPへ戻る]
ラジオボタン オブジェクトを.Clickしてみた

プログラミングの面白さって、同じ結果を得るのにイロイロな書き方があるって所ですよね。まぁ、回答が1つじゃないので個性が出たり、書き方の好き嫌いでもめたりするんだけどね。。。(読者の声:そんな無駄話はいいから、簡単な近道があるなら寄り道しないで教えろよ)

えっと、ラジオボタンの.CheckedプロパティにTrueをセットして選択したのですが、別の方法があって、オブジェクトに対してクリックする、.Clickメソッドを発行する、そんな方法もあります。

簡略仕様書(いつもの使えない箇条書き仕様書)
1.InputBoxで上司・先輩への愚痴を文字列で受け取ります
2.次にIEを起動してWebページを開き
3.フォームの名前がinputTESTのHTML Formに対して以下の処理を行え
 ア..Name(名前)=KUBUN,.Value(値)=GUCHIのオブジェクトを.Click(クリック)
 イ..Name(名前)=MEMOのオブジェクトに入力文字列をセット
 ウ. .Name(名前)=btnSUBMITのオブジェクトを.Click(クリック)
Sub ie_Forms_Input_Radio_Click()  '見つけたオブジェクトをClick

    '1.InputBoxで上司・先輩への愚痴を文字列で受け取ります
    Dim strCOMMENT As String  'コメントの入力
    
    '固定文字だとつまらないので、INPUTBOXで感想をもらう
    strCOMMENT = InputBox("上司や先輩への愚痴は?", "遠慮無く愚痴って", "まともな仕様書書け")
    If strCOMMENT = "" Then
        MsgBox "何か文字を入れてくださいね"
        Exit Sub  '途中で抜ける
    End If

    '2.次にIEを起動してWebページを開く
    Dim objIE      As Object  'IEオブジェクト参照用

    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test029-2.asp"

    'ページが表示される 完了を待つ
    While objIE.ReadyState <> 4  'READYSTATE_COMPLETE = 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend
    
    '3.フォームの名前がinputTESTのHTML Formに対して以下の処理を行え
    ' ア..Name(名前)=KUBUN,.Value(値)=GUCHIのオブジェクトを.Click(クリック)
    ' イ..Name(名前)=MEMOのオブジェクトに入力文字列をセット
    ' ウ. .Name(名前)=btnSUBMITのオブジェクトを.Click(クリック)
    
    Dim objTAG As Object  'タグのオブジェクト格納用
    
    'Form("inputTEST")のオブジェクトをFor Each で探る
    For Each objTAG In objIE.Document.Forms("inputTEST") '構成要素を1つ1つ取り出す
        '名前で分岐
        Select Case objTAG.Name
            Case "KUBUN": 'ア..Name(名前)=KUBUN
                If objTAG.Value = "GUCHI" Then '.Value(値)=GUCHIのオブジェクト?
                    objTAG.Click               '.Value(値)=GUCHIのオブジェクトを.Click(クリック)
                End If
            Case "MEMO"   'イ..Name(名前)=MEMOのオブジェクトに入力文字列をセット
                objTAG.Value = strCOMMENT  '値をセットする
            Case "btnSUBMIT" 'ウ. .Name(名前)=btnSUBMITのオブジェクトを.Click(クリック)
                objTAG.Click
                Exit For   'ボタンを押したので強制的にループを抜ける。
        End Select
    Next
   
End Sub
↑通常は、こんな書き方見かけないと思いますが・・・まぁ、いろいろな表現方法があるってことで、、、
いつもDocument.Forms("0")と0番目とか手抜きでやってましたが、
<FORM ACTION="test029-2.asp" METHOD="POST" NAME="inputTEST" id="test029">
みたいにFORMに名前が付いているなら、Document.Forms("inputTEST")と名前で表すこともできます、こちらの方がみなさんの好みかな。
当然 objIE.Document.Forms(0).Item("MEMO").ValueもobjIE.Document.Forms("inputTEST").Item("MEMO").Valueと書けます。
Form .Submitメソッドでデータを送信できるのですが、ボタンを押す、.Clickメソッド クリック動作でデータを登録することもできます。(ボタンにJavaScriptが貼ってある場合.Clickが有効な場合が多いです)
今回、ループの中でbtnSUBMITボタンを探しましたが objIE.Document.Forms("inputTEST").Item("btnSUBMIT").Clickなんて書き方もOKです。※ボタンの位置がたまたま一番下だったので、ループの中でクリックしてもOKだったけど、ボタンが上にあったらデータセット前に送信ボタンを押してしまいうまくいきませんよ。できたらデータセットとボタンを押すプログラムはわけたほうがいいです。

関連項目:[HTML入力フォーム外側のボタンを押す .Click]
(過去のメルマガ)[No.148 IE ラジオボタン(RADIO)の.Checkedと.Clickの違い]


[#Document_Forms_Select][ページ内のTOPへ戻る]

FORM SELECT OPTION の攻略(選択)サンプル

今回は、データの選択方法でよく見かける SELECT OPTION の選択処理を行ってみます。
リストから1つのOPTIONを選択する場合▼の ドロップダウン パターン

リストからCtrlキーを押して複数選択可能な[SELECT 複数OPTIONの選択] パターン リストボックスのイメージかな?
の2つがあると思います。

まずは、OPTIONを単独で選択する場合を攻略したいと思います。今回のターゲット(操作場所)は [http://www.ken3.org/cgi-bin/test/test092-2.asp] です。下記のような選択(SELECT OPTION)です。
SELECT OPTION の 入力(選択) TEST
表示したい・区分を選択して検索ボタンを押してください

↑実際に入力したり、まずは手動で動かしてみてください。
←のソース↓下記、ターゲットの文章(test092-2.asp)から抜き出した<form>の中身(ソース)です。
<FORM ACTION="test092-2.asp" METHOD="POST">
<font color="blue">SELECT OPTION の 入力(選択) TEST</font><br>
表示したい・区分を選択して検索ボタンを押してください<br>
<SELECT name="KUBUN">
   <option value="">全てのデータ</option>
   <option value="ASP">ASPのデータ</option>
   <option value="VBA">VBAのコメント</option>
   <option value="GUCHI">愚痴系</option>
   <option value="24H">24Hコンビニ</option>
</SELECT>
<INPUT TYPE="submit" VALUE="検索する">
</FORM>

↑みたいな感じで、入力用のFORM 選択(SELECT OPTION)が作られています。
この入力フォームに対して、操作(データをセット)してみたいと思います。


[#Select_Option_Selected][ページ内のTOPへ戻る]

選択なので、素直にオブジェクト .Selected = True にする

手間だけど、Form下のオブジェクトを表示させて探ってみますか。
下記、単純にページを表示させ、手抜きでForm(0)の下、オブジェクトをシートに書き出してみました。
Sub ie_Forms_Input_Select_001()  'Form(0)の下、構成要素を1つ1つ取り出す

    '調査するURLをInput Boxでもらう
    Dim strURL As String    '調査したいURL
    strURL = InputBox("調べたいURL", "URL", "http://www.ken3.org/cgi-bin/test/test092-2.asp")

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

    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate Trim(strURL)   '念のため左右の空白を取ってから、.Navigateに渡す
    
    'ページが表示される 完了を待つ
    While objIE.ReadyState <> 4  'READYSTATE_COMPLETE = 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend
    
    '※FORM(0)の下 オブジェクトを1つ1つ表示してみた
    Dim i As Integer      'カウンター
    Dim objTAG As Object  'タグのオブジェクト格納用

    Workbooks.Add  'テスト用の新規ブックを追加
    
    Range("A1") = "NO.i番目"  '見出しのセット
    Range("B1") = "TypeName関数の結果"
    Range("C1") = ".TagName タグの名前"
    Range("D1") = ".OuterHTML 外側含むHTML"
    Range("E1") = ".Value 値"
    Range("F1") = ".Name 項目に付けた名前"
    Columns("A:G").ColumnWidth = 20 '列幅を20に変更
    
    'Form(0)のオブジェクトをFor Each で書き出す
    i = 0
    For Each objTAG In objIE.Document.Forms(0)
        'データをセルへセットする
        Cells(i + 2, "A") = i 'i番目 結局iは使うのかよ(笑)
        Cells(i + 2, "B") = "'" & TypeName(objTAG) 'TypeNameでオブジェクトのタイプを表示
        
        Cells(i + 2, "C") = objTAG.TagName   'タグの名前
        Cells(i + 2, "D") = "'" & Left(objTAG.OuterHTML, 512) 'HTML 頭から512文字だけ書く
        Cells(i + 2, "E") = objTAG.Value  '値
        Cells(i + 2, "F") = objTAG.Name   '名前
        
        i = i + 1   'インクリメント
    Next
    
End Sub
↑を実行すると↓の結果が表示されました。

↑あれれ、Optionが見つからないよ。<SELECT>〜</SELECT>の中だからか?

For Each objTAG In objIE.Document.Forms(0) だと、<Option>へ たどり着けなかったので、For Each objTAG In objIE.Document.Forms(0).All.Allを付けて探ってみました。
Sub ie_Forms_Input_Select_002()  'Form(0).Allの下、構成要素を1つ1つ取り出す

    '調査するURLをInput Boxでもらう
    Dim strURL As String    '調査したいURL
    strURL = InputBox("調べたいURL", "URL", "http://www.ken3.org/cgi-bin/test/test092-2.asp")

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

    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate Trim(strURL)   '念のため左右の空白を取ってから、.Navigateに渡す
    
    'ページが表示される 完了を待つ
    While objIE.ReadyState <> 4  'READYSTATE_COMPLETE = 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend
    
    '※FORM(0).Allの下 オブジェクトを1つ1つ表示してみた
    Dim i As Integer      'カウンター
    Dim objTAG As Object  'タグのオブジェクト格納用

    Workbooks.Add  'テスト用の新規ブックを追加
    
    Range("A1") = "NO.i番目"  '見出しのセット
    Range("B1") = "TypeName関数の結果"
    Range("C1") = ".TagName タグの名前"
    Range("D1") = ".OuterHTML 外側含むHTML"
    Range("E1") = ".Value 値"
    Range("F1") = ".Name 項目に付けた名前"
    Columns("A:G").ColumnWidth = 20 '列幅を20に変更
    
    'Form(0).AllのオブジェクトをFor Each で書き出す
    i = 0
    For Each objTAG In objIE.Document.Forms(0).All
        'データをセルへセットする
        Cells(i + 2, "A") = i 'i番目 結局iは使うのかよ(笑)
        Cells(i + 2, "B") = "'" & TypeName(objTAG) 'TypeNameでオブジェクトのタイプを表示
        
        Cells(i + 2, "C") = objTAG.TagName   'タグの名前
        Cells(i + 2, "D") = "'" & Left(objTAG.OuterHTML, 512) 'HTML 頭から512文字だけ書く
        
        '※タグの名前がSELECTかOPTIONの時だけ値を書く(FONTタグなど値や名前を持たないタグがあるので)
        If objTAG.TagName = "SELECT" Or objTAG.TagName = "OPTION" Or objTAG.TagName = "INPUT" Then
            Cells(i + 2, "E") = objTAG.Value  '値
        End If

        '※タグの名前がSELECTかINPUTの時だけ名前を書く(FONTタグなど名前を持たないタグがあるので)
        If objTAG.TagName = "SELECT" Or objTAG.TagName = "INPUT" Then
            Cells(i + 2, "F") = objTAG.Name   '名前
        End If

        i = i + 1   'インクリメント
    Next
    
End Sub
※FONTやBRなど名前・値を持たないオブジェクトがあるので注意
↑を実行すると↓の結果が表示されました。

↑For Each objTAG In objIE.Document.Forms(0).All のループだと、OPTIONが取れます※余計な FONT や BR も 付いてくるけど、まぁ、よしとしますか。

For Each objTAG In objIE.Document.Forms(0).All のループで、OPTIONを取り出せたので、値(.Value)がVBAのオブジェクトを選択(.Selected=True)してみます。
Sub ie_Forms_Input_Select_003()  'Form(0).Allの下、.TagName = "OPTION" .Value="VBA" を探し.Select=Trueにする

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

    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test092-2.asp"

    'ページが表示される 完了を待つ
    While objIE.ReadyState <> 4  'READYSTATE_COMPLETE = 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend
    
    '※FORM(0).Allの下 オブジェクトを1つ1つ探す
    Dim objTAG As Object  'タグのオブジェクト格納用

    'Form(0).AllのオブジェクトをFor Each で取り出す
    For Each objTAG In objIE.Document.Forms(0).All
        'タグの名前がOPTIONで値がVBAのオブジェクトを探す
        If objTAG.TagName = "OPTION" Then   '初めにOPTIONタグを探す
            If objTAG.Value = "VBA" Then    '次に値がVBAを探す
                objTAG.Selected = True   '.Selected = Trueで選択状態にする
                Exit For                 '見つかったのでループを抜ける
            End If
        End If
    Next

End Sub
↑こんな感じで、タグがOPTION 値がVBAのデータを選択(.Selected=True)できました。


[#Select_Value][ページ内のTOPへ戻る]

もっと素直に<SELECT>タグ .Value に 値をそのままセット

んっ、↑で、Document.Forms(0).All のループで回してとか言ってたけど、その前に<OPTION>は<SELECT>〜</SELECT>の中だからか?なんて言ってたよね。
はい、言ってたよ。それが何か?
何かじゃねぇダロ、選択させる値が<SELECT>〜</SELECT>の中なら初めから、<SELECT>のタグに、.Valueに値をセットしてみたら?<OPTION>を探して.Selected=Trueなんてやってられるか
、、ってことで実際にやってみました。
Sub ie_Forms_Input_Select_004()  'Form(0).Item("KUBUN").Value="24H" と 値をセットする

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

    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test092-2.asp"

    'ページが表示される 完了を待つ
    While objIE.ReadyState <> 4  'READYSTATE_COMPLETE = 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend
    
    'Form(0) の アイテム(名前がKUBUN) の 値(.Value) を 24Hにする(24Hを選択する)
    objIE.Document.Forms(0).Item("KUBUN").Value = "24H"

End Sub
↑の1行でできてしまいました・・・あらら。※スミマセン、遠回りさせてしまって。

関連項目:値を直接セットできるなら、(過去のメルマガ)→ [No.154 IE SELECTタグの選択 .SelectedIndex=nで選択] も、必要なかったか・・・次に説明しようとしたのに。。。
じゃなくて屁理屈をこねると、値を変えただけだとJavaScriptのイベントが発生しないので、(過去のメルマガ)→[No.155 IE SELECT後 .fireEventでJavaScriptのイベントを起動]みたいなことが必要だし、<OPTION>を探して.Selected=Trueの応用で、探した<OPTION>を.ClickすればJavaScriptも起動する(過去のメルマガ 例はラジオボタンの.Checkedだけど)→ [No.148 IE ラジオボタン(RADIO)の.Checkedと.Clickの違い ] ってことで、<OPTION>タグを1から探す方法も無駄じゃない・・と、かなりの行数をかけて力説してみました。(読者の声:※素直にあやまればいいのに、屁理屈言って粘る 謝らないプログラマーっているよね。実力が三流のクセにプライドだけは一流ぶってるヤツ、えっ私Ken3のこと?(笑))


[#Select_Multiple][ページ内のTOPへ戻る]

FORM SELECT Size=n行 Multipleで複数選択が可能なOPTION の攻略(選択)サンプル

上で単独のOPTION選択を行ったので、次は、SELECT Size=nで複数表示されたリストボックスから、Ctrl+クリックで複数のOPTIONデータを選択する方法を探ってみたいと思います。
今回のターゲット(操作場所)は [http://www.ken3.org/cgi-bin/test/test093-5.asp] です。下記のようなリストボックスで複数選択可能なSELECTタグとOPTIONタグです。
FORM リストボックスの複数選択(selectタグ multiple で VALUE=を個別に作成)
表示したい・区分を選択後、検索ボタンを押してください
Ctrlキーを押しながらクリックすると、複数を選ぶことができます


↑実際に入力したり、まずは手動で動かしてみてください。
←のソース↓下記、ターゲットの文章(test093-5.asp)から抜き出した<form>の中身(ソース)です。
<font color="blue">FORM リストボックスの複数選択(selectタグ multiple で VALUE=を個別に作成)</font><br>
<FORM ACTION="test093-5.asp" METHOD="POST">
表示したい・区分を選択後、検索ボタンを押してください<br>
Ctrlキーを押しながらクリックすると、複数を選ぶことができます<br>
<SELECT NAME="KUBUN" SIZE="5" multiple>
 <option VALUE="ASP">ASP 感想(ASP)</option> 
 <option VALUE="VBA">VBA 感想(VBA)</option> 
 <option VALUE="24H">コンビニ系(24H)</option> 
 <option VALUE="GUCHI">愚痴系(GUCHI)</option> 
</SELECT><br>
<INPUT TYPE="submit" VALUE="検索する">
</FORM>

↑みたいな感じで、入力用のFORM 選択(SELECT OPTION)が作られています。
この入力フォームに対して、複数選択の操作(データをセット)してみたいと思います。


[#Select_Multiple_Selected][ページ内のTOPへ戻る]

Forms(0).All.tags("OPTION")で探したオブジェクトを.Selected = Trueにする

複数でも単独と同様、OPTIONの選択は.Selected = Trueかな。
単独のOPTION選択の時、[Option .Selected]で単純に For Each objTAG In objIE.Document.Forms(0).Allでループして.TagNameでOptionタグを探しOptionタグ.Selected = Trueをセットしました。

今回、同じだとつまらないので、少し変えてみます。.Allで指定したタグを抜くことが可能な、[.tags("タグの名称")]を使って、
For Each objTAG In objIE.Document.Forms(0).All.tags("OPTION")でFormからOPTIONのみを抜き、
値をチェック .Value="VBA" なら.Selected = True

表示文章(TEXT)の値 .InnerTEXT="愚痴系(GUCHI)" なら同じく.Selected = True
値とテキストをみて判断してみます。(※↑.InnerTEXTで見えているリストの文章を選択するのもアリかなぁ。)
Sub ie_Select_Multiple_001()
    'For Each objTAG In objIE.Document.Forms(0).All.Tags("OPTION")でループさせ
    ' .Value="VBA" と .InnerTEXT="愚痴系(GUCHI)" の2つを探し.Select=Trueにする

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

    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test093-5.asp"
    
    'ページが表示される 完了を待つ
    While objIE.ReadyState <> 4  'READYSTATE_COMPLETE = 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend
    
    '※FORM(0).Allの下 オブジェクトを1つ1つ探す
    Dim objOPTION As Object  'OPTIONタグのオブジェクト格納用

    'Form(0).All.Tags("OPTION")でOPTIONオブジェクトのみ取り出す
    For Each objOPTION In objIE.Document.Forms(0).All.Tags("OPTION")
        '.Value(値)がVBAのオブジェクトを探す
        If objOPTION.Value = "VBA" Then  '.Valueを見てチェック
            objOPTION.Selected = True    '.Selected = Trueで選択状態にする
        End If
        '.InnerTEXT(表示テキスト)が 愚痴系(GUCHI) のオブジェクトを探す
        If objOPTION.InnerTEXT = "愚痴系(GUCHI)" Then  '.InnerTEXTを見てチェック
            objOPTION.Selected = True    '.Selected = Trueで選択状態にする
        End If
    Next

    'おまけで、 OPTIONの親、SELECTの値をデバックエリアに出力
    Debug.Print "KUBUNの値は[" & objIE.Document.Forms(0).Item("KUBUN").Value & "]です"

End Sub
↑ポイントは、ページ表示後に、
For Each objOPTION In objIE.Document.Forms(0).All.Tags("OPTION")でOPTIONのタグをobjOPTIONに1つ1つ取り出し、
If objOPTION.Value = "VBA" と If objOPTION.InnerTEXT = "愚痴系(GUCHI)" で判断しただけなんですが・・

↑実行結果を見ると、複数の選択はできているのですが、おまけで追加した、親のSELECTタグ 名前KUBUNの値をデバック表示(次の章で使うため)が、VBAと1つだけしか表示されていない・・・検索を手動で押すと無事に2つ検索されるし複数選択はOKなんだけどなぁ、何だろうなぁ、、、何か違うアプローチがあるのかなぁ・・・

できれば、複数選択も値の代入だけですましたかったんだけど・・・これもいつもの調査中で逃げてるって感じですね。(時間を作って、壁に立ち向かわないとダメですね)


[#Form_Input_Checkbox][ページ内のTOPへ戻る]

INPUT TYPE="CHECKBOX" を 操作する

フォームのチェックボックス INPUT TYPE="CHECKBOX"を操作します。
おおまかなタイプは2つあって、NAME="オブジェクト名"が個々に違う場合と、NAME="オブジェクト名"が同じでValue="識別する値"で区別しているパターンです。
読者の声:何言ってるのかわからない、意味不明、日本語でお願いします。。。
日本語かぁ・・・自信がないので下記にHTML言語を書きます(HTML言語で話します)

INPUT TYPE="CHECKBOX"の2パターン
NAME="xxxx"が個々に違う NAME="xxxx"が同じでValue="zzzz"が違う
Formの場所[test093-2.asp]↓入力イメージ
CHECKBOX NAME=を個別に作成 Where句を作成するTEST
表示したい・区分をチェックしてから検索ボタンを押してください
ASP
VBA
コンビニ系
愚痴系

↑のHTMLソース↓
<FORM ACTION="test093-2.asp" METHOD="POST">
<font color="blue">CHECKBOX NAME=を個別に作成 Where句を作成するTEST</font><br>
表示したい・区分をチェックしてから検索ボタンを押してください<br>
<INPUT TYPE="CHECKBOX" NAME="ASP">ASP<br>
<INPUT TYPE="CHECKBOX" NAME="VBA">VBA<br>
<INPUT TYPE="CHECKBOX" NAME="24H">コンビニ系<br>
<INPUT TYPE="CHECKBOX" NAME="GUCHI">愚痴系<br>
<INPUT TYPE="submit" VALUE="検索する">
</FORM>
NAME="XXXX"が違うパターンです
Formの場所[test093-4.asp]
チェックボックス↓入力フォーム
FORM CHECKBOX VALUE=を個別に作成 Where句を作成するTEST
表示したい・区分をチェックしてから検索ボタンを押してください
ASP
VBA
コンビニ系
愚痴系

↑のHTMLソース↓
<FORM ACTION="test093-4.asp" METHOD="POST">
<font color="blue">FORM CHECKBOX VALUE=を個別に作成 Where句を作成するTEST</font><br>
表示したい・区分をチェックしてから検索ボタンを押してください<br>
<INPUT TYPE="CHECKBOX" NAME="KUBUN" VALUE="ASP">ASP<br>
<INPUT TYPE="CHECKBOX" NAME="KUBUN" VALUE="VBA">VBA<br>
<INPUT TYPE="CHECKBOX" NAME="KUBUN" VALUE="24H">コンビニ系<br>
<INPUT TYPE="CHECKBOX" NAME="KUBUN" VALUE="GUCHI">愚痴系<br>
<INPUT TYPE="submit" VALUE="検索する">
</FORM>
NAME="XXXX"が同じでVALUE="ZZZZ"が違うパターンです
見た目は同じでも、中身が違う、そんなパターンです。※中身が違うので操作方法も少し違うんですよ・・・世の中には(Web上には)イロイロな処理方法や表現(Htmlの記述)があって大変です。


[#Form_Input_Checkbox][ページ内のTOPへ戻る]

Name="XXXX"が個別で違う場合

Name="XXXX"が個別に違う場合は、素直に名前で目的のオブジェクトへアクセスできるので、
オブジェクト.Checked = Trueでチェックボックスにチェックを入れてみます

Name="VBA"とName="24H"にチェックを入れてみます。
Sub ie_Input_Checkbox_Checked()    '名前がVBA と 24H の チェックボックスをONにする

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

    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test093-2.asp"

    'ページが表示される 完了を待つ
    While objIE.ReadyState <> 4  'READYSTATE_COMPLETE = 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend
    
    '素直に Document.Forms(0).Item("名前")でアクセスする
    objIE.Document.Forms(0).Item("VBA").Checked = True   '.CheckedプロパティにTrueをセット
    objIE.Document.Forms(0).Item("24H").Checked = True   '.CheckedプロパティにTrueをセット

    'データをセットしたら 送信する(ここでは、コメント(非実行)にしたけど)
    'objIE.Document.Forms(0).Submit   '.Submitメソッドで送信処理

End Sub
素直に Document.Forms(0).Item("名前")でオブジェクトが特定できるので、あとは.Checked = Trueで選択状態にしました。


[#Input_Checkbox_Value][ページ内のTOPへ戻る]

Name="XXXX"が同じで、Value=(値)が違う場合

次に、CHECKBOXのName="XXXX"が同じでValue="ZZZZ"が違う入力フォーム
<INPUT TYPE="CHECKBOX" NAME="KUBUN" VALUE="ASP">ASP<br>
<INPUT TYPE="CHECKBOX" NAME="KUBUN" VALUE="VBA">VBA<br>
<INPUT TYPE="CHECKBOX" NAME="KUBUN" VALUE="24H">コンビニ系<br>
<INPUT TYPE="CHECKBOX" NAME="KUBUN" VALUE="GUCHI">愚痴系<br>
の場合、フォームのオブジェクトを1つ1つみて、.NameがKUBUN.Valueが目的の値で判断してから、.CheckedをTrueにしてみます。

KUBUN が ASP,VBA,24Hの3つにチェックを入れる
Sub ie_Input_Checkbox_Value()
    '名前(.Name)がKUBUN で 値(.Value)がASP,VBA,24H の チェックボックスをONにする

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

    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test093-4.asp"

    'ページが表示される 完了を待つ
    While objIE.ReadyState <> 4  'READYSTATE_COMPLETE = 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend
    
    'Form内を1つ1つ調べて、該当するオブジェクトを操作する
    Dim objTAG  As Object  '取り出したタグを入れる変数
    
    For Each objTAG In objIE.Document.Forms(0) 'フォームの下を1つ1つ取り出す
        If objTAG.Name = "KUBUN" Then  '名前が KUBUN のオブジェクトか?
            If objTAG.Value = "ASP" Then objTAG.Checked = True '値がASPならチェックを入れる
            If objTAG.Value = "VBA" Then objTAG.Checked = True '値がVBAならチェックを入れる
            If objTAG.Value = "24H" Then objTAG.Click  '値が24Hならクリックする(おまけのテスト)
        End If
    Next

    'データをセットしたら 送信する(ここでは、コメント(非実行)にしたけど)
    'objIE.Document.Forms(0).Submit   '.Submitメソッドで送信処理

End Sub
ポイントは、ループで回して、名前(.Name)と値(.Value)をチェックして、目的のチェックボックスなら、.CheckedをTrueにしました。※24Hの時、おまけで.Clickメソッドを発行して遊んでみました。(クリック動作でも チェックを付けたりハズしたりできます)


[#Document_getElementsByName][ページ内のTOPへ戻る]

Document.getElementsByName(.Nameがわかるなら名前で素直に探したら?)

上のチェックボックスの判断で、名前(.Name)と値(.Value)を判断したかったので、
For Each objTAG In objIE.Document.Forms(0) で ループを作り、
If objTAG.Name = "KUBUN" Then で 名前が KUBUN かみて
さらに If objTAG.Value = "ASP" Then で値を判断しました。
動いているので、これはこれで正解なのですが(動いているソースをイジルなってプログラマーの格言?もあるんだけど)、指定した名前を取り出す方法があったりします。

文章から指定したタグのオブジェクトを抜く時に、document.all.tags("タグの名前")で指定したタグを抜き出せました→[.tags("タグの名称")]
これに近い命令があって、
document.getElementsByName("名前(Nameの値)") なんて感じで意外と簡単に取り出せたり。

てっことで、実際に.getElementsByNameを使ってみます
Sub ie_document_getElementsByName()
    '名前(.Name)をgetElementsByNameで探し 値(.Value)がASP,24H,GUCHI の チェックボックスをONにする

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

    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate "http://www.ken3.org/cgi-bin/test/test093-4.asp"

    'ページが表示される 完了を待つ
    While objIE.ReadyState <> 4  'READYSTATE_COMPLETE = 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend
    
    '.getElementsByNameで指定した名前のオブジェクトを取り出し、値を見て処理を行う
    Dim objTAG  As Object  '取り出したタグを入れる変数
    
    For Each objTAG In objIE.Document.getElementsByName("KUBUN") '名前がKUBUNのデータを取り出す
        If objTAG.Value = "ASP" Then objTAG.Checked = True   '値がASPならチェックを入れる
        If objTAG.Value = "GUCHI" Then objTAG.Checked = True '値がGUCHIならチェックを入れる
        If objTAG.Value = "24H" Then objTAG.Click  '値が24Hならクリックする(おまけのテスト)
    Next

    'データをセットしたら 送信する(ここでは、コメント(非実行)にしたけど)
    'objIE.Document.Forms(0).Submit   '.Submitメソッドで送信処理

End Sub
オブジェクトを取り出すときに、
For Each objTAG In objIE.Document.getElementsByName("KUBUN")
で、名前指定で取り出す(ここではKUBUNのデータ)ことができるので名前が同じオブジェクトを処理する場合にぜひ使ってみてください。


[#Input_button_Click][ページ内のTOPへ戻る]

HTML入力フォーム外側のボタンを押す(<Form>が無い場合)

次は、<INPUT type="button" 〜 onclick="Javaで作った関数('パラメータ')"> で作られたボタンを.Clickで押し JavaScriptを起動してみたいとおもいます。Formに属さない無いボタンを押す、そんな処理を行ってみます。

テスト場所(操作場所)は [http://ken3-info.blog.ocn.ne.jp/test/2007/09/post_d21d.html] です。下記のように<FORM>〜</FORM> が 無く、ボタンのonclickイベントでJavaScriptを起動しています。 ↓htmlソース


<SCRIPT language="javaScript"> 
  function IE_JUMP(s){
    location.href=location.href='http://'+s;
  }
</SCRIPT>
<p>フォームの外のボタンを押すテスト</p>
<hr>
<INPUT type="button" name="btop" value="三流君Topへ" onclick="IE_JUMP('www.ken3.org')"><br>
<INPUT type="button" id="idvba" value="VBA解説" onclick="IE_JUMP('www.ken3.org/vba/')"><br>
<INPUT type="button" value="ASP解説" onclick="IE_JUMP('www.ken3.org/asp/')"><br>
<INPUT type="button" value="IE操作解説" onclick="IE_JUMP('www.ken3.org/cgi-bin/group/vba_ie.asp')"><br>
<hr>

↑こんな感じでFORM無しのINPUT type="button"です。

いままでの例だと 名前が付いていれば objIE.Document.Forms("フォームの名前").Item("ボタンの名前").Click や 名前が無くても番号で objIE.Document.Forms(0).Item(6).Click などFormオブジェクトの下を操作してました。
が、今回の文章(Document)には、<Form>がありません・・・

FORMに属していないので一番上のDocument.all("名前")で指定

Formの下にINPUTのボタンが無いからってあわてないでよ。(読者の声:別にあわててないよ、疑問を聞いてるだけ)
<INPUT type="button" name="btop" value="三流君Topへ" onclick="IE_JUMP('www.ken3.org')"><br> のボタンを押したい場合、名前がname="btop"と付いているので、
Document.all("btop").Click
↑こんな感じで、.all("名前")で目的のオブジェクトを指定することができます。
※余談:いつものFormアリ 属したボタン objIE.Document.Forms("フォームの名前").Item("ボタンの名前").Click 操作 を objIE.Document.All("ボタンの名前").Click と書くことも名前が重複していなければできたりします。全体allから名前でオブジェクトを特定することもできます。

話を戻して、Document.all("btop").Clickでクリックできるか、テストしてみます。
Sub ie_Input_Button_Click()  'Formが無い(Formに属さない)ボタンを.Click

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

    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate "http://ken3-info.blog.ocn.ne.jp/test/2007/09/post_d21d.html"

    'ページが表示される 完了を待つ
    While objIE.ReadyState <> 4  'READYSTATE_COMPLETE = 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend

    '↓デバック用で少し待つ(※これは通常いらないので)
    Application.Wait Time:=Now + TimeValue("00:00:03")  '画面遷移がはやいので3秒間止める

    'htmlドキュメント allの名前がbtopのオブジェクト を クリック(.Click)する
    objIE.Document.all("btop").Click   '単純に名前で指定した対象に.Click
 

End Sub
↑こんな感じで無事 FORM に属さないボタンが押せたと思います。※初めからDocument.all("名前").Clickを教えとけよ・・・と読者の声が聞こえてきたような


[#Input_button_NoNAME][ページ内のTOPへ戻る]

Document.all.tags("INPUT")で抜き出し判断する

ボタンにName=で名前が付いてればいいけど、
<INPUT type="button" value="ASP解説" onclick="IE_JUMP('www.ken3.org/asp/')"><br>
<INPUT type="button" value="IE操作解説" onclick="IE_JUMP('www.ken3.org/cgi-bin/group/vba_ie.asp')"><br>
上記INPUTのボタンは、ボタンにName=名前が付いてないよ。お手上げでしょ?
名前がなければ素直にあきらめるのかい?名前が付いていなくても あのお店・店員の中で地下の食品売り場の背が高くて痩せ型の男性いつも元気で笑顔がステキな女性など、特定方法はいくらでもあるダロ(読者の声:また違う方向に話が進んでるよ、まじめに解説しろ)

文章から表・テーブルデータを抜くときに、document.all.tags("タグの名前")で指定したタグを抜き出してたよね→[.tags("タグの名称")]
これ(.tags)を利用して、.tags("Input")で、INPUTを抜き、<INPUT type="button" value="IE操作解説" onclick="IE_JUMP('www.ken3.org/cgi-bin/group/vba_ie.asp')"><br>
取り出したINPUTの.Valueがvalue="IE操作解説"か判断してみます

ボタンの名称が(.Valueが) IE操作解説のボタンを押すサンプル
For Each objINPUT In objIE.Document.all.tags("INPUT")でINPUTを抜き出して、ボタンの名称をobjINPUT.Value = "IE操作解説"で判断して、見つかったらそのオブジェクトをobjINPUT.Clickしました。
Sub ie_Tags_Input_Button()  'ボタンにName=が無しなので、.tagsでINPUTを抜き .Valueで判断

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

    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate "http://ken3-info.blog.ocn.ne.jp/test/2007/09/post_d21d.html"

    'ページが表示される 完了を待つ
    While objIE.ReadyState <> 4  'READYSTATE_COMPLETE = 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend
    
    '↓デバック用で少し待つ(※これは通常いらないです)
    Application.Wait Time:=Now + TimeValue("00:00:03")  '画面遷移がはやいので3秒間止める
    
    'htmlドキュメント allのから .tagsでINPUTタグを抜き
    '.Value値(ボタンの名称) が IE操作解説 の オブジェクト を クリック(.Click)する
    Dim objINPUT As Object   'Inputタグ格納用

    For Each objINPUT In objIE.Document.all.tags("INPUT")  'Inputのタグを.allから抜く
        If objINPUT.Value = "IE操作解説" Then '.Value値(ボタンの名称) が IE操作解説 か?
            objINPUT.Click  '見つけたINPUTオブジェクト(ボタン)を.Clickクリックする
            Exit For  '用が済んだので(見つかったので)ループを抜ける
        End If
    Next
    
    '↑上でボタンが見つからなかった時のエラー処理が入っていない手抜きだけど、ご勘弁を
    
End Sub
まぁ、日本語のボタン名称(.Value)を探した方が意外と処理がわかりやすかったり?(ソースを見て何やっているのかわかるかなぁ)

余談:間違っても客先や派遣先で名前がわからないからって、胸の大きいな女性に説明しましたとか、とんでもない発言を客先担当者(納品先の課長)に言っちゃイケマセンよ(あの頃は若かったなぁ それで次の仕事が来なかったのか って、誰の失敗談だよ) じゃなくて、少々パターン違いの 逆にName=砂糖さん と名前が同じ場合もあったり、過去のメルマガ → [No.176 VBAからIE操作 NAMEが同じフォームの項目へデータをセットする] も参考にしてください。※逆の立場で自分が派遣で来ているデブ プログラマーとか社員さん達に言われたらと思うとかなり反省(オイオイ)

Form 終わりの挨拶

まだまだ、書かないといけないForm操作 プロパティやメソッドなどの組み合わせがあるのですが、このあたりで逃げるように失礼します(オイオイ)。更新が遅いけど温かく見守ってください 更新中 まだまだ書きかけ

いろいろな表現があって、かえって迷ってしまうかもしれませんが、数をこなすと見えてくるので、私のサンプルだけじゃなく、いろいろなサンプルを探して見てください。[番外編 GoogleでoIE,objIE,WebBrowserをKeyWordにして検索]にお勧めのキーワード検索方法を載せてます

ここまでのサンプル Formのデータ登録サンプル:[IE起動とデータセットのサンプル 20080527_IE_Form.zip]←Excel VBAです
保存後、解凍して、テストしてみてください。


[#Document_Links][ページ内のTOPへ戻る]

リンク情報を取り出す(Document.Linksオブジェクト)

はじめに(あいさつ?):インターネットエクスプローラーの操作と一口に言ってもイロイロな操作があると思います。
そのうちの一つが、あるホームページ(URL)を表示して、リンク先の情報を取り出したい、、、そんな要望があると思います。※リンクの先を探りたいなど、この一連の流れをVBA上から行いたい・・・と日本語で書くのは簡単なんだけど、この流れをプログラムで記述してみたいと思います

ここからのリンク先の取り出しサンプル[IE起動とリンクの取り出し サンプル 20080605_IE_Link.zip]←Excel VBAです
ダウンロードして遊んでみてください。

読者の声:.Document.Links ? アンタまたわけわかんないオブジェクトをイキナリくちばしるね?自分だけわかってて、相手のこと考えたことあるの??説明の順番は、考えたことあるの?もっと違う方向性・説明の順番があると思うけどなぁ。。。読者Bそうだそうだ、基本もいいけどもっと実用的なことやれよ

まぁまぁ、そんなこと言わないで、今回の1 .Lengthの話 2. For Eachの話、3. InnerHTMLやInnerTEXT.OuterHTMLや.OuterTEXTの違いだけでも、この3点だけでも聞いてくださいね。

と、いつもの小芝居は置いといて、表示したHP(ドキュメント)のリンク先が.Linksオブジェクトに保存されています。この.Document.Linksを操作して、IEドキュメント操作の感覚をつかんでもらう、それが狙いなのでよろしくお願いします。

今回操作したいリンクはAタグなので、MSDNで調べるならココ、
アクセス可能な HTML 要素 [http://www.microsoft.com/japan/msdn/workshop/author/access/accessibility.aspx#acc_elements] をクリック 後に、
Aタグ を探っていくと、
A Element | a Object [http://msdn2.microsoft.com/en-us/library/ms535173.aspx] が見つかります。
ここにイロイロと使えそうなプロパティやメソッドがありそうです。ワクワクしませんか?

読者の声:あっそ、でも英語でしょ?日本語の解説無いの?

冷めてるなぁ、、、でも、いっぱいあって何を使えばいいのか・・・いきなりこんなの見せられたら挫折しますね。
なので、私が使っている(知っている)プロパティを使って、テストプログラムを書いてみました。

読者の声:はじめから知ってるコマンドだけ解説します・残りは自分でMSDNやネットから探してくださいと言えよ?全て丁寧に解説してくれるものだと期待するでしょ

スミマセン、、、と、落ち込みつつ、リンクを取り出すサンプルを作成します


[#Link_TEST][ページ内のTOPへ戻る]

調査したいURLを表示後 リンク先の情報をセルにテストで書いてみた

初めは、どんなことをやるか、仕様(仕様書)を書かないといけないんだっけ、
では、いつもの通用しない箇条書き仕様を軽く書きます。
1.調査したいURLをInputBoxで受け取ります(かなり手抜き・・・)
2.IEを起動させ、目的のページを表示させます。
3.目的のページからリンク先を取り出し、セルに書き出します。
こんな感じかな。※オイオイ、おおまか過ぎでしょ・・・
次章からこの3つに対応したコードを載せます。

1.標準関数のInputBoxを使ってURLを受け取る

もしかして、解説不要?だと思いつつ、標準関数のInputBoxを使ってURLを受け取る(入力してもらう)には、
strURL = InputBox("調査するURLは?", "URL入力", "http://www.ken3.org/backno/backno_vba_mokuji.html")
こんな感じかな?
標準関数なので、よく見かけると思います。

2.IEを起動させ、目的のページを表示させます

IEの起動とページ表示です。最近流行の 高級料亭でも行っている料理の使い回し じゃないけど、解説の使い回しで、
ア.初めは[IEの起動] CreateObject("InternetExplorer.application")でブラウザを起動させます
イ.次に[.Navigateで開く] 目的のページを開くために.Navigateメソッドでページを移動させます。
ウ.最後に[.Busyと.ReadyState]で表示の完了(ページの読み込み)を待ちます。

上記を参考に(って言ってもほぼそのまま、URLが変数に変わっただけですが)
Sub ie_Link_TEST()

'1.調査したいURLをInputBoxで受け取ります(かなり手抜き・・・)
    Dim strURL  As String   '入力値を受け取る変数

    'INPUTBOXでURLをもらう
    strURL = InputBox("調査するURLは?", "URL入力", "http://www.ken3.org/backno/backno_vba_mokuji.html")
    If strURL = "" Then
        MsgBox "調査したいURLを指定してください"
        Exit Sub  '途中で抜ける
    End If

'2.IEを起動させ、目的のページを表示させます。

    Dim objIE      As Object  'IEオブジェクト参照用
    
    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate strURL
    
    '表示完了を待つ
    While objIE.ReadyState <> 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend

'3.目的のページからリンク先を取り出し、セルに書き出します。
    '表示されたら、ここから抜き出す処理を書く

End Sub
と、作成しました。

3.目的のページからリンク先を取り出し、セルに書き出します。

調査対象のページが無事に表示されたら、新しいブックを追加後
Document.Links.Lengthでリンクの数がわかるので、
For i = 0 To objIE.Document.Links.Length - 1とループを作り
objIE.Document.Links(i).Href
objIE.Document.Links(i).OuterText .OuterHTML
objIE.Document.Links(i).InnerText .InnerHTML
objIE.Document.Links(i).Target
をセルに書き込みます。

解説の前に 先出しで下記、テストで作ったリンク書き出しのプログラムです。
Sub ie_Link_TEST()

'1.調査したいURLをInputBoxで受け取ります(かなり手抜き・・・)
    Dim strURL  As String   '入力値を受け取る変数
    
    'INPUTBOXでURLをもらう
    strURL = InputBox("調査するURLは?", "URL入力", "http://www.ken3.org/backno/backno_vba_mokuji.html")
    If strURL = "" Then
        MsgBox "調査したいURLを指定してください"
        Exit Sub  '途中で抜ける
    End If

'2.IEを起動させ、目的のページを表示させます。

    Dim objIE      As Object  'IEオブジェクト参照用
    
    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate strURL
    
    '表示完了を待つ
    While objIE.ReadyState <> 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend
    
'3.目的のページからリンク先を取り出し、セルに書き出します。
    
    Dim i     As Integer '添え字 i番目などで使用
    Dim yLINE As Integer '行カウンタ、Y行目
   
    'html ドキュメント リンク オブジェクトからデータをセルへ転記(代入)する。
    Workbooks.Add  '新規ブックを追加 データ転送用に新規のブックを追加する
    Range("A1") = "調査したURLは " & strURL & " です"  'A1にURLを記述(セット)
    Range("D1") = "リンクの数は " & objIE.Document.Links.Length & "です"  'D1にリンクの数をセット

    Range("A2") = ".Href(リンク先)"   'A2〜F2 2行目に見出しをセットする
    Range("B2") = ".OuterText"
    Range("C2") = ".OuterHTML"
    Range("D2") = ".InnerText"
    Range("E2") = ".InnerHTML"
    Range("F2") = ".Target"
    Columns("A:F").ColumnWidth = 22 '列幅を22に変更

    yLINE = 3  'セット開始の行を代入する
    For i = 0 To objIE.Document.Links.Length - 1
        'データをセルへセットする  'を付けて文字列にする(セルにセットしたいので)
        Cells(yLINE, "A") = "'" & objIE.Document.Links(i).Href      'リンク先
        Cells(yLINE, "B") = "'" & objIE.Document.Links(i).OuterText '自分を含む テキスト(Innerと変わりない?)
        Cells(yLINE, "C") = "'" & objIE.Document.Links(i).OuterHTML '自分を含む HTML
        Cells(yLINE, "D") = "'" & objIE.Document.Links(i).InnerText '内側のテキスト
        Cells(yLINE, "E") = "'" & objIE.Document.Links(i).InnerHTML '内側のHTML
        Cells(yLINE, "F") = "'" & objIE.Document.Links(i).Target    '_Blank や 表示先フレームの名前など
        
        yLINE = yLINE + 1 'セット位置(行)を+1する
    Next i
    
    '抜き出し作業が終わったので、通常.QuitでIEを終了させる が 今回は残す
    'objIE.Quit
    Set objIE = Nothing
   
    MsgBox "処理終了、ブラウザの表示内容 と シートを確認してください"
   
End Sub

操作手順と実行結果:


[#Links_Length][ページ内のTOPへ戻る]

Links.Lengthでデータ数 添え字 Links(i) でアクセス

ループで回す時、最大値・要素の数を知りたいので、そんな時は、Document.Links.Lengthで知ることができます。

バカの一つ覚えのExcelとの比較を一つ、ブック内のシート名を表示するテストプログラムを書きます。

Sub TEST_SHEET_NAME()
    'シートの名前をテストで表示する
    Dim i As Integer   'カウンター、添え字
    
    For i = 1 To ActiveWorkbook.Sheets.Count
        MsgBox i & " シートの名前 " & ActiveWorkbook.Sheets(i).Name
    Next i

End Sub

ActiveWorkbook.Sheets.Count
で、ブックのシート数が取れるので、ループで1からシート数分まわし、
ActiveWorkbook.Sheets(i).Name
で、i番目のシートの名前(.Name)を表示してます。

読者の声:だから何?、ドキュメント内のリンク数は、objIE.Document.Links.Countと言いたいの?感覚的にExcel VBAに慣れた人は.Countを使うと決め付けたいの??でも、リンクの数は.Lengthなんでしょ?

あまり怒らないでくださいよ、リンクの数(要素の数)は.Countじゃなくて.Lengthです、配列も0から始まるので、
For i = 0 To objIE.Document.Links.Length - 1
Cells(yLINE, "A") = "'" & objIE.Document.Links(i).Href


Next i
と、i=0から初めて、.Length - 1までのループとしてます
他のIEオブジェクト操作でも 配列の要素数は、パターン的に.Lengthが多いので覚えておいてください・・それが言いたかっただけなんですが、Excelを例にしてた蛇足の解説でしたね(少々反省)


[#Links_Href][ページ内のTOPへ戻る]

.Href .OuterText .OuterHTML .InnerText .InnerHTML .Target

ドキュメント内 リンクのオブジェクト に
objIE.Document.Links(i番目)
で、アクセスできた(できる)ので、次はプロパティ・値を取りたいと思います。
objIE.Document.Links(i).Hrefでリンク先などを取り出すことができます

私が使ったことがあるプロパティをセルに書き出してみました。↓単純に縦に羅列しただけですが
Cells(yLINE, "A") = "'" & objIE.Document.Links(i).Href
Cells(yLINE, "B") = "'" & objIE.Document.Links(i).OuterText
Cells(yLINE, "C") = "'" & objIE.Document.Links(i).OuterHTML
Cells(yLINE, "D") = "'" & objIE.Document.Links(i).InnerText
Cells(yLINE, "E") = "'" & objIE.Document.Links(i).InnerHTML
Cells(yLINE, "F") = "'" & objIE.Document.Links(i).Target
実行結果を見ていただけると、各プロパティの違いがわかると思います

読者の声:わかるわけねぇだろコラ。また、自分だけ気持ち良くなってんじゃねぇよ。。。InnerとOuterHTMLとTEXT どこが違うんだよ。

スミマセン、手抜きの解説で、少々いつものようにくどく書くと下記のリンクのAタグがあります
<A href="http://www.ken3.org/" target=_blank><Big><STRONG>三流</STRONG>プログラマー</Big></A>
↑のデータを例にすると、
.Hrefは リンク先URL http://www.ken3.org が値として取り出せます。
.Target_blank (見たまんまか)
.OuterText.InnerTextは タグの付いてないテキスト文字列 三流プログラマー を値として取り出せます
.OuterHTMLは、外側のタグを含むHTML <A href="http://www.ken3.org/" target=_blank><Big><STRONG>三流</STRONG>プログラマー</Big></A> です。あっ、そのまま全てか(笑)
.InnerHTMLで タグの内側 <Big><STRONG>三流</STRONG>プログラマー</Big> 外側を1つはずした感じかな の データを受け取れます。

.OuterText .OuterHTML .InnerText .InnerHTMLは、他のタグでも使うことが多いので、なんとなくでもいいので頭のスミにでも覚えておいてください。


[#Links_For_Each][ページ内のTOPへ戻る]

Linksの参照を Links(i)から For Each に 変更

よし、リンクオブジェクトの説明終了、、、朝までにもう一軒飲み屋じゃなかった、オブジェクトをハシゴするぞと行きたい所ですが、あと一杯、少しだけお時間をとらせてください。

読者の声:だから、余計な会話はいいから、はやくシロ。(※←この読者の心の声もかなりの蛇足なんですが(笑)説明に必要ないでしょと思いつつ)

書き方に好みの問題もあるのですが、
objIE.Document.Links(i)
と、配列(i番目)でまわす方法のほかに、
For Each 変数 In オブジェクト
なんて書き方もあります

読者の声:何言ってんだか、よくわからん。いつもの例だせよ

えっ、いいんですか?いつもの蛇足の例を出して。では、お言葉に甘えてExcelのシートを例にして、

Sub TEST_SHEET_NAME_FOR_EACH()
    Dim objSHEET As Worksheet  'シートのオブジェクト受け取り用
    For Each objSHEET In ActiveWorkbook.Sheets
        MsgBox " シートの名前 " & objSHEET.Name
    Next
End Sub

みたいに、Dim objSHEET As Worksheetと受け取り用の変数を1つ定義して、 For Each objSHEET In ActiveWorkbook.Sheets
と記述すると、ActiveWorkbook.Sheets分だけ1つ1つ次のオブジェクトを取り出しながらループさせ、objSHEET.Nameみたいに(i)とか添え字や.Countなどの要素数を使わないで処理することができます。
同様に For Each 変数 In objIE.Document.Links とLinksもFor Each IN を使うことができます。
読者の声:デジャブか?この解説前にも見たことがある。
Ken3:ギク、、[Document.AllをFor Eachで回す]とそっくりですね。。。料理じゃなかった、解説の使い回しですね(二度見た人はお許しを)
※逆に言うと For Each 変数 IN オブジェクト はイロイロと使えるってことです。もったいないから・・と言ってみた。(オイオイいい加減にしろよまったく)

話を戻して、下記 For Each INを使用したサンプルに書き換えました。
Sub ie_Link_For_Each_test()  'For Each 変数 In objIE.Document.Links のテスト

'1.調査したいURLをInputBoxで受け取ります(かなり手抜き・・・)
    Dim strURL  As String   '入力値を受け取る変数
    
    'INPUTBOXでURLをもらう
    strURL = InputBox("調査するURLは?", "URL入力", "http://www.ken3.org/backno/backno_vba_mokuji.html")
    If strURL = "" Then
        MsgBox "調査したいURLを指定してください"
        Exit Sub  '途中で抜ける
    End If

'2.IEを起動させ、目的のページを表示させます。

    Dim objIE      As Object  'IEオブジェクト参照用
    
    'IEを起動する
    Set objIE = CreateObject("InternetExplorer.application") 'IEのオブジェクトを作る
    objIE.Visible = True '見えるようにする(お約束)

    '.Navigate で 指定したURLを開く
    objIE.Navigate strURL
    
    '表示完了を待つ
    While objIE.ReadyState <> 4
        While objIE.Busy = True
            DoEvents  '特に何もしないで.Busyの状態が変わるまで待つ
        Wend
    Wend
    
'3.目的のページからリンク先を取り出し、セルに書き出します。
    
    Dim yLINE   As Integer '行カウンタ、Y行目
    Dim objLINK As Object  'リンクのオブジェクト受け取り用
       
    'html ドキュメント リンク オブジェクトからデータをセルへ転記(代入)する。
    Workbooks.Add  '新規ブックを追加 データ転送用に新規のブックを追加する
    Range("A1") = "調査したURLは " & strURL & " です"  'A1にURLを記述(セット)
    Range("D1") = "リンクの数は " & objIE.Document.Links.Length & "です"  'D1にリンクの数をセット

    Range("A2") = ".Href(リンク先)"   'A2〜F2 2行目に見出しをセットする
    Range("B2") = ".OuterText"
    Range("C2") = ".OuterHTML"
    Range("D2") = ".InnerText"
    Range("E2") = ".InnerHTML"
    Range("F2") = ".Target"
    Columns("A:F").ColumnWidth = 22 '列幅を22に変更

    yLINE = 3  'セット開始の行を代入する
    For Each objLINK In objIE.Document.Links  'リンクを1つ1つ取り出しobjLINKへ
        'データをセルへセットする  'を付けて文字列にする(セルにセットしたいので)
        Cells(yLINE, "A") = "'" & objLINK.Href      'リンク先
        Cells(yLINE, "B") = "'" & objLINK.OuterText '自分を含む テキスト(Innerと変わりない?)
        Cells(yLINE, "C") = "'" & objLINK.OuterHTML '自分を含む HTML
        Cells(yLINE, "D") = "'" & objLINK.InnerText '内側のテキスト
        Cells(yLINE, "E") = "'" & objLINK.InnerHTML '内側のHTML
        Cells(yLINE, "F") = "'" & objLINK.Target    '_Blank や 表示先フレームの名前など
        
        yLINE = yLINE + 1 'セット位置(行)を+1する
    Next
    
    'IEの終了を聞く
    If MsgBox("IEを閉じますか?", vbYesNo, "終了確認") = vbYes Then
        objIE.Quit   '.Quitで閉じる
    End If
    Set objIE = Nothing
   
End Sub
頭から全てのデータをループさせる場合、For Each objLINK In objIE.Document.Linksとして、使う時は objLINK.プロパティ このほうがスッキリとした記述かなぁ。
※三流君的には、Links(i)とかLinks(n)、の書き方が長くても好きだけど。


[#objIE_Quit][ページ内のTOPへ戻る]

処理が終わったら IEを .Quit で閉じてみた

今回のリンク抜き出し処理にはあまり関係ないのですが、
objIE.Quit
.Quitで、Set objIE = CreateObject("InternetExplorer.application") で作成した IEを終了、閉じることができます。
開発中やデバッグ中はIEをそのまま残しておいたほうが何かと便利なのですが、処理が終わったら.Quitでサヨナラをすることもできます。

逃げるように 終わりの挨拶

まだまだ、書かないといけないIE操作 プロパティやメソッドなどの組み合わせがあるのですが、このあたりで逃げるように失礼します(オイオイ)。更新が遅いけど温かく見守ってください 更新中 まだまだ書きかけ

いろいろな表現があって、かえって迷ってしまうかもしれませんが、数をこなすと見えてくるので、私のサンプルだけじゃなく、いろいろなサンプルを探して見てください。[番外編 GoogleでoIE,objIE,WebBrowserをKeyWordにして検索]にお勧めのキーワード検索方法を載せてます


[#BackNoLink][ページ内のTOPへ戻る]

過去のメールマガジンのリンクが長かったので、下記に移動しました。
[IE操作 メルマガ 一覧]
よろしくお願いします。


改版履歴 更新情報:過去のIE操作の解説はこちら↓(IE6+XP,IE7+XPの古い記事もアリ)
2009-12-01:[過去の解説 vba_ie_20091201.asp]
2009-06-01:[過去の解説 vba_ie_20090601.asp]
2009-02-01:[過去の解説 vba_ie_20090201.asp]
2008-05-01:[過去の解説 vba_ie_20080501.asp]
2007-08-31:[過去の解説 vba_ie_20070831.asp]
2007-05-20:[過去の解説 vba_ie20070520.asp]

2012-03-19:[過去の解説 vba_ie_20120319.html]
もあわせてみてください。
(↑もしかして書き直さない過去の解説の方がよかったかも?(笑))



[ページ内のTOPへ戻る]

ページフッター

Googleで情報を探す

せっかくホームページに来ていただいたのに、検索の紹介 ぉぃぉぃ
サイト指定や期間の指定を組み合わせて実行してみてください。

Google
探す言葉:
ググる。↑VBAなど 気になる単語や,オブジェクト(MailItem),プロパティ(.Body)やメソッド(.Move)などを入れて検索してみてください。

サイト指定:人気QAサイト や 一次情報MS本家を指定する
条件無し WWW 全体から検索も良いけど↓で絞り込むのもおススメです
一次情報・二次情報まとめから探る
一次情報は基本のMSDN含む microsoft.comから
まとめ一次・二次情報 Qiita 知識を記録・共有 qiita.comで個人まとめを参考に
手前味噌の三次情報 三流君メモBlog ken3memo.hatenablogから検索
QAサイトの質問から探る
QAはやっぱり人の多いYahoo知恵袋 chiebukuro.yahoo.co.jpから探る
こちらもどうぞ おしえてgoo! oshiete.goo.ne.jp
15分探して見つからなかったら?回答率90%以上 teratail.com
私も利用中 最近過疎ってる失礼 人力検索 q.hatena.ne.jp
意外と穴場? 2ch 5ch.netから探す
検索実行: ←オプション確認後に検索ボタンを押してください

期間指定:情報の鮮度も大切?
指定なし(全て)※不変の情報を得るには指定無しが一番?
3日以内 最新の更新情報を探す時など。
3ヶ月 これはあまり使わないかも
1年以内の更新なら情報鮮度もOK?バランス型
3年も経てばOfficeもバージョンUP?
検索実行: ←オプション確認後に検索ボタンを押してください

メッセージ送信

ここまで、読んでいただきどうもです。ここから下は、三流君宛のメッセージ送信や 三流君のホームページの紹介・案内です
目的の情報が見つかったか?少々心配しつつ、、、

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


あなたのお名前(ニックネーム):さん
返信は?:


アドレス:に返事をもらいたい
感想や質問↓:


対応速度・緊急度:
(回答・感想は下記のようにしてHPで記事に載せてます) 例:[XXXXさんへ回答例]←みたいに回答していたり...
とても急ぎで連絡がほしい、そんな時は:[twitter三流君DM]に気軽に連絡してください。

[三流君(TOPへ)] / [VBAで楽しく] / [記事一覧]
カスタム検索