ラベル VBA、IE の投稿を表示しています。 すべての投稿を表示
ラベル VBA、IE の投稿を表示しています。 すべての投稿を表示

2011年4月7日木曜日

VBAでJavaScriptが埋め込まれたリンクをクリックする

仕事場で使用されている業務システムがInternetExplorer6クライアントで動いており、私はこのIE上に表示されるコンテンツをVBAで取得するという仕組みを作っています。



tableタグやinputタグ内のコンテンツは難なく取得できたのですが、リンク先の画面からデータを取得するというところで行き詰まってしまいました。

だってリンクがクリックできないんだもん 笑
(URLを直接指定するのではなくリンクからでないと遷移できない画面なのです)

inputタグのsubmitボタンは簡単にクリックできるのですが、aタグに埋め込まれたリンクがクリックできませんでした。

そこでいつものあのサイトにたどり着くだろうなと思いつつググったわけです。
やはり行き着いたのはこのサイトでした。

「AB型の変わり者 三流プログラマー Ken3のHP」

私がVBAでIEを操作できるようになったのはこのサイトのおかげです。

もともと知人の方がVBAでWebページを操作するという仕事をしていらっしゃるという話を聞いたことがあり、VBAでWebページが操作できることは知っていました。

それを身につけるに至ったのは、仕事場の業務システムリリースにあたって大量のデータをクリーニングのためにチェックしていた際、この作業はVBAで処理できるんじゃないか、と思い立ったからでした。

そこから私のVBAとIEの物語が始まりました。

IEで動く業務システムを支配下に置く(?)ことに快感を覚え、またこのプログラムによっていろんな業務処理が効率化できそうだということで、VBAのツール作成依頼があちこちから湧いてきました。

今回のツール作成もその一つです。

さて、以下プログラムの紹介です。

VBAからIEブラウザ上のJavaScriptのリンクをクリックします。

-----------------------------------------------------------------------------------

1.リンク先アドレスの確認
まずはリンク先のURLがプログラム上でどう読み込まれるのかを把握します。
対象のWebページのHTMLソースを参照すればリンク先のアドレスを知ることはできますが、プログラム上で処理する場合のアドレスと異なっている場合があります。
確実に操作するためには先にリンク先のアドレスを調べた方がよさそうです。


Option Explicit

'-----変数-----

'IEオブジェクト
Dim objIE As Object

'処理対象のリンクカウンタ
Dim i As Integer
'--------------


'----------------------------------------
'アドレスの確認
'----------------------------------------
'リンク先アドレスを文字列で取得し、イミディエイトウィンドウに表示する

Sub CheckAddress()

'InternetExplorerオブジェクトを生成するサブルーチン呼び出し
Call CreateIE

'生成したIEオブジェクト上で処理対象のURLを指定し、遷移
objIE.navigate "http://oirnao.blogspot.com/"

'ページ読込待機のサブルーチン呼び出し
Call WaitIE

'IEオブジェクト内の全リンクをチェックし、イミディエイトウィンドウにリンク先アドレスを表示
For i = 0 To objIE.document.Links.Length - 1
      
        'イミディエイトウィンドウに表示
        Debug.Print objIE.document.Links(i).href
      
    Next i
  
    '生成したIEオブジェクトを閉じる
    objIE.Quit

End Sub
'----------------------------------------
'End Of アドレスの確認
'----------------------------------------


処理結果をイミディエイトウィンドウで確認するとクリックしたいアドレスが表示されているはずです。



HTMLソースを参照すると大文字で入力されている内容が実は小文字だったりします。
HTMLソースだと"JavaScript"~となっているところが"javascript"~というように。
この大文字小文字の違いで意図したように処理されないという事象が発生するので先にアドレスを確認します。

2.指定したリンクのクリック
1.リンク先アドレスの確認で取得したリンク先アドレスをプログラムに埋め込みます。
ここでは仮にリンク「javascript:openwinA('5');」をクリックするものとします。


'----------------------------------------
'リンクのクリック
'----------------------------------------
'指定したリンクをクリックする
Sub ClickLink

'InternetExplorerオブジェクトを生成するサブルーチン呼び出し
Call CreateIE

'生成したIEオブジェクト上で処理対象のURLを指定し、遷移
objIE.navigate "http://oirnao.blogspot.com/"

'ページ読込待機のサブルーチン呼び出し
Call WaitIE

'IEオブジェクト内のリンクをチェックし、クリックしたいリンクを探す
For i = 0 To objIE.document.Links.Length - 1
      
        '取得したリンク先アドレスを文字列単位で比較
        If objIE.document.Links(i).href = "javascript:openwinA('5');" Then
        
          'クリック対象だったらクリックする
            objIE.document.Links(i).Click
          
            'ループを抜ける
            Exit For
          
        End If

    Next i

End Sub
'----------------------------------------
'End Of リンクのクリック
'----------------------------------------


0.補足
上記で使用しているサブルーチンです。


'----------------------------------------
'IEオブジェクト生成
'----------------------------------------
'Internet Explorerのオブジェクトを生成する
Sub CreateIE()
  
    'IEオブジェクトを生成
    Set objIE = CreateObject("InternetExplorer.Application")
  
    'IEオブジェクトを可視化する
    objIE.Visible = True
  
    'IEオブジェクト画面の表示位置(左上の座標)とサイズ(高さ・幅)を調整
        '左上 上位置
        '左上 左位置
    objIE.Top = 0
  
    objIE.Left = 0
  
End Sub
'----------------------------------------
'End Of IEオブジェクト生成
'----------------------------------------


