以前、「【ExcelVBA】keybd_eventをつかってCitrix経由で起動しているアプリにキー入力を送る。(手作りRPA)」という記事を書きました。
この記事の中で「keybd_event」という関数を使ってRPAを手作りしたわけですが、この記事を書いた当時はこの関数のことをよくわかっていませんでした。
いや、今もよくわかっていませんが、当時よりわかってきた気がするので追記します。
「keybd_event」には引数が4つあります。
①「bVk」には仮想キーコードを設定します。
②「bScan」にはスキャンコードを設定します。
(設定しなくても大丈夫という意見もありますが、私の環境では設定しないと動きませんでした)
③「dwFlags」は、メイクコードを送る際には0を設定しますが、ブレイクコードを設定する際には「&H2」を設定します。
④「dwExtraInfo」は使いません。
(まだ勉強不足です。使うときはあるのでしょうか。)
当時の記事の中では「keybd_event」のために「仮想キーコード」と「スキャンコード」の両方を調べなければならないと書きました。
しかし、これがぶっちゃけかなり面倒です。特に「スキャンコード」は環境によって違うようなので、自分の環境に合ったスキャンコードを調べる必要がありました。
しかし、「MapVirtualKey」関数を使うことで「スキャンコード」を調べる手間を減らせるのではないかと思います。
「MapVirtualKey」については以下のページが参考になりました。いくつか機能がありますが、RPAを作るうえでは仮想キーコードをスキャンコードに変換してくれる機能が役に立ちます。
www.tokovalue.jp
「MapVirtualKey」には引数が二つあります。
「wCode」と「wMapType」です。
「wCode」には仮想キーコードを設定します。
「wMapType」には使用したい機能ごとに値を設定します。
仮想キーコードをスキャンコードに変換したい場合は「0」を設定します。
これらの情報をもとに、「keybd_event」を「MapVirtualKey」を活用しながら使うと以下のようになります。
Private Declare PtrSafe Sub keybd_event Lib "user32" _ (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long) Private Declare PtrSafe Function MapVirtualKey Lib "user32" _ Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long Dim wsh As Object Set wsh = CreateObject("Wscript.shell") wsh.AppActivate "新規 Microsoft Excel ワークシート.xlsm" Range("A1").Select keybd_event 65, MapVirtualKey(65, 0), 0, 0 'keybd_event 65, MapVirtualKey(vbKeyA, 0), 0, 0 でも可 Set wsh = Nothing End Sub
このようにすることで、A1セルにアルファベット小文字のaを入力できます。
では、例えば以下のようにしたら「ctrl+A」と「ctrl+V」を再現してコピペができるかと思ったのですが、動きませんでした・・・。
Private Declare PtrSafe Sub keybd_event Lib "user32" _ (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long) Private Declare PtrSafe Function MapVirtualKey Lib "user32" _ Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long Dim wsh As Object Set wsh = CreateObject("Wscript.shell") wsh.AppActivate "新規 Microsoft Excel ワークシート.xlsm" Call コピー Call ペースト Set wsh = Nothing End Sub Private Sub コピー() Range("A1").Select keybd_event &H11, MapVirtualKey(&H11, 0), 0, 0 keybd_event 67, MapVirtualKey(67, 0), 0, 0 keybd_event 67, MapVirtualKey(67, 0), &H2, 0 keybd_event &H11, MapVirtualKey(&H11, 0), &H2, 0 End Sub Private Sub ペースト() Range("A2").Select Application.Wait [Now() + TimeValue("00:00:00.5")] Call keybd_event(&H11, MapVirtualKey(&H11, 0), 0, 0) Call keybd_event(86, MapVirtualKey(86, 0), 0, 0) Call keybd_event(86, MapVirtualKey(86, 0), &H2, 0) Call keybd_event(&H11, MapVirtualKey(&H11, 0), &H2, 0) End Sub
原因は勉強中です。
sub「コピー」を呼び出した後の「keybd_event 67, MapVirtualKey(67, 0), &H2, 0」で何故か処理が終了してしまうんですよね。
ここがクリアできれば、手作りRPAを作るのがもっと楽になります(スキャンコードを調べる手間がなくなるので)。
そしたら、手作りRPAのメンテナンスとかが楽になって、ウチの会社の他の課の人とかにも使って貰いやすくなるなぁ・・・。
なんて、そもそもVBAを使える人も勉強する人も全然いない弊社では広めていくのは難しいんですがね・・・。