VBAの勉強を始めてみた

色々試しています。

VBAでIEを操る(ポップアップや通知バーをSendKeysで操作する)

VBAIEを操作している途中、ポップアップや通知バーが出てきたらどうすればいいでしょうか?
今回は、その辺に焦点をあててみたいと思います。

ポップアップや通知バーが出たら、選択肢を選んで次へ進んだり、ファイルを保存したりする・・・・・・
これをオブジェクトとして操作する方法もあるようですが、正直、ちょっと煩雑です。

もともと、楽がしたくてIEの自動操作を行っているのに、そのコードを書くために長い時間を割いたり、結局上手くいかなくて何回も試行錯誤したり・・・・・・。
そのうち、本来の目的以上に時間を浪費してしまう矛盾に陥ってしまいます。まぁ、コードの技術は上がりますが(@_@;)

うー・・・ん。

まあ、その都度悩むのはやめにして、ポップアップや通知バーの操作はもれなく SendKeysメソッド で記述する作戦にしようと思います。

SendKeys とはなんぞや?

ということですが、これは、アクティブなアプリケーションにキーストロークを送信することができるメソッド・・・・・・
もうちょっと噛み砕いて言うと、人間が行うキーボード入力を再現することができるメソッド、とゆーことになります。

  • SendKeys 引数

引数には、送信するキーストロークを文字列式で指定します。

例えば、IEでファイルメニューを開くなら、Alt + F なので、下記のようにします。

  • SendKeys "%f"

 % はAltキーを押しながら、ということを表す特殊文字です。

キー操作をどのように表現するかは、MSDN 又はその他のサイトを参照下さいませ。

 

上記をふまえて、通知バーでファイル保存する操作を再現してみたいと思います。

と、その前に、IEがそもそも画面の前面にないと、キーストロークが他のアプリケーションに対して送信されるので、下記のWin APISetForegroundWindow関数IEを最前面に表示して、アクティブにしておきます。(下記は、Win32 API での例)

Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) As Long

    SetForegroundWindow (ie.hWnd)

太字の行は、モジュールの先頭(宣言エリア)に記述します。

 

さて・・・・・・、話を戻しましょう。

ファイルを保存するリンクやボタンをクリックすると、下記のような通知バー(ポップアップの場合もある)が表示されます。

f:id:kouten0430:20180901155050j:plain

 

画像に表示されているように、「保存」にはショートカットキー"S"が割り当てられているのがわかります。ショートカットキーはAltキーとの同時押しなので、

  • SendKeys "%s", True

とすることで、名前を指定せずに保存できます。(第二引数の True は、キーストロークが渡るまで処理を中断することを表します)

ショートカットキーが効かないページや、名前を付けて保存したいような場合は、Alt + N で通知バーにフォーカスを当ててから、TABキーとEnterで操作することもできます。

まずは、Alt + N で通知バーにフォーカスを当てます。

  • SendKeys "%n", True

f:id:kouten0430:20180901155126j:plain

 

最初に、「実行」が選択されていることがわかります。次に、TABキーで移動し「保存」を選択します。

  • SendKeys "{TAB}", True

f:id:kouten0430:20180901155202j:plain

 

「名前を付けて保存」は、この状態で下方向を押すと現れ、さらに「保存」の下なので、下方向を2回送信します。

  • SendKeys "{DOWN 2}", True

f:id:kouten0430:20180901155228j:plain

 

あとは、Enterで名前を付けて保存します。

  • SendKeys "{ENTER}", True

このあと表示されるダイアログボックスで、SendKeys のみでファイル名を打ち込むことも可能です。(SendKeysの引数には変数を使うこともできるので、連番などを付加することも可能)

一見、メンドくさそうですが、キー操作を模擬するだけのことなのでカンタンです。

※ファイルを保存するには、URLを直接指定する専用のメソッドもありますが、CGIなどで都度ファイルが生成されるようなものはURLが特定できないので、今回のような SendKeys が有効だと思います。