IEを操作するためのEXCEL VBAの基本操作-IEでURLにアクセスする

Navigateメソッドを使用して、IEでURLにアクセスします

次にはIEを使用して特定のURLを起動してアクセスする方法を説明します。IEを起動することには、InternetExplorerオブジェクトのNavigateメソッドが使用されます。

Navigateメソッドを使用して特定のURLのWebページを表示しますが、Webページが完全に読み込まれるまで待ちたい場合は、他のプロセスが必要です。それでは、詳しく説明します。

Navigateメソッドを使用してIEでURLにアクセスする流れ

この記事では、最初にプロセス過程について説明します。著者は全体の操作内容を把握する上で、具体的なプログラミングの編集方法を学んだほうが、より深く理解できると思います。

プロセスの流れは次のとおりです。

1、変数の定義

2、IEオブジェクトの生成

※IEオブジェクトのメソッドとプロパティが利用可能になります。

3、IEオブジェクトの表示

※ブラウザを表示してください。

4、指定したURLにアクセスする。

5、すべてのWebページが読み込まれるまでプログラムを待機させる。

※Webページの表示と読み込み完了のプロセス方法が異なります。

VBAの関数、メソッド、プロパティについて

今回使用する必要のある関数、メソッド、プロパティは次のとおりです。

CreateObject関数

CreateObject関数は、自動化された機能を使用してオブジェクトを一時的に生成する関数です。 この関数を使用すると、外部アプリケーションをオブジェクトとして操作できます。

Set オブジェクト変数名= CreateObject( "アプリケーション名。オブジェクトタイプ")

DoEvents関数

DoEvents関数は、プロセス中にオペレーティングシステムを操作する関数です。長時間のプロセスやループプロセスの場合、プロセスが終了する前にオペレーティングシステムを操作できません。(ループプロセス中には、オペレーティングシステムまたはExcelインターフェイスの更新権限は付与されません)

そのため、DoEvents関数を使用すると、オペレーティングシステムを一時的に操作し、プロセスできます。ただし、この関数を使用すると、長時間のループプロセスや無限ループが発生することがよくあります。使いすぎると、安定したプロセスよりも時間がかかる場合がありますので、ご注意ください。

DoEvents

Now関数

Now関数は、使用されているコンピューターのシステム日付と時刻の設定に基づいて、現時点の日付と時刻をVariant型の値に返します。今回はこの関数を使用して、無限ループの問題を解決します。

Now

TimeSerial関数

TimeSerial関数は、パラメータで指定された時、分、秒に対応する時間を取得し、Variant型の値を返します。この関数は、無限ループの問題を解決するためにも使用されます。

TimeSerial(0, 0, 20)

Navigateメソッド

Internet ExplorerオブジェクトのNavigateメソッドを使用すると、IEは指定されたURLを表示できます。全部で5つのパラメータがありますが、今回は必要なURLのみを使用します。

objIE.Navigate("IEに表示するURL")

Visibleプロパティ

InternetExplorerオブジェクトのVisibleプロパティはIEに表示するかどうかを設定できます。非表示の状態では、目に見えないだけなので、この場合はIEオブジェクトを操作できます。

objIE.Busy = True/False

Busyプロパティ

InternetExplorerオブジェクトのBusyプロパティは、Webページがロードされているかどうかを示すために使用されます。Trueはロード中を意味し、Falseはロードが完了したことを意味しますが、実際のプロセスでは、True→False→True→Falseのようなループの場合もあります。

例えば、Webサイトがframeまたはiframeタグを使用している場合、最初のフレームがロードされた後、しばらくFalseを返しますが、次のframeがロードを開始すると再びTrueになります。

Javascriptなどの他のスクリプトも、実行時に同じ現象が発生するため、Busyプロパティを使用してWebページがロードされているかどうかを判断するだけでは不十分です。これを理解してください。

objIE.Busy = True/False

Internet ExplorerオブジェクトのReadyStateプロパティ

InternetExplorerオブジェクトのReadyStateプロパティは、IEオブジェクトのドキュメントのロードの状態を示すために使用されます。ロードの状態は0~4の5つのステージに分割され、上記のBusyプロパティのframeの一部をロードしてすべてのframeが完了する状態をマークするために使用できます。同時に、Busyプロパティを使用してページが完全にロードするのを待つのは、比較的に普通の方法です。

objIE.readyState = 0〜4

DocumentオブジェクトのReadyStateプロパティ

DocumentオブジェクトのReadyStateプロパティは、Documentオブジェクトのドキュメントのロードの状態を示すために使用されます。ロードにはプロセスは4つのステージに分かれていますが、返す値は文字列であることに注意してください。このプロパティを使用して、Webページが完全にロードするのを待つこともできます。

