プロが教える店舗&オフィスのセキュリティ対策術

ブラウザコントロールでタグを探っています。TRの中の文字の長さを取得しているのですが、今までPentium M や Pentium IIIのノートでは何も問題ありませんでした。ところが、今回、Core Duoのノートに変更したところ Ifのところで書き込みができませんというエラーがでて止まります。

For のところで一度ブレイクをかけて次の Ifへいったときは問題がありません。Forにはいる前にページ自体が読み込み完了しているかはチェックしていますが、今回の場合、どのようなチェックを入れたらいいものでしょうか?

よろしくお願いします。

   For Each myTag In myIE.Document.all.tags("TR")
     If (Len(myTag.innertext)) < 10000 then
     
     End If
   Next myTag

A 回答 (4件)

> アーリーバインディングしていました。



アーリーでもレイトバインドでも大丈夫だと思いますけど
以下は、読み込み待機のサンプルです。試してみてください。

 # ちなみに HTML ソースや innerText 取得のみが目的なら IE を起動
 # する必要はありません。
 # Microsoft HTML Object Library の createDocumentFromUrl で直接
 # HTML DOM を生成できるので。

Private Declare Sub Sleep Lib "kernel32.dll" ( _
    ByVal dwMilliseconds As Long)

' IE オブジェクト ReadyState プロパティーの定数(抜粋)
Public Const READYSTATE_COMPLETE   As Long = 4

Sub SampleProc()

  ' myIE ってことはグローバルレベルですよね...?
  ' でもサンプルなので...ローカルでやります
  
  Dim IE     As Object ' InternetExplorer Application
  Dim TR     As Object ' HTMLTableRow
  Dim sUrl    As String
  Dim bComplete  As Boolean
  Dim bChangeUrl As Boolean
  
  sUrl = "http://oshiete1.goo.ne.jp/qa2592462.html"
  
  Set IE = CreateObject("InternetExplorer.Application")
  ' IE 可視化
  IE.Visible = True
  ' 一度空ページに Navigate してから目的のページに飛ぶ
  ' --> Document 取得でエラーにならない
  IE.Navigate "about:blank"
  IE.Navigate sUrl
  ' 2 重のロジックでロード完了を待機
  Do
    If IE.Busy Or IE.ReadyState <> READYSTATE_COMPLETE Then
      bComplete = True
    End If
    If UCase$(IE.Document.URL) <> "ABOUT:BLANK" Then
      bChangeUrl = True
    End If
    ' 無駄な CPU パワー消費防止のため適当に Sleep する
    Call Sleep(100)
    ' ※ DoEvents については、私はあった方が良いと思う
    DoEvents
  Loop Until bComplete And bChangeUrl
 
  If UCase$(IE.Document.URL) Like "RES://*" Then
    ' タイムアウトやエラー404などで目的の Document が
    ' 正しく取得できなかった場合の処理
    Debug.Print "(ERR) Document の取得に失敗しました"
  Else
    ' 目的の Document が正しく取得できた場合の処理
    For Each TR In IE.Document.all.tags("tr")
      ' innerText をイミディエイトウインドウに表示
      Debug.Print TR.innerText
    Next
  End If
 
  ' InternetExplorer への参照を開放
  Set IE = Nothing
  
End Sub
    • good
    • 0
この回答へのお礼

大変、遅くなりました。

いただいたソースでCore Duoでも落ちないことが確認できました。

ありがとうございました。

お礼日時:2007/04/13 21:11

こんにちは。

#1のWendy02です。

>『myIE.Document.all.tags("TR") 一旦、オブジェクト変数の中』とご指摘いただいておりますが、具体的にどのようなコードを書けばよろしいのでしょうか?

コード自体は、たぶん、ありきたりのないようで、問題はないとは思っています。
ただ、eIE(IEオブジェクトの変数)を維持するのが、厳しいのかな思ったのです。

単に
 Set DocAll = myIE.Document.All
 または、
 Set DocAllTags = myIE.Document.All.Tags("TR")

