ie-excel

エクセル・マクロでie操作

Excel VBAでIEのリンクをクリック(テキスト文字検索)

2019/01/21

Excelで目的のURLを自動的に開くことは前回例示しましたが、今回はそこから違うサイトへとハイパーリンクをたどってリンクするやり方を簡単に解説していきたいと思います。
ハイパーリンクも複数種類があるために、今回はテキスト型のリンクのリンク先への遷移方法です。

そこで今回のお題は
「Yahoo!Japan」でファイナンスのページへ自動リンクする
を実践。

前準備

  • Visual Basic Editor の画面から「ツール」→「参照設定」を選択します。
  • 「Microsoft Internet Controls」と「Microsoft HTML Object Library」にチェックを入れて、OKを押す

特定のサイトを開き、リンクをクリックする

URLがわかっている特定のサイトを開くためには、ヒトが操作すると以下の行為が必要です。

  1. IEを立ち上げる
  2. URLを入力する
  3. サイトが表示されるのを待つ
  4. クリックするリンクを特定する
  5. リンクをクリックする

このヒトが無意識に行なっている動作をExcel VBAで表現される必要があります。
すると以下の通りになります。

実際のコード
'変数を必ず定義すると宣言
Option Explicit

'変数を定義
Dim objIE As InternetExplorer
Dim ieDoc As HTMLDocument
Dim obj As Object

Sub IE_Click()

'Internet Exploreを立ち上げる
  Set objIE = CreateObject("InternetExplorer.Application")
  objIE.Visible = True

'URLを指定する
  objIE.Navigate2 "https://www.yahoo.co.jp/"

'該当のWebサイトが表示されるのを待つ
  While objIE.Busy Or objIE.readyState <> READYSTATE_COMPLETE
    DoEvents
  Wend

'HTML型ドキュメントに収録する
  Set ieDoc = objIE.Document

'表示されているサイトのアンカータグ一つずつを変数objにセット
'アンカータグの表示内容が「ファイナンス」の場合に該当するタグをクリックし、処理を抜ける
  For Each Obj In ieDoc.getElementsByTagName("a") 
    If Obj.innerText = "ファイナンス" Then
      Obj.Click
      Exit For
    End If
  Next

'該当のWebサイトが表示されるのを待つ
  While objIE.Busy Or objIE.readyState <> READYSTATE_COMPLETE
    DoEvents
  Wend

'オブジェクト参照を解除
  Set ieDoc = Nothing
  Set objIE = Nothing

End Sub

マクロを実行したら、「Yahoo!ファイナンス」のトップサイトが開いていませんか?

上記コードの解説

特定のサイトを立ち上げる

Dim objIE As InternetExplorer
Dim ieDoc As HTMLDocument
Dim obj As Object

Sub IE_Click()

'Internet Exploreを立ち上げる
  Set objIE = CreateObject("InternetExplorer.Application")
  objIE.Visible = True

'URLを指定する
  objIE.Navigate2 "https://www.yahoo.co.jp/"

'該当のWebサイトが表示されるのを待つ
  While objIE.Busy Or objIE.readyState <> READYSTATE_COMPLETE
    DoEvents
  Wend

Yahoo!Japanを開くところまでは解説済みのため、以下のサイトを参照ください。

Excel VBA でIEを操作して特定サイトを開く

それ以降を説明します。

読み込んだサイトをHTML型ドキュメントに収録
  Set docIE = objIE.Document

上記で読み込んだサイトをHTML型のドキュメントに収録しています。
「objIE.document」では利用できなかったプロパティなどが使えるようになることもあるため、ドキュメントはHTML型ドキュメントに収録します。

対象とするタグを特定する

この処理からがやや難解ですが、避けては通れません。
ただ、パターンを覚えてしまえば、同じような処理ばかりとなりますので、パターンだけをしっかりと覚えましょう!

今回クリックするターゲットのタグは以下のタグです。

<a href="https://finance.yahoo.co.jp/>ファイナンス</a>

このタグをクリックする方法はたくさんありますが、その代表的なものを紹介します。

タグを限定する

タグを限定するためには、HTML型ドキュメントに収録されている要素から「アンカータグ」のみを抽出することになります。

docIE.getElementsByTagName("タグ名")

上記命令により「タグ名」に指定されたタグをすべて抽出することができます。
「div」タグを抽出したければ、docIE.getElementsByTagName("div")と記載すればいいこととなります。

指定されたタグが複数あれば、それを配列形式ですべて取得することとなります。
そのために、その中から該当のタグを選択する必要が発生します。

参考まで、該当のタグ名をすべて抽出するのと同じような命令で。以下のようなものがあります。

getElementsByTagName("タグ名") タグ名で限定  例<foo>●●</foo>
getElementsByName("NAME") NAMEで限定  例:<input name=foo>
getElementsByClassName("Class名") Class名で該当タグを限定  例:<div class=foo>●●</div>
getElementById("Id名") ID名でタグを限定  例:<div id=foo>●●</div>
●●番目の□□タグを選択
docIE.getElementsByTagName("タグ名")(数字)

