Excelのあれこれ ~ IEを自動操作するマクロ

前置き

残念ながら私の経験では、テスト仕様書をExcelで記述する職場が多いです。Excelのテスト仕様を見ながら、IE8とかIE9あたりを操作しつつ、スクリーンキャプチャを別のExcelに貼っていく……、といったスタイルで単体テストや結合テストを実施します。

こんなとき、ExcelマクロでIEを自動操作できると便利ですね。フォームに繰り返し同じ情報を入力する手間を省くことができます。Excelは常に開いているので、リボンをカスタマイズしておけばマクロ起動もワンタッチです。

IEオブジェクトを得る

IEを見つける/起動する(utils.bas)
Public Function uFindIE(Optional caption As String = "", Optional url As String = "", Optional alloc As Boolean = False) As Object
  Set uFindIE = Nothing
  
  Dim shell As Object
  Set shell = CreateObject("Shell.Application")
  
  Dim win As Object
  For Each win In shell.Windows
    If TypeName(win.document) = "HTMLDocument" And _
      (caption = "" Or InStr(win.LocationName, caption) >= 1) And _
      (url = "" Or InStr(win.LocationURL, url) >= 1) Then
      Set uFindIE = win
      Exit Function
    End If
  Next
  
  If alloc Then
    Set uFindIE = CreateObject("InternetExplorer.Application")
    uFindIE.Visible = True
    If url <> "" Then
      uFindIE.navigate url
      uIEYield uFindIE
    End If
  End If
End Function
  • タイトル(caption)とアドレス(url)を条件にして、IEオブジェクトを検索
  • 見つからない場合、alloc引数がtrueならIEを起動する
  • 起動した場合、url引数で指定されたアドレスを開く

HTMLの要素を探す

まず、class属性値からクラス名を検索するためのヘルパ関数を定義します。

文字列内のトークン有無を調べる(utils.bas)
Public Function uTokenInStr(s As String, t As String, Optional d As String = " ") As Boolean
  uTokenInStr = False
  For Each u In Split(s, d)
    If u = t Then
      uTokenInStr = True
      Exit Function
    End If
  Next
End Function

id属性、タグ名、class属性などをキーにしてHTML要素を探す関数を定義します。複数個見つかったら、ix引数で1つに絞ります。

HTMLの要素を探す(utils.bas)
Public Function uIEFindElement(ie As Object, Optional id As String = "", _
  Optional tag As String = "", Optional klass As String = "", Optional ix As Integer = 0) As Object
  Set uIEFindElement = Nothing
On Error Resume Next
  
  If id <> "" Then
    Set uIEFindElement = ie.document.getElementById(id)
    Exit Function
  End If
  
  If tag <> "" Then
    If klass = "" Then
      Set uIEFindElement = ie.document.getElementsByTagName(tag)(ix)
    Else
      Dim e As Object
      Dim i As Integer
      i = 0
      For Each e In ie.document.getElementsByTagName(tag)
        If uTokenInStr(e.className, klass) Then
          If i = ix Then
            Set uIEFindElement = e
            Exit Function
          End If
          i = i + 1
        End If
      Next
    End If
  ElseIf klass <> "" Then
    Set uIEFindElement = ie.document.getElementsByClassName(klass)(ix)
  Else
    'no criteria!
  End If
End Function

name属性をキーにしたいときは、getElementsByTagName()を使います。また、ie.document.all で、全要素を走査することもできます。

待ち

IE起動直後やページ遷移中は、IEがビジーなので操作できません。そこで、IEがアイドルになるのを待つ関数が必要です。

IEが落ち着くのを待つ(utils.bas)
Public Sub uIEYield(ie As Object)
  Do While ie.Busy Or ie.readyState <> 4
    DoEvents
  Loop
End Sub

使用例

使用例として以下を行ってみます。

  • Googleを開き(既に開いていれば、それを利用)
  • Googleの検索ボックスに"Yahoo"と入力し
  • "I'm feeling lucky"ボタンを押し
  • Yahooの検索ボックスに"Google"と入力し
  • フォームをsubmitする
  Dim ie As Object
  Set ie = uFindIE(url:="https://www.google.co.jp/", alloc:=True)
  
  uIEFindElement(ie, "gbqfq").Value = "Yahoo"
  uIEYield ie
  uIEFindElement(ie, "gbqfbb").Click
  uIEYield ie
    
  uIEFindElement(ie, "srchtxt").Value = "Google"
  uIEFindElement(ie, , "form", , 0).submit
  uIEYield ie
Last modified:2014/07/21 14:40:18
Keyword(s):
References:[Windowsリテラシ]
This page is frozen.