objIE.document.readyState =
"uninitialized"/"loading"/"interactive"/"complete"

Refreshメソッド

InternetExplorerオブジェクトのRefreshメソッドは、ブラウザによって表示されるWebページを更新するために使用されるメソッドです。このメソッドは、ブラウザの読み込みに失敗した場合に有効なメソッドです。

objIE.Refresh

IEサンプルプログラムでNavigateメソッドを使用して特定のURLにアクセスする

今回、VBAコードは、「VBAのIE操作」Webサイトのホームページを表示するマクロを実装します。これはIE操作が使用しなければならないプロセスなので、注意してください。

Sub sample()

Dim objIE As InternetExplorer

'IE(InternetExplorer)オブジェクトの作成
Set objIE = CreateObject("InternetExplorer.Application")

 'IE(InternetExplorer)表示
objIE.Visible = True

'指定したURLを表示する
objIE.Navigate "https://www.ceodata.com/"

'Webページが完全に読み込まれるまで待つ
Do While objIE.Busy = True Or objIE.ReadyState <> 4
DoEvents
Loop

End Sub

実行結果

「Florianstudio」サイトのホームページが表示されます

説明

次には上記のVBAコードを1行ずつ説明します。

Sub sample()
 Dim objIE As InternetExplorer

これは、Subプロセスでパラメータが定義されていないサンプルプログラムです。まず、Dimステートメントを使用してInternetExplorerタイプの変数objIEを定義すると、対応するスペースがメモリに割り当てられます。

変数を定義することにより、InternetExplorerオブジェクトは、作成した後にそのプロパティとメソッドを使用できます。

'IE(InternetExplorer)オブジェクトの作成
Set objIE = CreateObject("InternetExplorer.Application")

次に、オブジェクトを参照するSetステートメントとCreateObject関数を使用して、InternetExplorerオブジェクトを作成します。

'IE(InternetExplorer)の表示
objIE.Visible = True

このコードは、InternetExplorerオブジェクトのVisibleプロパティをTrueに設定します。VisibleプロパティはIEを表示および非表示にするように設定でき、IEはTrueに設定すると表示します。

デフォルトでは非表示状態であるFalseに設定されていますが、非表示になっているだけで、IEオブジェクトの操作は正常に実行できることを注意してください。

'指定したURLを表示する
objIE.Navigate https://www.ceodata.com/

上記のコードは、IEで指定されたURLのIEオブジェクトのNavigateメソッドの設定メソッドを表示するために使用されます。最初のパラメータを表示するURL「http://www.vba-ie.net/」に設定されているため、「VBAのIE操作」Webサイトのホームページが表示されます。

'Webページが完全に読み込まれるまで待つ
Do While objIE.Busy = True Or objIE.ReadyState <> 4
 DoEvents
Loop

このコードは、他のWebサイトユーザーにとってより常用のメソッドです。指定したWebページはNavigateメソッドで表示できますが、ブラウザがWebページを完全に読み込まれるまで待つ機能はありません。

Webページが完全に読み込まれず、後続の処理が実行されると、エラーが発生したり、予期しないプロセスが発生したりする可能性があるため、プログラムはWebページが完全に読み込まれるまで待機する必要があります。 (Basic Authentication(基本認証)を除く)

読み込み中であるかどうかは、IEオブジェクトのBusyプロパティとReadyStateプロパティによって判定されます。BusyプロパティがTrueの場合は読み込みを意味し、ReadyStateプロパティが「4」の場合は読み込みが完了したことを意味します。

次はReadyStateプロパティの返す値のリストです。4以外の返す値は読み込みを示しているため、プロセスを待機しているループ条件は「BusyプロパティがTrueであるか、ReadyStateプロパティが4以外です」です。

定数返す値説明
READYSTATE_UNINITIALIZED0返す値。 読み込んでいない
READYSTATE_LOADING1IEオブジェクトの読み込み中の状態
READYSTATE_LOADED2IEオブジェクトは読み込んだ状態だが、操作できない
READYSTATE_INTERACTIVE3IEオブジェクトが操作できる状態
READYSTATE_COMPLETE4IEオブジェクトのすべてのデータが読み込んだ状態

「特定の条件が満たされたときにプロセスを繰り返す(条件式がTRUE)」という機能のDo While〜Loopステートメントを使用するため、BusyプロパティがTrueであり、ReadyStateプロパティが4に等しくない場合は、ループを繰り返す必要があります。

