WshScriptのSendKeysメソッドを使う
ち~んw珍現象は続く
WshScriptのSendKeysメソッド
前回の
コチラの記事にid:imihito さんからコメントをいただいた。
そこでご紹介いただいたのは、コチラの方法。このうち、「WshShellのSendKeysをラップする」というやつを使わせていただくことにした。
要するに、バグがあることが分かっている方法を使うのを避けて、同じような機能を持つバグのないメソッドを使おうということ。極めて健全な対処法だと思う。
面白いなと思ったのが、
毎回CreateObjectすると負荷が大きくなるので、Static宣言+存在判定をしています。
という考え方。なるほど。Static変数をそういうふうに使うのか! VBAのStatic変数って、プロシージャ内でしか使えなくて、イマイチ使いどころが分からなかったんだよな。クラス変数みたいに使えたらいいのに。
ただ、ちょっと気になる記述が。
代わりにオブジェクトを破棄する方法が無くなるので、wshShellオブジェクトがメモリに残り続けます。
むむむ。イマイチVBAのガベージコレクションの動作がよく分からないし、素人の悲しさ、メモリ関係もよく分かっとらんので、あまり気にしたこともないのだが、こうはっきり書いてあると、「メモリに残り続けるってのもマズいのかなあ」とかビビってしまう。
まあ、オブジェクトの破棄については、素人の浅知恵を後ほど披露するとして、ちょっとやってみた。
WshScriptのSendKeysメソッド呼び出し用プロシージャ
コチラのコードをちょっとだけ改造する。
リスト1 標準モジュール
Public Sub callWshScriptSendKeys(ByVal wsKeys As String, _ Optional ByVal wsWait As Boolean, _ Optional ByVal isFinal As Boolean) '……(1)' Static objWshShell As Object If isFinal Then Set objWshShell = Nothing: Exit Sub '……(2)' If objWshShell Is Nothing Then Set objWshShell = CreateObject("Wscript.Shell") Call objWshShell.SendKeys(wsKeys, wsWait) End Sub
元のコードに付け加えたのは(1)の引数リストと(2)のコードだけ。
(1)の
Public Sub callWshScriptSendKeys(ByVal wsKeys As String, _ Optional ByVal wsWait As Boolean, _ Optional ByVal isFinal As Boolean)
では、省略可能な第3引数isFinalを設定している。
(2)の
If isFinal Then Set objWshShell = Nothing: Exit Sub
では、第3引数のisFinalがTrueだったら、objWshShellをNothingにしてそのままプロシージャを抜けるようにした。
全体の処理の最後に、第3引数isFinalをTrueにしてこのプロシージャを呼び出すことで、オブジェクトを破棄できると考えた。これが、素人の浅知恵の部分w
まあ、そのために第1引数wsKeysにアテ馬のように文字列を与えないと呼び出せない(もちろん、""でいいんだけれど)ので、ブサイクといえばブサイクですけどw
SendKeysメソッド呼び出し回りの改造
VBAのApplication.SendKeysメソッドの使用をやめ、全面的にWshScriptのSendKeysメソッドに置き換える。
具体的には、
このときのリスト1を、リスト1で作成したプロシージャを呼び出す形に書き換える。
リスト2 標準モジュール
Public Sub cutText() Call callWshScriptSendKeys("^X") DoEvents End Sub Public Sub copyText() Call callWshScriptSendKeys("^C") DoEvents End Sub Public Sub pasteText() Call callWshScriptSendKeys("^V") DoEvents End Sub Public Sub selectAll() Call callWshScriptSendKeys("^A") DoEvents End Sub
これで準備万端のはず。
実行結果
伝わりにくいと思いますが、NumLockがオンになっているので、数字の入力ができることを表現した画像ですw
この状態で、
右クリックして、「貼り付け」をクリック。
おおっ! 無事に貼り付けできたぞ!
今度は、「全て選択」だっ!
ガッ……!?
ど、どういうことやねん???
今度は「切り取り」をクリック!
ガッ……!?
な、何が起こっているんだーーーーッ!?
んで、気色悪いのが、
OSDにNumLockオン、オフの表示が出るのが不規則
だということ。右クリックメニューを使ったときに、出たり出なかったりする。んで、「NUM LOCK OFF」ばっかり連続で出るかと思ったら、急に「NUM LOCK ON」に変わったり、わけが分からない。
で、途方に暮れかけているときに気づいたのが、
OSDのオン、オフ表示に関係なく、NumLockの状態は変化していない
という、さらにわけの分からない事実。
OSDに「NUM LOCK OFF」と表示された後でも、こんなふうに普通にテンキーで数字が入力できる。
私のノートPCに限った現象だと思う(デスクトップはキーボードのLEDの点灯でNumLockの状態を知らせる仕組み)けれど、気色悪いなあ。
おわりに
id:imihito さん、ありがとうございました。