上記の数字はゼロから開始します。
ですから、5番目のタグに対して処理したい場合は、

docIE.getElementByTagName("A")(4)

と定義します。
数字が5番目にも関わらず、一つ減算されて「4」となっていることに注意ください。

抽出されたタグを一つずつ処理して該当のタグを限定する
For Each Obj In docIE.getElementsByTagName("a")
 ・・・ 
Next

アンカータグを一つずつ読み込み、該当のタグが見つかったら抜ける処理です。
上記コードは以下の処理を実行しています。

  • 現在IEが表示しているページのアンカータグ(Aタグ)それぞれを一つずつ「obj」に収録
  • 「・・・」の処理を実行する
  • 次のアンカータグ(Aタグ)を処理する

なお、途中でこのループを抜ける場合は「Exit For」の命令を記述すると抜けることができます。
※今回はクリックしたのちに抜けています。

複数のアンカータグの中から該当を特定する
    If Obj.innerText = "ファイナンス" Then
      ・・・
    End If

今回はアンカータグの中から、タグの中の文字が「ファイナンス」であるタグを特定します。
そのため、「innerText」というプロパティを利用しています。

innerTextとouterText

innerTextと同じような命令でouterTextがありますので、その違いも含めて説明します。
innerTextはタグの内側を取得、outerTextはタグ全体を取得します。

今回ターゲットしているタグは以下の通り

<a href="https://finance.yahoo.co.jp/>ファイナンス</a>

それぞれで取得される結果は以下の通りとなります。
innerTextの方が使い勝手がいいため、今回はinnerTextを活用しています。

innerText ファイナンス
outerText <a href="https://finance.yahoo.co.jp/>ファイナンス</a>
クリックする
obj.Click

そしてクリックという処理自体は「click」で操作できます。
今回の場合、各アンカータグをobjに代入していますので、objをクリックすることになります。

ループを抜ける

対象が見つかったので、これ以上ループさせる必要性はないためにループを抜けます。

  Exit For

これによりForとLoopの抜けて次の処理ができることになります。
この部分だけ記載してもわからないと思うので、全体を表示すると

  For Each Obj In docIE.getElementsByTagName("a") 
    If Obj.innerText = "ファイナンス" Then
      Obj.Click
      Exit For
    End If
  Next

上記ロジックは以下を行なっています。

  • For Eachでそれぞれのアンカータグを次々に読み取り
  • 内部のテキストが「ファウナンス」の場合、クリック
  • For Eachを抜けて次の処理をする
次の画面が表示されるのを待つ
  While objIE.Busy Or objIE.readyState <> READYSTATE_COMPLETE
    DoEvents
  Wend

上記クリックにより、画面遷移が発生します。
そのため、その画面遷移後の画面が表示されることを待ちます。

画面がオブジェクトへの参照を解除
  Set docIE = Nothing
  Set objIE = Nothing

セットしたオブジェクトをそれぞれ解除しています。
不要論もあるようですが、ここはお約束で設定しています。

すでにIEが開いている状態で、対象項目をクリックする

 

'変数を必ず定義すると宣言
Option Explicit

'変数を定義
Dim objIE As InternetExplorer
Dim ieDoc As HTMLDocument
Dim obj As Object
Dim objShell  As Object
Dim objWindow  As Object


Const strSite As String = "Yahoo"

Sub IE_Click()

  'シェルのオブジェクトを作成
  Set objShell = CreateObject("Shell.Application")

  '立ち上がっているエクスプローラーをすべて検索
  For Each objWindow In objShell.Windows

    '対象をIEのみに限定
    If objWindow.Name = "Internet Explorer" Then
      Set objIE = objWindow

            '該当のWebサイトが表示されるのを待つ
        While objIE.Busy Or objIE.readyState <> READYSTATE_COMPLETE
            DoEvents
        Wend

'      'HTML型ドキュメントに収録する
      Set ieDoc = objIE.document

      'タイトルにYahooの文字列があるIEのSelectタグの中で選択されている文字列をメッセージボックスとして出力する
      If InStr(ieDoc.Title, strSite) > 0 Then

        '表示されているサイトのアンカータグ一つずつを変数objにセット
        'アンカータグの表示内容が「ファイナンス」の場合に該当するタグをクリックし、処理を抜ける
        For Each obj In ieDoc.getElementsByTagName("a")
          If obj.innerText = "ファイナンス" Then
            obj.Click
            Exit For
          End If
        Next
      End If
    End If
  Next

  '該当のWebサイトが表示されるのを待つ
  While objIE.Busy Or objIE.readyState <> READYSTATE_COMPLETE
    DoEvents
  Wend

'オブジェクト参照を解除
  Set ieDoc = Nothing
  Set objIE = Nothing

End Sub

 

-ExcelでIE操作