VBA IE操作編 意外と知らない?【webサイトでファイル選択・添付する方法】

この記事は約9分で読めます。

VBA IE操作編 9回目サムネイル

どうも、マサヤです!

この記事は、VBAでのIE操作が初めて or 慣れていない方向けに『Webサイト・システムの情報を取得・設定する方法』をお伝えしていく連載記事となってます!

 

前回はリストボックスのJavaScriptを発動させる方法を紹介しました!

 

今回は「Webサイト上にある「ファイルを選択」のクリック、ファイルを選択する方法」をお伝えします!

※サイトによってはファイルを選択ではなく、添付やアップロードといったボタンになってたりします。

「ファイルを選択」をクリックするだけならClickメソッドで可能ですが・・・・・・実は落とし穴があります。

これを解説していきますよ!

本記事で習得できること

  • Webサイト・システムにある「ファイルを選択」ボタンを操作できる。
  • 変数をクリップボードへ格納する方法

 

スポンサーリンク

ファイル選択のサンプルページ

 

今回も例にもれずサンプルページを用意しました。

ぜひ理解度を上げるためにも、記事を読む前にサンプルページを触ってみてください。

 

「ファイルを選択」ボタンのHTMLコード

サンプルのファイル選択のHTMLは下記となります。

<input id="add-file" type="file">

idが付与されているので、VBAではgetElementByIdを使って操作していきます。

 

失敗:Clickメソッドだけでは失敗する

 

では、Clickメソッドだけで実行した例をみていきましょう。

 

動画で失敗例を見る

では、Clickメソッドだけで実行した動画をご覧ください。

※クリックすると大きくなります。

VBA JSファイル選択失敗例

ボタンである「ファイルを選択」はクリックできましたが、ポップアップした画面に対して操作ができず、処理が止まっています。

失敗するVBAコード

下記が失敗するコードになります。

Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr)
Sub ie_AddFile()

    'IEオブジェクトを作成
    Dim ie As InternetExplorer
    Set ie = CreateObject("InternetExplorer.Application")
    
    'HTMLコレクションを取得 独自関数化
    Call IeGetObj(ie, "https://mmm-program.com/vba-ie-sumple-file/")
   
   'ファイルを選択をクリック 
  ie.document.getElementById("add-file").Click
    
    'クリップボードにコピー
    Dim CB As New DataObject
    Dim buf As String

    'ファイルのパス設定
    buf = "C:\Users\masay\Downloads\テスト.png"
    
    With CB
        .SetText buf        '変数のデータをDataObjectに格納する
        .PutInClipboard     'DataObjectのデータをクリップボードに格納する
    End With
    
    Sleep 2000
    'キー操作 Ctrl+V を実行
    SendKeys "^v"
    
    Sleep 1000
    'キー操作 Altl+o を実行
    SendKeys "%o"
    
    'オブジェクトを閉じる
    ie.Quit

    'メモリからオブジェクトを破棄
    Set ie = Nothing
 
End Sub
'指定URLのオブジェクトを取得する独自関数
Sub IeGetObj(obj, url, Optional vFlg As Boolean = True)
    
    'IEを表示(見えるようにする)
    obj.Visible = vFlg
    
    '指定したURLをIEで開く
    obj.navigate url
    
    'サイトの読み込みが完了するまで待つ
    Do While obj.Busy = True Or obj.readyState <> READYSTATE_COMPLETE
        DoEvents
    Loop
    
End Sub

なぜ、Clickメソッドでは失敗するのか?

前途のコードは一見すると問題なさそうですが、どこが問題なんでしょうか?

本来であれば、ファイル選択画面が表示されたら次のプログラムを実行してほしいわけですが、下記コード実行すると、IE処理からWindowsのファイル選択画面となり、プログラムとしてはIE処理が途中と認識して、ファイル選択の画面を閉じられるまで次の行にあるプログラム処理へ移行できません。

※上記コード 12行目
ie.document.getElementById("add-file").Click

 

スポンサーリンク

成功:ファイルを選択を成功させた動画

 

では、成功させるコードをみていきましょう。

