1:Debug.Print objIE.Document.forms("hoge").all.tags("b").Length →5と出力
2:Debug.Print objIE.Document.all.Length →2500と出力
3:Debug.Print objIE.Document.all.tags("b").length →エラーを起こす
よろしくお願いします。
doxasさんがご指摘の様に、On Error GoToの行の先頭にアポストロフィ(')を挿入し、
エラー処理を無効化してから実行して、エラーメッセージを報告していただかないと
なかなか問題の本質を把握できません。
また、以下のコードを実行して、そのページの内部の構造が
きちんと列挙されるかどうか確認されてみては?
Option Explicit
Sub Enumerate_objAppIE_Document_All()
Dim iCount1 As Integer
Dim objAppIE As Object
Set objAppIE = CreateObject("InternetExplorer.application")
objAppIE.Visible = True
objAppIE.Navigate "http://XXX.YYY/"
While objAppIE.ReadyState <> 4
While objAppIE.Busy = True
DoEvents
Wend
Wend
Sheets.Add
ActiveSheet.Name = "Report" & Format(Rnd() * 10000, "0")
Cells(1, 1).Value = "Num"
Cells(1, 2).Value = "Type"
Cells(1, 3).Value = "Tag"
Cells(1, 4).Value = "OuterHTML"
Columns(1).ColumnWidth = 10
Columns(2).ColumnWidth = 20
Columns(3).ColumnWidth = 10
Columns(4).ColumnWidth = 100
For iCount1 = 0 To objAppIE.Document.All.Length - 1
Cells(iCount1 + 2, 1) = iCount1
Cells(iCount1 + 2, 2) = "'" & TypeName(objAppIE.Document.All(iCount1))
Cells(iCount1 + 2, 3) = "'" & objAppIE.Document.All(iCount1).TagName
Cells(iCount1 + 2, 4) = "'" & Left(objAppIE.Document.All(iCount1).OuterHTML, 100)
Next
End Sub
ソースコードが一部しか記載されていないですし、情報が少なすぎます。
もう少し細かく開示していただければ、解決のお手伝いができるかもしれません。
まずエラーが起きるということですが、どのような内容のエラーが起きるのでしょうか。
また、データ取得の対象となるHTMLソースには、どのくらいの<b>要素があるのでしょう。
全体が2500だからそれ以下だとは思いますが、もう少し情報をいただけませんか。
普通に考えると ReoReo7 さんが示してくれたコードでうまくいくはずですね。
現状ではそれ以上のことが言えません。
ありがとうございます。
その "b" の要素を一つ一つ取り出そうとしたのですが、うまくいきませんでした。
数えてみたら100くらいだと思います。
「普通に考えると ReoReo7 さんが示してくれたコードでうまくいくはずですね。」
↑コードの誤りそのものでは無いということですね。ありがとうございます。
多分全体の数が大きすぎるのかな?
あと、エラーの捕捉の方法が分かりません。
objIEはIEオブジェクトを格納しており、これはある会員制サイトのページを表示しています。
On Error GoTo myFail
Debug.Print objIE.Document.forms("hoge").all.tags("b").Length '←1
Debug.Print objIE.Document.all.Length '←2
Debug.Print objIE.Document.all.tags("b").Length '←3
Debug.Print " "
myFailコロン
で、F8を押しながら一つ一つ実行していくと、←3の時点でmyFailへ移動します。
エラーの内容をさらすと、答えがつきやすいんじゃないかな。
とりあえず、length の頭が L になってないのを、候補に挙げておこう。
エラーの内容の捕捉ができたら補足します!Lは単純に質問時のミスでした。
こんばんは。回答者1です。
On Error GoTo~ の記述がありますので、これだとエラーメッセージは表示されずに、指定されている myFail へ処理が移ってしまいますね。エラーの内容を得る方法はいくつかありますが、この On Error GoTo~ の一行を無効化しておけばエラーメッセージが出るはずです。
F8を押しながらステップ実行しているのであれば、オブジェクト(IEやそれに付随するオブジェクト)が破棄されてしまっているなどの、参照系のエラーではないと思いますが、なんでしょうね……想像がつきません。
もし、可能であればローカルウィンドウを活用して、オブジェクトの中身を参照してみると原因がわかるかもしれません。手元にExcelがないので記憶に頼るかたちになりますが、VBEの表示メニューのなかに、ローカルウィンドウというのがあるはずですので、それを表示しておき、同様にF8でステップ実行してみてください。ローカルウィンドウのなかにオブジェクトの詳細な情報が表示されるはずです。
他に有効なデバッグ手段としては、オブジェクト変数をもうひとつ用意して、そちらにまずデータを取得してみる方法が考えられます。
Dim objTAG_B As Object 'オブジェクト変数をひとつ新しく宣言 '------------------------ '中略 '------------------------ Set objTAG_B = objIE.Document.all.tags("b") 'オブジェクト変数にエレメントコレクションを取得
上記のようにオブジェクト変数に一度データを取得することができると、ローカルウィンドウから目的の情報を探しやすくなるでしょう。
ただし、一度オブジェクト変数を経由しているとは言え、<b>タグのエレメントコレクションを取得しようとしている処理自体は ReoReo7 さんが先に掲示してくれたコードと同じです。つまり先ほどのエラーの原因がわからないと(解決しないと)、オブジェクト変数(objTAG_B)にオブジェクトを得ることができないはずです。
とにかくエラーの内容、これがわからないことにはどうにも難しいです。
ありがとうございます。
エラーコード取得はまだできていませんが、先にローカルウィンドウでのオブジェクトの展開を試してみました。
オブジェクトの構造は、objIE-Document-allの下にItem(*)があるのですが、これがItem(256)までしか表示されていません。つまり、エレメントの下のコマンドが使えるのは256個以下の数字のみということになりそうです。
つまり、Debug.Print objIE.Document.all.Lengthは2500個あっても出力できるが、その下位エレメントであるobjIE.Document.all.tags("b")というのは、allの数が256を超えた時点でtags()コマンドが使用不可になるらしいのです。
ありがとうございました。必要に応じてもう少し掘り下げてみます。
追記(10月9日):
Dim objTAG_B as Object
Set objTAG_B = objAppIE.Document.all.tags("b")
debug.print objAppIE.Document.all.tags("b").Length
を、4の回答者Silvanusさんの示すプログラムのURLの値を所望のアドレスに変えてobjAppIEを取得後、試しましたが、コメント欄に示すエラーが出ます。また、URLをwww.google.co.jpで試したところ、
Debug.Print objAppIE.document.all.Length '106を出力
Set objButton = objAppIE.document.all.tags("b") '実行可能
Debug.Print objAppIE.document.all.tags("b").Length '2を出力
となり、大丈夫でした。このエラーの原因は分かりませんが、ページのDocument.All.Lengthで示されるエレメント数が256を超えていることと何か関係あるのでしょうか。
doxasさんがご指摘の様に、On Error GoToの行の先頭にアポストロフィ(')を挿入し、
エラー処理を無効化してから実行して、エラーメッセージを報告していただかないと
なかなか問題の本質を把握できません。
また、以下のコードを実行して、そのページの内部の構造が
きちんと列挙されるかどうか確認されてみては?
Option Explicit
Sub Enumerate_objAppIE_Document_All()
Dim iCount1 As Integer
Dim objAppIE As Object
Set objAppIE = CreateObject("InternetExplorer.application")
objAppIE.Visible = True
objAppIE.Navigate "http://XXX.YYY/"
While objAppIE.ReadyState <> 4
While objAppIE.Busy = True
DoEvents
Wend
Wend
Sheets.Add
ActiveSheet.Name = "Report" & Format(Rnd() * 10000, "0")
Cells(1, 1).Value = "Num"
Cells(1, 2).Value = "Type"
Cells(1, 3).Value = "Tag"
Cells(1, 4).Value = "OuterHTML"
Columns(1).ColumnWidth = 10
Columns(2).ColumnWidth = 20
Columns(3).ColumnWidth = 10
Columns(4).ColumnWidth = 100
For iCount1 = 0 To objAppIE.Document.All.Length - 1
Cells(iCount1 + 2, 1) = iCount1
Cells(iCount1 + 2, 2) = "'" & TypeName(objAppIE.Document.All(iCount1))
Cells(iCount1 + 2, 3) = "'" & objAppIE.Document.All(iCount1).TagName
Cells(iCount1 + 2, 4) = "'" & Left(objAppIE.Document.All(iCount1).OuterHTML, 100)
Next
End Sub
ありがとうございます。プログラムを実行してみたところ、できました!
実行には2分ほどかかりました。NUM=2331程度でした。
内部の構造の取得には問題ないようですね・・・。
複数ある"B"タグの中から、所望の"B"タグの中身(innerText)を取り出したかったのですが、まず"B"要素を取り出したくてもできなくて困っていました。
そこで、違う回避策を見つけました。このほうが実行も早そうです。
objIE.Document.all.tags("b").length
ではなくて、所望の"B"タグの直前(タグ数で10個以内)にある、「DIV ID="hoge"」や「SCRIPT NAME="hoge2"」のように、ユニークなIDまたは名前のついている要素を
Dim i as Long
i = objIE.Document.all.Item("hoge").sourceindex
のように取得して、
Dim j as Long
For j = i to i + 10
If objIE.Document.all.Item(j).nodeName = "B" then
msgbox "望みの'B'タグの中身は" & objIE.Document.all.Item(j).innerText & "です。"
End If
Next
として取得することで解決している状態です。
まだ、そもそも何でエラーしたのかは分かっていませんが。。
ありがとうございます。プログラムを実行してみたところ、できました!
実行には2分ほどかかりました。NUM=2331程度でした。
内部の構造の取得には問題ないようですね・・・。
複数ある"B"タグの中から、所望の"B"タグの中身(innerText)を取り出したかったのですが、まず"B"要素を取り出したくてもできなくて困っていました。
そこで、違う回避策を見つけました。このほうが実行も早そうです。
objIE.Document.all.tags("b").length
ではなくて、所望の"B"タグの直前(タグ数で10個以内)にある、「DIV ID="hoge"」や「SCRIPT NAME="hoge2"」のように、ユニークなIDまたは名前のついている要素を
Dim i as Long
i = objIE.Document.all.Item("hoge").sourceindex
のように取得して、
Dim j as Long
For j = i to i + 10
If objIE.Document.all.Item(j).nodeName = "B" then
msgbox "望みの'B'タグの中身は" & objIE.Document.all.Item(j).innerText & "です。"
End If
Next
として取得することで解決している状態です。
まだ、そもそも何でエラーしたのかは分かっていませんが。。