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で(ExcelやAccessなどから)InternetExplorer WebBrowserを操作してみたいと思います。
入り口?Document.からイロイロと操作してみたいと思います。
Webページ、HTML文章は、
タグで囲われた文章、ドキュメントで表現されています。
って、当たり前のこと書いてみました。
□ Microsoft HTML Object Library
と
□ Microsoft Internet Controls
を参照設定して、As HTMLDocument など型設定をしてみてください
下記↓、私のASP解説のテストページなのですが、ここの表からデータを抜いてみたいと思います
[http://www.ken3.org/cgi-bin/test/test028-2.asp]
↑test028-2.asp 感想データをORDER BY ID DESC で IDの降順で表示↓
ID | F_TITLE | F_MEMO | WriteTime |
---|---|---|---|
6026 | 説明が下手 | 理解が難しい・・・ | 2008/05/04 4:57:50 |
6025 | 解らん | 使えないサイトだな | 2008/05/03 5:23:24 |
5968 | ok | test | 2008/03/02 13:30:49 |
5696 | a | a | 2007/09/19 19:04:19 |
5675 | IE操作 | UWSC使用が正解 変な記事書き続けるなボケ | 2007/09/09 23:31:41 |
5505 | てすと | できるかな? | 2007/05/30 18:02:13 |
処理の流れ・仕様は
1.IEを起動する CreateObject("InternetExplorer.application")
2.目的のURL(test28-2.asp)を開く .Navigate
3.テーブルからデータを抜く(Excelのシートにセットする)
なんて感じの3行おまかせ仕様で(笑)
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
↑とにかくコレを貼り付けて実行してみてください。※サンプルで私がよく使う好きな方法は、Set objIE = CreateObject("InternetExplorer.application")なのですが、Vista IE7の保護モードだと.Navigateで失敗したり・・[三流君 Vista IE7の修正でハマる(小細工で逃げる)] ← Vista IE7の人はこちらも見てください。
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メソッドで"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(ブラウザ)さんが解析して表示をしてくれる。そんなイメージです。
先走らないでここで深呼吸、一呼吸おいて、
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番目)頭 を 探って見たいと思います)
実際に文章 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秒?
なぜ、待つかと言うと、いきなりさわるとビックリするでしょ?(オイオイ、何言ってんだおっさん)
表示待ちを入れないで いきなりオブジェクトに触りに行くと(ドキュメントなどのオブジェクトにアクセスすると) 相手の心の準備ができていないみたいで(オブジェクトの展開処理が間に合わないみたいで)、どこ見てんのよ(古)と怒られるじゃなかった、 実行時エラー Document メソッドは失敗しました ・・・など、エラーで怒られるんですよ。
エラーの画像→[http://ken3-info.blog.ocn.ne.jp/screen/2007/05/ie__debe.html]
なので、objIE.Navigate 後に相手の準備ができるが確認します。
手抜きの2秒はじゃなくてもっとチャントシタ行儀作法があるので後ほど。
えっ、今説明しないの?はい、アトで・・・気になる人は先に→[.ReadyStateと.Busyで待つ]を見てください
操作手順と実行結果の動画:IE 実行時エラー Document メソッドは失敗しました
今度は始めの0番目を表示だけじゃなくて、データを新しいシートに書き出してみます。
バカの一つ覚えの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
読者の声:だから何?、ドキュメント内のオブジェクト数は、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
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)にアクセスしに行くとエラーになったりします注意してね
よし、簡単なオブジェクトの説明終了、、、ここまで長かった。酔っぱらいの独り言に付き合っていただきどうもです。朝までにもう一軒飲み屋じゃなかった、オブジェクトをハシゴするぞと行きたい所ですが、あと一杯、少しだけお時間をとらせてください。
読者の声:だから、余計な会話はいいから、はやくシロ。(※←この読者の心の声もかなりの蛇足なんですが(笑)説明に必要ないでしょと思いつつ)
書き方に好みの問題もあるのですが、
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
この書き方が 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
話を戻して、文章の表からデータを抜きたいんですよね、やりたいことは。 忘れてたよ
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>(テーブル終わり)と、
ループで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行で仕様書?当然、穴があるんだけど・・・)
|
ポイントは、特になく(オイオイ)、
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 失敗バージョン
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までデータを飛ばしたいので
変数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 で判断して自分でセットする、そんな原始的 イヤ三流的な方法でした。嘘つきがもっとスマートな方法があるだろオイ・・と、上級読者様は突っ込まれたと思いますが、泥臭いループの練習、反面教師的ソースの例ってことでご勘弁を。
自分で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に切り替えて貼り付け
記録終了(上記操作をマクロ記録してみます)
実際に記録したコードを見てみると、ダメだ記録されてない。。。
|
操作手順と実行結果の動画:マクロ記録で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を指定)するみたいですね。
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パターンの貼り付けを実行してみます
|
テーブルを選択 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番目(テーブル位置を指定)にしてみたいと思います。
|
↑なんとか、テーブルのみを選択して貼り付けできました。まぁ、貼り付けの形式は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") これでコピーできるのかな?
ってことで、下記のようにプログラムを修正しました。
|
.execCommand "Copy" でコピーする方法、惜しかったなぁ・・・カッコつけ損ねました(笑)ってことで、表のコピーはなんかカッコ悪いけど、テーブル選択後.ExecWB 12, 0とコピーのコマンドを発行してください。
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に変更してテストしてみます。
|
ポイントは、
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 を使えよ・・・と、読者様の声が聞こえたので、テストプログラムを書いてみます。
|
まだまだ、書きかけ。
※確認すること、やることいっぱいだぁ。。。
過去のメールマガジンのリンクが長かったので、下記に移動しました。
[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へ)] / [VBAで楽しく] / [記事一覧] |
カスタム検索
|