まずは動画で動きを確認してから、VBAコードを見ていきましょう。

 

VBAコードでJavaScriptが発動した動画

VBA JSファイル選択成功例

↑の動画を見ると、ファイル選択後の画面でもプログラムは止まらず、ファイル名を入力⇒開くと操作が続いてることが確認できます。

何が違うのか?

コードを見ていきましょう。

 

このVBAコードでファイル選択が成功!

Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr)
Sub ie_AddFile()

    'IEオブジェクトを作成
    Dim ie As InternetExplorer
    Set ie = CreateObject("InternetExplorer.Application")
    
    'HTMLコレクションを取得 独自関数化
    Call IeGetObj(ie, "https://mmm-program.com/vba-ie-sumple-file/")
 
    '「ファイルを選択する」をクリックする
    ie.document.parentWindow.execScript "window.setTimeout(""document.getElementById('add-file').click()"",100);"
    
    'クリップボードにコピー
    Dim CB As New DataObject
    Dim buf As String

    'ファイルのパス設定
    buf = "C:\Users\masay\Downloads\テスト.png"
    
    With CB
        .SetText buf        '変数のデータをDataObjectに格納する
        .PutInClipboard     'DataObjectのデータをクリップボードに格納する
    End With
    
    Sleep 2000
    'キー操作 Ctrl+V を実行
    SendKeys "^v"
    
    Sleep 1000
    'キー操作 Altl+o を実行
    SendKeys "%o"
    
    'オブジェクトを閉じる
    ie.Quit

    'メモリからオブジェクトを破棄
    Set ie = Nothing
 
End Sub
IeGetObjは上記コードと同じのため省略しています。

コードを見るとClickメソッドではなく、何が長いコードを使っているのが解ります。

 

parentWindow.execScriptがポイント

Clickメソッドの代わりに下記のコードを利用しています。

ie.document.parentWindow.execScript "window.setTimeout(""document.getElementById('add-file').click()"",100);"

これは「100ミリ秒後にid属性add-file(ファイルを選択ボタン)をクリックしろ」といったコードになってます。

parentWindow.exeScriptは、IE側にスクリプト処理を依頼することができるメソッドになります。

ただ、IE側にスクリプト処理が完了するまで、次のプログラムに進めません。

これを回避するために、JavaScriptのsetTimeoutメソッドで対処しています。

setTimeoutは「何秒後に●●処理しなさい」と命令した段階で処理完了扱いとなり次のプログラムを処理することができるようになります。

お気づきの方がいるかもしれませんが、VBSを作成・実行することでVBAとVBSでの疑似マルチスレッドで同じことが可能ですが、少し面倒なので簡単に済むsetTimeoutメソッドを使ってます。

 

注意!スクリプトの書き方

parentWindow.execScriptの””(ダブルクォーテーション)の中に書くスクリプトは、JavaScriptで正しく書きましょう。

大文字・小文字や使用するカッコなどを間違えると、エラー or エラーは出ないが想定処理がされない

例えば、Clickメソッドを下記のように書いてもダメです。

“window.setTimeout(“”document.getElementById(‘add-file’).Click“”,100);”

VBAでは正解ですが、JavaScriptではclick()が正しいため正しく処理されません。

詳しく言うと、エラーは発生しませんがクリック処理がされません。

 

また、要素番号をしているときに利用するカッコは、()ではなく[]なので注意しましょう。

 

まとめ

 

Webサイトでのファイル選択(添付)の方法をお伝えしました。

ファイルの選択は、Clickメソッドでなく、

parentWindow.execScriptでsetTimeoutメソッドを使う。

 

さて、今回でIE操作編は最後となります。

ここまでお読みいただいてありがとうございました!

 

1回目から実践しながら追っていれば、IE操作処理に困ることはほぼなくなっているでしょう。

まさに自由自在にWeb操作できるようになっていると思います。

もし、あなたが単調なデータ収集や入力操作で時間を使っているなら、ぜひ学んだことを生かして自動化してみてくださいね。

 

さて、IE操作編は連載としては終了しましたが、ピンポイントで操作方法や補足知識などを不定期でお届けする予定です。

コメント