CoCoのYDブログ

心に思い浮かんだことを少し掘り下げ発信します

【VBA】画面移動の間処理を待つ方法

こんにちは

今回は前回の続きです。

IEにて画面の表示中にテキストの表示を行うとエラーが発生するため少し時間をあける必要があるというお話しでした。

ではIEが読み込み中の間は処理をしないという条件を追加したらどうなるのでしょうか?

 

Busyプロパティを使用する

Sub WaitTest()
    Dim ie As InternetExplorer

    Set ie = CreateObject("InternetExplorer.Application")

    ie.Visible = True
    ie.navigate "https://ydcoco.hatenablog.com/"

    Do While ie.Busy
        Debug.Print ie.Busy
        DoEvents
    Loop
    MsgBox ie.document.body.innerText

End Sub

 前回のプログラムにDo \whileをつけてみました。

条件がie.BusyなのでIEがビジー状態の間ループするというプログラムです。

 

これなら問題なく読み込みが完了してから処理を行ってくれるはず・・・とすんなり行かないんです。

 

Busyプロパティで監視しているのはIEがビジー状態かどうかです。

ジー状態が終わったからといって読み込みが完全に終了したとは限りません。

 

 ReadyStateプロパティ

Sub WaitTest()
    Dim ie As InternetExplorer

    Set ie = CreateObject("InternetExplorer.Application")

    ie.Visible = True
    ie.navigate "https://ydcoco.hatenablog.com/"

    Do While ie.Busy Or ie.readyState < READYSTATE_COMPLETE
        Debug.Print ie.Busy & ":" & ie.readyState
        DoEvents
    Loop
    MsgBox ie.document.body.innerText

End Sub

While の条件を変更してみました。

readyStateとは

オブジェクトの読み込み状態を数値として表すものです。

 

定数 戻り値 説明
READYSTATE_UNINITIALIZED 0 未完了状態
READYSTATE_LOADING 1 IEオブジェクトのロード中
READYSTATE_LOADED 2

IEオブジェクトのロード完了

ただし、操作不可能

READYSTATE_INTERACTIVE 3 IEオブジェクトの操作可能状態
READYSTATE_COMPLETE 4 IEオブジェクトの全データ読み込み完了

 ie.readyState < READYSTATE_COMPLETEは

IEオブジェクトが全データを読み込み終わるまでループを行って欲しいためつけられていることがわかります。

 

Sleep

ページを全部終わってもJavaScriptを多用するページでは再読み込みが行われる場合があるそうです。

そこでSleep関数を使用して少し時間を空けてから、再び読み込み状態の確認を行うと確実らしいです。長いわ!w

Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Sub WaitTest()
    Dim ie As InternetExplorer

    Set ie = CreateObject("InternetExplorer.Application")

    ie.Visible = True
    ie.navigate "https://ydcoco.hatenablog.com/"

    Do While ie.Busy Or ie.readyState < READYSTATE_COMPLETE
        Debug.Print ie.Busy & ":" & ie.readyState
        DoEvents
    Loop

    Sleep 500

    Do While ie.Busy Or ie.readyState < READYSTATE_COMPLETE
        Debug.Print ie.Busy & ":" & ie.readyState
        DoEvents
    Loop

    MsgBox ie.document.body.innerText

End Sub

 Sleep はms単位で処理を止めることができるらしいので試しに0.5sの遅れにしてみました。実際に何秒が適切なのかは分からないです。PCのスペックによるだろうし。

Sleepで遅延させたから読み込み状態の確認が再度入って完了といった処理ですね。本当に長かったです。