'----------------------------------------
'ページ読込待機
'----------------------------------------
Sub WaitIE()
'指定したページの読み込みが完了するまで待機する
    Do Until objIE.Busy = False
        DoEvents
      
    Loop

End Sub
'----------------------------------------
'End Of ページ読込待機
'----------------------------------------


-----------------------------------------------------------------------------------

以上、私がリンクをクリックするまでに行った処理です。
クリックができて画面遷移した瞬間に、嬉しすぎて仕事場でにやついたのは秘密です。
できることが増えるって楽しいですね。

2011年3月24日木曜日

Internet Explorer を起動するVBA

Internet Explorerを起動するマクロは以前作成していました。
※参考:http://oirnao.blogspot.com/2011/01/vbaieie.html
今回はこのマクロをもっと使い勝手の良いものにしようと思い、少しだけ改良してみました。


引数指定されたページをIE上で表示する、という簡単なものです。

-----以下ソース-----
'--------------------------------------------------------------------------------------
'InternetExplorerを起動し、引数に指定されたURLを表示する
'--------------------------------------------------------------------------------------
Sub BootIE(URL As String)
    Dim objIE As Object
  
    'IEObjectをセット
    Set objIE = CreateObject("InternetExplorer.application")

    'セットしたObjectをActivate
    objIE.Visible = True

    'Objectの表示位置調整
    objIE.Top = 0
    objIE.Left = 0
   
   '指定されたURLのページ表示
    objIE.navigate URL
  
    '指定したページの読み込みが完了するまで待機
    Do Until objIE.busy = False
        DoEvents
    Loop
  
End Sub
'--------------------------------------------------------------------------------------
'End
'--------------------------------------------------------------------------------------

-----ソースここまで-----

私の知識とともにこういった小さなプログラム達が成長していくことが楽しみだったりします。
まだ少ししかネタはありませんが、VBAはよく使う道具なのでライブラリ化していくつもりです。
きれいなプログラムが書けるようになりたいな。

2011年1月17日月曜日

VBAでIE操作~IE起動とロード待機のプロシージャ~

VBAでIEを操作するマクロの開発。
IEの起動とURLアクセス後のページ読み込み待機処理はマクロ中でよく使う部品なのでサブルーチン化しました。
きれいなソースを目指してあれこれ調べては改造を繰り返していますが、とりあえずこれで使えるものになったかなぁ・・・ということでエントリーです。

以下ソース


'【要件】
'IEの起動
'指定URLの表示


'【要件詳細】
'空白のIEページを表示する
'表示したIEページ上で指定したURLのページを表示する
'指定したページの読み込みが完了するまで待機する


'【処理フロー】
'空白IEWindow起動
'  ↓
'指定URLへリンク
'  ↓
'ページ読み込み待機


'【プログラム上の制約】
'サブプロシージャとして機能できるよう、パブリック変数を使用する


'【構成】
'-Option Explicit
'--パブリック変数
'-BootIE
'--IEの起動
'-WaitIE
'--ページ読込待機


'【詳細設計】
'------------------------------< start of source >------------------------------
Option Explicit
Public objIE As Object      'IEオブジェクトをセットする

'--------------------< start of SubRoutine >--------------------
Sub BootIE()
'空白のIEページを表示する
  
    'IEObjectをセット
    Set objIE = CreateObject("InternetExplorer.application")
  
    'セットしたObjectをActivate
    objIE.Visible = True
  
    'Objectの表示位置調整
    objIE.Top = 0
    objIE.Left = 0
  
End Sub
'----------< end of SubRoutine >----------


'--------------------< start of SubRoutine >----------
Sub WaitIE()
'指定したページの読み込みが完了するまで待機する
    Do Until objIE.busy = False
        DoEvents
    Loop
  
End Sub
'----------< end of SubRoutine >----------
'------------------------------<  end of source  >------------------------------

VBAでIE操作~起動中の画面タイトルを取得~

IEで起動している画面のタイトル一覧を作成するというVBAのプロシージャを作りました。
元々はある掲示板にあったソースで、それを自分の作業用に改変しました。
参考:http://hpcgi1.nifty.com/MADIA/VBBBS/wwwlng.cgi?print+200508/05080025.txt

今回こんなプロシージャを作ったのは、IEにおいて、起動しようとしている画面が既に開かれていないかをチェックするためです。
同一画面を2つ以上立ち上げていると予期せぬ不具合が発生しうるというシステムに対する回避策です。
今後のソース改造と勉強のためにひとまずエントリーしておきます。


以下ソース

Sub GetIETitle()
'IE test 用プロシージャ
'開いているIEWindowのタイトルを取得する

Dim objShell As Object
Dim intIEcnt As Integer
Dim i As Integer
Dim objIE(64) As Object
Dim objWindow As Object



'IE検索
'シェルのオブジェクトを作成する
Set objShell = CreateObject("Shell.Application")
      
'IEウィンドウ数初期化
intIEcnt = 0
      
'ウインドウの数だけまわす
For Each objWindow In objShell.Windows
  
    'MsgBox TypeName(objShell.windows)
    'Debug.Print "タイプは:" & TypeName(objWindow.document)
            
    'HTMLDocumentだったら
    If TypeName(objWindow.document) = "HTMLDocument" Then
        'オブジェクトを代入する
        Set objIE(intIEcnt) = objWindow
        intIEcnt = intIEcnt + 1
    End If
Next
Set objShell = Nothing

'IE TITLE取得
'発見したウインドウの数だけまわす
For i = 0 To (intIEcnt - 1)
    objIE(i).Visible = True
    Worksheets("test").Cells(i + 1, 1).Value = objIE(i).document.Title
  
Next i
End Sub