LoginSignup
1
3

More than 5 years have passed since last update.

VBAから非同期でSendKeysを行う

Posted at

概要

VBAからPowerShellを非同期で実行し、.NETのSendWaitを実行するだけ

コード


''' <param name="iKeys">
'''送信する文字列
'''</param>
''' <param name="pSendDelayMilliSec">
'''SendWaitを実行する前の待ち時間(ミリ秒)。
'''PowerShell起動そのもののオーバヘッドもあるため、既定値は0ミリ秒
'''</param>
Public Sub AsyncSendKeys(ByVal iKeys As String, Optional ByVal pSendDelayMilliSec As Long = 0)
    Dim psCmdTxt(4) As String
    Let psCmdTxt(0) = "PowerShell.exe -sta -Command &""{"
    Let psCmdTxt(1) = "Start-Sleep -Milliseconds " & pSendDelayMilliSec & ";"
    Let psCmdTxt(2) = "Add-Type -AssemblyName System.Windows.Forms;"
    Let psCmdTxt(3) = "[System.Windows.Forms.SendKeys]::SendWait('" & iKeys & "')"
    Let psCmdTxt(4) = "}"

    Call VBA.Shell(VBA.Join(psCmdTxt, ""), vbHide)
End Sub

経緯

  1. あるプログラムの操作を自動化しようと考えた。
  2. 該当のプログラムはCOMオブジェクトとして操作可能なため、自分の慣れもあってVBAを使うことにする。
  3. 大部分の処理が出来た時点で、一部操作がCOM側から操作不可能なことが判明(確認漏れ)。
  4. 幸いOfficeのExecuteMsoに相当するものが存在したので、GUIを表示させて、キーボード操作で対応することにする。
  5. ExecuteMso相当コマンドが、GUI表示中は呼び出し元の動作を停止する仕様であることが判明。
  6. 非同期でSendKeysすれば良いのでは?(上記のコード)
  7. 「呼び出し元」の動作を停止するので、PowerShellから非同期でExecuteMso相当をすれば良いじゃん(最終結論)。

まとめ

PowerShellを使えばコマンドライン実行でも、COMオブジェクト操作・.NETライブラリの使用が可能。
あまり常用すべきでは無いと思うが、可能であることを知っておくのは悪くないと思う。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3