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