VBAの勉強を始めてみた

色々試しています。

VBAでIEを操る(起動済みIEをシェルとして取得)

前回は、IEを起動させると同時にIEをオブジェクトとして取得しました。
しかし、CreateObjectで起動したIEは何も表示していないIEです。Webページを表示するには、下記のように navigate メソッドでURLを指定します。 

  • ie.navigate "URLをここに記載"

 

ではでは、起動済みの、IEをオブジェクトとして取得するにはどうすればいいでしょうか?

結論からいうと、前回の CreateObject("InternetExplorer.Application") を、CreateObject("Shell.Application") に変えて取得します。

以下、さらっと読んでもらい、とりあえず雰囲気をわかってもらえればOKです。(私もエラそうに語れるほど、詳しくはない・・・・・・)

起動済みのIEを取得するには、起動しているシェルをコレクションとして取得し、さらにシェルのコレクションの中からIEを取り出す必要があります。

シェルとはなぁに?

ってことですが、人間様は普段、OSの核(カーネル)に直接触れることができないので、外皮(シェル)の上から間接的に触れて(アクセスして)います。

f:id:kouten0430:20180811132918j:plain

その、間接的な役割である、シェル(shell32.dll)の機能を使っているプログラム

例えば、ファイルエクスプローラー、コントロールパネル、Internet Explorerなどの中から現在起動中のものを、コレクションとして取得します。

んで、コレクションの中からIEを探し出して取得するために、For Each ~Next でまわして評価するのです。

Nameプロパティで、IEか否か評価するなら次のようにします。

Sub test()
    Dim ie As InternetExplorer
    Dim sh As Object
    Dim win As Object
    
    Set sh = CreateObject("Shell.Application")
    
    For Each win In sh.Windows
        If win.Name = "Internet Explorer" Then
            Set ie = win
            Exit For
        End If
    Next

End Sub

 

ついでに、ローカルウィンドウで確認したところ、ファイルエクスプローラーやコントロールパネルのNameプロパティの値は、"エクスプローラー"でした。

 

しかし、上記のコードだとIEが複数起動している場合、どのIEが取得されるか分からないので、目的の(操作したいWebページを表示中の)IEを取得するなら、Titleプロパティ(要するにHTMLのTitleタグで書かれている部分)で判定します。

Titleプロパティで評価するなら次のようにします。

Sub test()
    Dim ie As InternetExplorer
    Dim sh As Object
    Dim win As Object
    Dim DocumentTitle As String
    
    Set sh = CreateObject("Shell.Application")
    
    For Each win In sh.Windows
        DocumentTitle = ""
        On Error Resume Next
        DocumentTitle = win.document.title
        On Error GoTo 0
        If DocumentTitle = "VBAの勉強を始めてみた" Then
            Set ie = win
            Exit For
        End If
    Next
End Sub

 

ファイルエクスプローラーやコントロールパネルは document.title プロパティをもっておらず、実行時エラーとなるため On Error Resume Next ~ On Error GoTo 0 で挟み、無視するようにしています。(無視されると、変数 DocumentTitle の中身は空白になります)

上記のコードで、当ブログのトップページを表示中のIEを取得します。

この状態で、ちょっとした操作をしてみましょう。

Sub test()
    Dim ie As InternetExplorer
    Dim sh As Object
    Dim win As Object
    Dim DocumentTitle As String
    
    Set sh = CreateObject("Shell.Application")
    
    For Each win In sh.Windows
        DocumentTitle = ""
        On Error Resume Next
        DocumentTitle = win.document.title
        On Error GoTo 0
        If DocumentTitle = "VBAの勉強を始めてみた" Then
            Set ie = win
            Exit For
        End If
    Next
    
    ie.document.getElementsByTagName("TITLE")(0).innerText = "タイトルを変更してみた"

End Sub

 

上記のコードを実行すると、下のようにタイトルが変更されます。

f:id:kouten0430:20180811133912j:plain

 

f:id:kouten0430:20180811134130j:plain

 

(ローカルのIE上で変更されているだけなので、サーバー上のデータにはもちろん影響ありません)

 

この辺については次回以降に。

 

補足:タイトルの変更だけなら document.titleプロパティ の値の変更だけでもできる

上記では汎用性がある、getElementsBy・・・・・・の形で変更していますが、タイトルだけなら、単純に、ie.document.title = "タイトルを変更してみた" でも変更できます。

 

補足:起動済みのIEを取得して操作するほうが、オートメーションエラーにならない?

今回のように、シェルから起動済みIEを取得したIEで操作したほうが、オートメーションエラーに悩まされずに済むようです。
というのも、CreateObject したIEでWebページを操作しようとしたところ、何回か「オートメーションエラー」が発生して困ったため(発生するページ、しないページ、さまざまですが)いろいろ調べてみたところ、原因としては、CreateObject した時の何も表示していないIEのセキュリティレベルと、navigateメソッドでの移動後でセキュリティレベルが変わってしまうことがあるためのようです。(というのをどこかのサイトで見た)

 

本記事は、以下の書籍

book.impress.co.jp

 及び、他の様々なサイト様の情報をパクって参考にしています。ご不明な点は書籍または他のサイト様を合わせて参考にして下さい。