8
9

More than 5 years have passed since last update.

VBA.SendKeysでキーボードのロックが外れる現象への対策

Last updated at Posted at 2016-10-02

1. 現象

操作の自動化の最終手段であるSendKeysですが、VBAのSendKeysにはバグが存在します。

Misrosoftサポート
[BUG] 複数の SendKeys ステートメントが実行されると NumLock キーがオフになる

リンク先にあるように、VBAでSendeKeysステートメントを使用すると、NumLockなどが外れることがあります。

2. 対策:他のSendKeysを使用する

"Windows Script Host Object Model"の"WshShell"オブジェクト(ProgID:"WScript.Shell")のSendKeysステートメントでは上記の問題は発生しません。

WshShellのSendKeysをラップする

WshShellのSendKeysを使えば良い、といっても参照設定を追加するのも面倒だし、CreateObjectするのも面倒、ということでサブルーチン化したものがこちらです。

Public Sub wshSendKeys(Keys As String, Optional Wait As Boolean = False)
    'メモリ効率より動作速度を優先する場合
    Static wshShell As Object
    If wshShell Is Nothing Then Set wshShell = CreateObject("WScript.Shell")
    Call wshShell.SendKeys(Keys, Wait)
End Sub

毎回CreateObjectすると負荷が大きくなるので、Static宣言+存在判定をしています。
代わりにオブジェクトを破棄する方法が無くなるので、wshShellオブジェクトがメモリに残り続けます。

3. その他

AppActivate

WshShellのAppActivateもVBAのものと動作が異なるので状況によっては使い道があります。

具体的には、
VBAでは該当ウィンドウが存在しないときはエラーとなりますが、WshShellではAppActivateが成功したか、失敗したかがBooleanで戻ってきます。

力技

NumLock/CapsLockのオン・オフを取得する

にあるように、WordのApplicationオブジェクトからNumLockなど状態を取得できます。
これを使って、初期状態を保存しておき、VBA.SendKeys後に元に戻すという事もできなくもないです。

参考

8
9
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
8
9