ReadyStateプロパティの返す値は定数値または数値のいずれかです。 つまり、4を「READYSTATE_COMPLETE」に変更することは同じです。他のWebサイトにも同様のコードがある場合は、READYSTATE_COMPLETE=4として理解してください。

'Webページが完全に読み込まれるまで待つ(定数を使用する)
Do While objIE.Busy = True Or objIE.ReadyState <> READYSTATE_COMPLETE
 DoEvents
Loop

さらに、DoEvents関数がループで使用されます。通常、ループ中に操作を実行できませんが、オペレーティングシステムが操作を転送できるようにするDoEvents関数を使用しているため、ループ中に操作を実行できます。ただし、マシンのパフォーマンスを非常に低くすることを回避できるVBA関数もあります。

DoEvents関数が使用されているかどうかの個人的な理解として、著者は、コンピューターを操作せずにWebページをトラバースしてデータを収集するだけであれば、特に使用する必要はないと考えています。また、操作を移さずにEscキーで一時停止できるため、自分だけで使用し、他のユーザーには使用しない場合は、DoEvents関数を使用する必要はありません。

これまで、2つのプロパティを使用して、Webページが完全に読み込まれるまでの待機処理を実行してきましたが、ブラウザがフリーズした状況もよくあります。この場合、Webブラウザは完全に読み込まれるまで繰り返し待機する必要があるため、無限ループに陥ります。

この無限のループに対する対策の1つは、一定期間後にWebページをリロード(更新)して、Webページの無限の待機状態を回避します。この場合のコードは次のとおりです。

Dim timeOut As Date

'現在の時刻に20秒を追加する
timeOut = Now + TimeSerial(0, 0, 20)

Do While objIE.Busy = True Or objIE.ReadyState <> 4
DoEvents
Sleep 1
If Now > timeOut Then
'ページをリロード(更新)
objIE.Refresh
timeOut = Now + TimeSerial(0, 0, 20)
End If
Loop
15 
'現在の時刻に20秒を追加する
timeOut = Now + TimeSerial(0, 0, 20)
 
Do While objIE.document.ReadyState <> "complete"
DoEvents
Sleep 1
If Now > timeOut Then
'ページをリロード(更新)
objIE.Refresh
timeOut = Now + TimeSerial(0, 0, 20)
End If
Loop

まず、Dimステートメントを使用して日付形式(Date)の変数timeOutを定義します。次に、現在の時刻を返すNow関数と、指定した日時に対応する値を日付形式(Date)の変数TimeSerialに変更し、変数timeOutを処理時間+20秒に割り当てることができます。上記の例では、処理時間が10:15:20の場合、変数timeOutの値は10:15:40になり、20秒長くなります。

Do While objIE.Busy = True Or objIE.ReadyState <> 4
 DoEvents
 Sleep 1
 (省略)
Loop

ここでは、上記のDo While〜Loopステートメントを使用して、Webページが完全に読み込まれる前の待機処理を実現します。DoEvents関数とWindows APIのSleep関数はループ内に記録されます。

上記のように、DoEventsの処理内容に応じて使用するかどうかを判定します。Windows APIのSleep関数はループ処理中に使用され、システムのCPUを占有します。

したがって、指定された時間内に処理を停止できるWindows APIのSleep関数を設定すると、CPU使用率を維持できます。ここでは“Sleep 1”に設定し、パラメータの単位はマイクロ秒であるため、0.001秒の停止処理があります。

ただし、デメリットがあり、処理時間が長くなるだけで実行速度が遅くなります。そのため、プロセスと構成を組み合わせて使用しましょう。

If Now > timeOut Then
 'ページをリロード(更新)
 objIE.Refresh
 timeOut = Now + TimeSerial(0, 0, 20)
 End If

次の処理では、条件分岐ステートメントIf〜Then〜Elseを使用して、変数timeOutに格納されている時間が過ごした場合、IEオブジェクトのRefreshメソッドを使用してページをリロード(更新)し、無限ループを回避します。

ページがリロード(更新)された後、処理時間+20秒が変数timeOutに再び割り当てられます。 ブラウザがフリーズした場合にリロードすると、無限ループを回避できますが、完璧なやり方ではありません。これは、メモリの小さいコンピューターやメモリの大きいWebページを開くと、通常より時間がかかる場合があるためです。

ページの読み込み時間が20秒を超えると、「ページのリロード(更新)」の無限ループに陥るため、処理の内容に応じて適切な待ち時間を選択してください。

timeOut = Now + TimeSerial(0, 0, 20)

