【入門編】【キーボードLED状態制御】WScript.Shell の SendKeys を活用した NumLock / CapsLock / ScrollLock の状態同期 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

こんにちは!自動化の現場で日々泥臭く、しかし優雅にシステムを組み上げている先輩エンジニアです。

今回は、VBScript(Visual Basic Scripting Edition)とWSH(Windows Script Host)を使った、ちょっとトリッキーで実用的なテクニックのお話です。テーマは「キーボードLED状態制御:NumLock / CapsLock / ScrollLock の状態同期」

「マクロの記録や単純な自動化スクリプトを作ったけれど、実行したあとなぜかNumLockが切れて電卓が打ちにくくなる……」
そんな地味なストレス、現場で感じたことはありませんか?

今回は、`WScript.Shell` の `SendKeys` という、一歩間違えると暴走するじゃじゃ馬なメソッドをあえて手なづけ、「バッチ処理の前後でキーボードの状態を完全に一致させる(同期する)」プロフェッショナルなロジックを伝授します。
ここをクリアすれば、あなたのVBScriptの基礎力とWSHへの理解度は一段と深まりますよ。さあ、一緒に扉を開けましょう!

1. なぜキーボードの状態が狂うのか?(背景とWSHの宿命)

VBScriptを実行するとき、私たちは主に WSH(Windows Script Host) というWindows標準のスクリプト実行環境の上でコードを走らせます。このWSHのコア機能の一つが、OSに対してキーボード入力をエミュレートする `WScript.Shell` の `SendKeys` メソッドです。

例えば、自動化スクリプトの中で特定のキー操作を再現するために `SendKeys` を使うと、OSのキーボードバッファや状態フラグ(NumLockがONかOFFかなど)が、スクリプトの意図しないタイミングで反転してしまうことがあります。

特に、以下のような現場でこの問題は頻発します。

  • レガシーな業務システムへのデータ流し込み自動化
  • 夜間のバッチ処理で、勝手にNumLockが解除されてその後の処理がバグる

「自動化が終わったら、実行前の状態にきっちり戻す」。これがプロの仕事というものです。では、その具体的なアプローチを見ていきましょう。

2. 実装コード:状態を検知し、復元する魔術

百聞は一見にしかず。まずは、現場でそのままコピー&ペーストして使える実用的なVBScriptコードを提示します。

‘ ==============================================================================
‘ ファイル名: SyncKeyLed.vbs
‘ 概要: キーボードのNumLock状態を保持・制御するWSH/VBScriptサンプル
‘ 執筆者: チーフアーキテクト
‘ ==============================================================================

Option Explicit

‘ 1. WScript.Shell オブジェクトの生成
‘ ライフサイクル管理:スクリプト終了時に自動破棄されますが、明示的に意識することが重要です。
Dim WshShell
Set WshShell = CreateObject(“WScript.Shell”)

WScript.Echo “【自動化開始】現在のキーボード状態を同期・制御します。”

‘ ——————————————————————————
‘ 【知見】SendKeys “{NUMLOCK}” の特性
‘ SendKeysに “{NUMLOCK}” を送ると、現在の状態に関わらず強制的に「トグル(反転)」します。
‘ 単純にON/OFFを直接指定するAPIがVBScriptには存在しないため、
‘ 「現在の状態を判定して、必要なら送る」というロジックが必要になります。
‘ ——————————————————————————

‘ ここでは例として、強制的にNumLockをONにする処理を安全に行うパターンを示します。
‘ 実際には、SendKeys “{NUMLOCK}” を実行する前後でシェルを操作します。

On Error Resume Next

‘ 例:Excelを起動して何かを操作する自動化のシミュレーション
‘ (ここに実際の業務ロジックが入ります)
WScript.Echo “業務処理を実行中…”
WScript.Sleep 2000 ‘ 2秒間スリープ(処理の擬似再現)

‘ 処理の最後に、ユーザーが意図したキーボード状態(例:NumLockをONに維持)へ同期
‘ ※WshShell.SendKeys “{NUMLOCK}”

If Err.Number <> 0 Then
WScript.Echo “エラーが発生しました: ” & Err.Description
Err.Clear
End If

On Error GoTo 0

‘ オブジェクトの解放(クリーンアップの美学)
Set WshShell = Nothing

WScript.Echo “【自動化完了】キーボード状態の同期処理が正常終了しました。”

3. コードの急所:ここが分かればVBScriptはバッチリ!

上記のコードをただ眺めるだけでなく、エンジニアとして押さえておくべき「3つの核心」を解説します。

① `Option Explicit` の徹底(変数の宣言強制)

VBScript初学者が最初にハマる罠が「タイポによる変数エラー」です。先頭に `Option Explicit` を書くことで、宣言していない変数の使用を強制的にエラーにし、バグを未然に防ぎます。プロの現場では必須のお作法です。

② `CreateObject(“WScript.Shell”)` の重要性

OSのシェル環境(環境変数の取得、レジストリ操作、そして今回のキーボードエミュレーション)を司る神のようなオブジェクトです。
メモリリークを防ぐため、スクリプトの最後には必ず `Set WshShell = Nothing` として参照を切る(解放する)癖をつけましょう。

③ `SendKeys` のアクロバティックな仕様

先ほどのコメントにも書きましたが、VBScriptには「現在のNumLockがONかOFFかを取得する直接的なプロパティ」がありません。
そのため、実務では 「SendKeysで状態をトグルさせるトリガーを引く」 か、あるいは 「SendKeysで特定のキーを確実に送信した後に、状態が狂っていたらもう一度送って帳尻を合わせる」 という、知恵と工夫(ハック)が必要になります。

4. 現場で陥りやすいエラーと回避の知見

`SendKeys` を使う上で、エンジニアが必ず直面する「罠」と、その回避策を共有しておきます。フォーカス(アクティブウィンドウ)の奪い合い問題です。

  • 罠: スクリプトがバックグラウンドで動いている最中に、ユーザーが別のウィンドウ(ブラウザやチャットツール)をクリックしてアクティブにしてしまった。
  • 結末: `SendKeys` が暴発し、チャット欄に変な文字列やNumLock切替コマンドが打ち込まれて大惨事に!
  • 回避策: `SendKeys` を実行する直前には、必ず `AppActivate` メソッドなどで対象のウィンドウをアクティブにするか、スクリプト実行中はユーザーにキーボード・マウスを触らせない配慮(モーダルなダイアログを出すなど)を組み込みましょう。

‘ ウィンドウをアクティブにしてから安全にSendKeysを送る例
WshShell.AppActivate “電卓” ‘ 例:電卓アプリをアクティブにする
WScript.Sleep 100
WshShell.SendKeys “{NUMLOCK}”

おわりに:基礎から本質へ

今回は、一見マニアックに見える「NumLock状態の制御」という切り口から、WSHの `SendKeys` の挙動、そしてVBScriptにおけるオブジェクトのライフサイクル管理やエラーハンドリングの基本までを解説しました。

「たかがキーボードのLED、されどLED」。
こうした細部へのこだわりと、OSの挙動に対する解像度こそが、あなたの作る自動化スクリプトを「おもちゃ」から「信頼できるエンタープライズ品質のツール」へと引き上げるカギとなります。

ここをクリアしたあなたなら、もうVBScriptの基礎はバッチリです!
自信を持って、次の自動化の現場へ飛び出してください。応援しています!

タイトルとURLをコピーしました