Internet Explorer自動操作

VBAでIE操作「エラーに負けない」【エクセルマクロ】

VBAでIE操作(InternetExplorer操作)

ExcelVBAマクロでIEを操作し、Webスクレイピング、Webクローリングをする事が可能です。
マクロがインターネットエクスプローラーを自動で操作し、
WEBのデータ取得・登録などの、各種WEB操作します。

具体的には以下が可能です。
・IEから取得したデータをシートに書込。
・エクセルデータを、WEBブラウザに反映。

 

VBAでIE操作のエラーで困ること

どの環境でも出るのであれば、コードがおかしい為デバッグ処理をすれば問題ありません。
しかし、エラーはパソコンや回線の環境、サイトによってエラー発生するタイミングが異なることです。

(エラー例)
・ページ遷移後、読込途中に次の処理をしてしまった
=要素がない為、VBAが処理できない。
IEをNothing(objIE=Nothing)したが、実は終了できていない状態で再度IEを使用する。
=終了できていないのにもかかわらず、起動処理をするので矛盾が発生する。
IEの保護モードの整合性が取れない。
=保護モードがLowILからMediumIL に切り替わり矛盾が発生する。
保護モードは事前に回避できるとして、それ以外はエラーが出るタイミングが同一ではありません。
エラーに負けず、うまく付き合っていく必要があります。

エラーに負けない

エラーが出るタイミングは同一でなくても、対策は立てられます。

InternetExplorerMediumで起動する

IE側の設定で保護モードが悪い影響を与えるケースがあります。
急に保護モードが切り替わることで、エラーが発生します。
(セキュリティゾーンをまたぐと、セッション維持できない)

エラー例
起動されたオブジェクトはクライアントから切断されました

下記のように「New InternetExplorerMedium」を使用して、明示します。

    '■CreateObjectで作成しない(保護モードが明示されていない)
  Set objIE = CreateObject("InternetExplorer.Application")

  '■保護モードを中(MediumIL)で明示して起動する   
  Set objIE = New InternetExplorerMedium

objIEは使いまわす

プログラム上で何度もIE起動する場合はobjIEを解放せず、使いまわします。
「objIE = Nothing」としてもNothingにならず、オートメーションエラーが出る場合があります。

エラー例
オートメーションエラーです。
エラーを特定できません。

下記のようなコードは、すぐに「Set objIE = Nothing」をコメントアウトしてエラー回避しましょう。

    objIE.Quit
    Set objIE = Nothing

IEのプロセスを終了させる

上記のobjIEの使いまわしだけでは、実は不十分です。(使いまわすことでIEのプロセスが残る場合もある)
下記のようにobjIEを起動前にIEのタスクを終了させます。
この動作を入れる事、VBAでのIE操作は安定します。

'■InternetExpolerのタスクを終了する
Public Function Call_IE_TaskKill()
    Dim objShell As Object
    Dim objExec As Object
    
    Set objShell = CreateObject("WScript.Shell")
    Set objExec = objShell.Exec("taskkill.exe /F /IM iexplore.exe")
End Function

BusyやreadyStateは信用しない

前記事のブラウザの読込待ち処理ですが、待機処理が安定しない場合があります。
下記のように何度も待機処理をさせたり、

  For i =1 to 5
   call Call_IE_WaitTime 
  Next i

objectが急に掴めなくならないように、Shell.ApplicationでIEを掴みなおしたり、

Public Function Call_IE_WaitTime()
    Dim win As Object
    Dim winshell As Object
    Set winshell = CreateObject("Shell.Application")
    For Each win In winshell.Windows
        If win.Name = "Internet Explorer" Then
            Set objIE = win
            Exit For
        End If
    Next
    Do While objIE.Busy = True
        DoEvents
    Loop
    Do While objIE.readyState <> READYSTATE_COMPLETE
        DoEvents
    Loop
    Application.Wait Now() + TimeValue("00:00:02")
End Function

IDの要素がNullでない事を確認したり、

   errchk = objIE.document.getElementById("ID")

 

色々な形でエラーとうまく付き合っていきましょう。

 

その他

Internet Explorerを使用して、Webスクレイピングは敷居が高い風に捉えられますが、
上記のように、パーツ化して組み合わせ処理するだけです。

Web上のデータを触りたい要望は会社様でも個人様でも多いと思います。
VBA IE操作を覚えて効率化しませんか?
作成が大変であれば弊社で代行開発も可能です。お気軽にお問い合わせください。

 

コメント

  1. ・objectが急に掴めなくならないように、Shell.ApplicationでIEを掴みなおしたり、

    この処置でエラーがでなくなりました。
    気になるのは複数の”Internet Explorer”が開いているときに、最近開いた”Internet Explorer”に最初にあたるのが保証されているのかが知りたいです。

    • 動作確認してませんが、古いIEから見ていく気がします。
      objIE.document.Titleなどで、処理を分岐させて、最近開いたIEを掴むようにしたらいかがでしょうか。

  2. Dim win As Object
    Dim winshell As Object
    Set winshell = CreateObject(“Shell.Application”)
    For Each win In winshell.Windows
    If win.Name = “Internet Explorer” Then
    Set objIE = win
    Exit For
    End If
    Next

     ■For Each ~ をやめてインデックスでやれば最新のウィンドウから取得できます。

      dim i as long
    for i = winshell.Windows.length to 0 step -1
    Set win = winshell.windows(CINT(i))
    If win.Name = “Internet Explorer” Then
    Set objIE = win
    Exit For
    End If
    next

タイトルとURLをコピーしました