ということです。

もしくは、全体に、With ステートメントを入れて、


With myIE
 
  または、
 Set DocAllTags = .Document.All.Tags("TR")
 または、
 'Set DocAll = .Document.All →DocAll.tags("TR") と繋ぐ。
 
  For Each myTag In DocAllTags
    If (Len(myTag.innertext)) < 10000 then
     '実行
    End If
  Next myTag
End With



それと、話が前後してしまいますが、
Do While myIE.Document.ReadyState <> "complete"
   ↓
ここは、

Do Until myIE.ReadyState = 4 '(事前バインディングなら、[READYSTATE_COMPLETE])

としたほうがよいのでは?
    • good
    • 0

こんばんは。



> Core Duoのノートに変更したところ Ifのところで書き込みができません
> というエラーがでて止まります。

結論から言えば、Document オブジェクトが正しく取得できてないのだと
思います。その根拠は、

> For のところで一度ブレイクをかけて次の Ifへいったときは問題が
> ありません。

このコメントで明らかです。原因は、

> Forにはいる前にページ自体が読み込み完了しているかはチェックしています

ここです。このチェック方法に誤りがあるか、または不十分なのでしょう。

他 PC で動作し、Core Duo でエラーとなったのは、単に各 PC のネットワーク
性能、環境、あるいは設定などプログラムとは異なる要素による結果に過ぎない
のでは?

現時点では、これ以上何とも言えないのですが、IE オブジェクト生成~For Each
までのコードを補足してもらえますか?

この回答への補足

こんにちは。ありがとうございます。

まず、#1さんでご指摘がありましたが、myIEはアーリーバインディングしていると思っていたのですがソウではありませんでした。まずは、ここを直してみたいといけないと思います。myIEの生成は、、、

  Set myIE = CreateObject("InternetExplorer.application")

です。


読み込み完了チェックは、、、、

  Do While myIE.Busy
    DoEvents
  Loop

  Do While myIE.Document.ReadyState <> "complete"
    DoEvents
  Loop
  
以上です。


不足の点がありましたら、また追加いたします。

よろしくお願いします。

補足日時:2006/12/11 09:09
    • good
    • 0
この回答へのお礼

すみません、アーリーバインディングしていました。ご回答いただいたお二方に訂正します。

お礼日時:2006/12/11 09:40

こんばんは。



最初に、機種固有の問題は、同じ機種を持った人間でないと、分からないような気がします。

全体像は見えていないのではっきりとしませんが、

>Ifのところで書き込みができませんというエラーがでて止まります。

エラーコードは、実行時エラー「70」 なのでしょうか?

もしかしたら、コードの途中で、アクセスして作った、myIEの IEオブジェクトが壊れているか、ラインが切れているもしれません。もし、そうだったら、事前バインディングしたらいかがですか?

CreateObject をしているのではありませんか?

また、途中で、回線に割り込みが入っている場合は、こちらでは、どうしようもありませんね。例えば、ブレイクの代わりに、Wait を入れても、多少、余裕を持たせても、あまり期待できないかもしれません。Wait の代わりに、API のSleep を置くというのもありますが。

どこか、切れそうな危ない部分に、
  DoEvents
を入れて、ラインの命綱が、途切れないようにするとか、

それと、
 myIE.Document.all.tags("TR") このままだと、丸抱えになりますから、それを、一旦、オブジェクト変数の中に入れてから、それを、Tags("TR") 分だけを別に取り出し、負担を軽減させるとか。

方法は、いろいろ試してみるしかありません。

この回答への補足

こんにちは。ありがとうございます。

ご指摘の通りアーリーバインディングではありませんでした。エラーは70です。
まずは、ここを直してみます。

『myIE.Document.all.tags("TR") 一旦、オブジェクト変数の中』とご指摘いただいておりますが、具体的にどのようなコードを書けばよろしいのでしょうか? ご教授いただけると、幸いです。


よろしくお願いします。

補足日時:2006/12/11 09:10
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!