Do While objIE.document.ReadyState <> "complete"
 DoEvents
 Sleep 1
 If Now > timeOut Then
  'ページをリロード(更新)
  objIE.Refresh
  timeOut = Now + TimeSerial(0, 0, 20)
 End If
 Loop

上記の処理により、IEオブジェクトの状況がチェックされ、次にDocumentオブジェクトの状況をチェックします。

DocumentオブジェクトもHTMLドキュメントであるため、データの抽出或はクリック操作などのHTMLドキュメントの操作を実行する場合は、より信頼性の高い「HTMLドキュメントが読み込まれたかどうかの確認」を使用して安全性を高めます。

ここで、オブジェクトが異なればReadyState値も異なることに注意する必要があります。 IEオブジェクトのReadyStateプロパティは、読み込みが完了すると整数値4を返しますが、Docume返す値は文字列”complete”です。

次は、DocumentオブジェクトのReadyStateプロパティの返す値のリストです。このリストから、IEオブジェクトのReadyStateプロパティとの違いを区別します。

返す値説明
“uninitialized”デフォルト。 読み込み前。
“loading”Documentオブジェクトが読み込み中
“interactive”Documentオブジェクトが読み込み中、操作できる
“complete”Documentオブジェクトが読み込んだ

このような同じプロパティとメソッドを持っているが、異なるオブジェクトが異なる値を返す場合、この記事ではどのオブジェクトプロパティまたはメソッドであるかを明確に説明します。これを理解すると、この記事を理解しやすくなります。

また、オブジェクト、コレクション、メソッド、属性などのVBAの基礎を理解していない場合は、「VBA初心者向け」チュートリアルを参照した後、IEの操作に挑戦することができ、理解も深まります。そのため、この初級チュートリアルをご覧ください。

今の課題に戻り、Documentオブジェクトのロード状態がチェックされます。ReadyStateプロパティの設定値が異なる以外、他のプロセスは同じです。この部分のコードも、読み込みが完了するまで繰り返し処理されるため、ループからジャンプすると、ページが完全に読み込まれたことを意味します。

この記事では、ロードが完了する前にプロセスの無限ループを回避するためにIEオブジェクトを使用するRefreshメソッドを説明しましたが、ページが完全にロードされていない状態でプロセスを終了したい場合もあります。

この場合、Refreshメソッドを使用する代わりに、jumpステートメントGoToを使用して、20秒後にプログラムをループからジャンプさせることも一つの解決策です。そうすれば、確実に次の処理が一定時間後に実行されるので、それ以降のプロセスを強制的に実行するメソッドとも言えます。

Dim timeOut As Date

'現在の時刻に20秒を追加する
timeOut = Now + TimeSerial(0, 0, 20)

Do While objIE.Busy = True Or objIE.readyState <> 4
DoEvents
Sleep 1
If Now > timeOut Then
'label01にジャンプする 
 GoTo label01
End If
Loop

label01:

現在の時刻に20秒を追加する
timeOut = Now + TimeSerial(0, 0, 20)

Do While objIE.document.ReadyState <> "complete"
DoEvents
Sleep 1
If Now > timeOut Then
'label02にジャンプする
GoTo label02
End If
Loop

label02:

改良されたサンプルプログラム

以下は、Webページがロードされる前に処理を待機するVBAコードです。 今回はWindows APIのSleep関数を使わなければなりませんでしたが、これも検討中の問題です。Windows APIについては、改めて説明しますが、今回はまず、以下のコードのプロセス内容を理解しましょう。

#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
#End If

Sub sample()

Dim objIE  As InternetExplorer
Dim timeOut As Date

'IE(InternetExplorer)オブジェクトの作成
Set objIE = CreateObject("InternetExplorer.Application")

 'IE(InternetExplorer)表示
objIE.Visible = True

'IEブラウザに指定されたURLを表示する
objIE.navigate "http://www.ceodata.com/"

'ページが完全に読み込まれるまで待つ
timeOut = Now + TimeSerial(0, 0, 20)

Do While objIE.Busy = True Or objIE.readyState <> 4
DoEvents
Sleep 1
If Now > timeOut Then
objIE.Refresh
timeOut = Now + TimeSerial(0, 0, 20)
End If
Loop

timeOut = Now + TimeSerial(0, 0, 20)

Do While objIE.document.ReadyState <> "complete"
DoEvents
Sleep 1
If Now > timeOut Then
objIE.Refresh
timeOut = Now + TimeSerial(0, 0, 20)
End If
Loop

End Sub

まとめ

この記事では、Webページが表示された場合、必須の注意事項などについて説明しました。プロセスの内容を一つずつ理解することはそれほど難しくありません。この記事は最も基礎のもののため、よく理解してください。

Share

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です