電子書籍の厳選無料作品が豊富!

vbaでieの操作をしているのですが

Sub マクロ1()
Do While ObjIE.Busy = True
DoEvents
Loop
End Sub

でも
Sub マクロ2()
Const READYSTATE_COMPLETE As Long = 4

Do Until ObjIE.ReadyState = READYSTATE_COMPLETE
Loop
End Sub

でも、
表示される前に次のコードへ進んでしまって
エラーになってしまいます。

表示されるまで待たせるには
Application.Wait (Now + TimeValue("00:00:03"))
を付け足すしかないのでしょうか?

(できればこれは使いたくないです)
ご教授よろしくお願い致します。

A 回答 (3件)

こんばんは。



現在は、私は、こうしたコードは一切使っていませんが、Navigate で開くなら、そのサイトの重さに依存するので、いつまでも、Complete にならないこともあります。だから、こういう場合は、どちらかというと、ループの回数を数え(i = i + 1)、一定の回数を越えたら、マクロの離脱(GoTo EndLine or Exit Sub)を強制的にさせます。もちろん、イベントでエラーを得ても良いかもしれませんが、試したことはありません。

'-------------------------------------------
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
Const URL As String = "http://www.google.co.jp/"
'Private WithEvents IE As InternetExplorer '参照設定
Sub Test1()
  Dim IE As Object
  Dim i As Long
  Set IE = CreateObject("InternetExplorer.Application")
  ''Set IE = New InternetExplorer '参照設定の場合
  With IE
    .Visible = True
    .Navigate URL 'URLは、定数
    Do While .Busy
      DoEvents
    Loop
    Do Until .ReadyState = 4
      DoEvents
      Sleep 1000 '1秒
      i = i + 1
      If i > 50 Then
        MsgBox "一定期間で開けませんでした。", vbInformation
        GoTo EndLine
      End If
    Loop
  End With
EndLine:
  Set IE = Nothing
End Sub

ただ、IEを開く目的でコードを書くなら、Sleep やWait を使わざるを得ないと思います。

そうして、以下のようなイベントを置く必要があるのかは、なんとも言えません。私は、なくても、Waiting の調整で長い間処理してきました。

'参照設定 イベント設定
'Private Sub IE_DocumentComplete(ByVal pDisp As Object, URL As Variant)

Private Sub IE_NavigateComplete2(ByVal pDisp As Object, URL As Variant)
  MsgBox "Navigate Completed" '"Document Completed"
End Sub
    • good
    • 0
この回答へのお礼

Sleepを使うのもいいアイディアですね。
大変参考になりました。有難うございます。

お礼日時:2009/12/23 22:28

こんにちは。


#2の回答者です。私の発言は、誤解を受けるような説明でしたので、訂正・補足しておきます。

>Application.Wait (Now + TimeValue("00:00:03"))
>だと3秒たっても終わらない時や、3秒前に終わる時があってムラがあり、いやなんです。

Waitを入れる目的は違うのです。

#2のコードは、本来は、こうしたWait(私の場合、Sleep) を入れるということは、その時間を待たせて開くという働きではなくて、ループを遅らせる目的なのです。ループで早く抜けるか遅く抜けるは、それは誰にも分からないです。それは、Webのステータスのタイミングをとるということです。そのために、Sleep と DoEvents を組み合わせるわけです。そして、時間的な間隔ではなくて、ループの規定回数を越えたら、IEオブジェクトの離脱を取るようにするわけです。そうしないと、無限ループになる可能性があるからです。

もちろん、そういう考え方に足りない部分があるのは承知しています。IEオブジェクトとは言っても、IEそのものでしかありませんから、そこにアドオンがあったり、JavaScript, ActiveX, 画像など、そういうものが障害になります。私の場合は、Google Tool Bar が邪魔しました。
また、IEの設定にも影響を受け、一般的な設定ではHTMLでエラーが発生したら、無限ループ状態になりかねません。今回のマクロでは、あくまでも、「便宜的」なものです。この方法からは、目的のサイトがある以上は、IEオブジェクトを使った完璧な解決というものはないのです。

言葉にすると分かりにくいのですが、そうした考え方の上で、#2のコードが書かれています。
    • good
    • 0
この回答へのお礼

有難うございました。

お礼日時:2009/12/29 12:12

>(できればこれは使いたくないです)


 私は、面倒なので、逆に
Application.Wait (Now + TimeValue("00:00:03"))
で済ませていますが、「DocumentCompleteイベント」を利用するという方法が一般的なようです。
●VB6 IEオブジェクトで読み込み完了まで待たせる
http://hpcgi1.nifty.com/MADIA/VBBBS2/wwwlng.cgi? …

 使い方については、
●IE アプリケーションのイベントを横取りする
http://www.ken3.org/vba/backno/vba108.html
をご覧ください。

 ただし、
●[IE] 新しいブラウザ ウィンドウを開いたときに DocumentComplete イベントが発生しないことがある
http://support.microsoft.com/kb/316593/ja
そうです。
    • good
    • 0
この回答へのお礼

Application.Wait (Now + TimeValue("00:00:03"))
だと3秒たっても終わらない時や、3秒前に終わる時があってムラがあり、いやなんです。
見てみます!ご回答ありがとうございます。

お礼日時:2009/12/23 10:31

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