SendKeysの「運頼み」から卒業せよ:レガシーGUI自動操作を掌握する極限の知見
APIが存在しない。ドキュメントは紛失。そんな「負の遺産」とも言えるレガシーアプリを相手にする際、多くのエンジニアが `WScript.Shell` の `SendKeys` に頼り、そしてその不安定さに絶望します。
「キーが入力されたり、されなかったりする」「タイミングによって処理が止まる」。これらは単なる運の悪さではなく、OSのメッセージキューとスクリプト実行速度の乖離を理解していない設計ミスです。
今日は、SendKeysを「おもちゃ」から「堅牢な自動化ツール」へと昇華させるための、プロのアーキテクチャを伝授します。
—
1. なぜ「固定ウェイト」は失敗するのか
多くの初学者は `WScript.Sleep 1000` のような固定待機時間を挿入します。しかし、これは最悪の設計です。
- 処理が遅いとき: アプリの反応が遅れるとキー送信が空振りする。
- 処理が速いとき: 無駄な待ち時間で全体の実行時間が肥大化する。
真の自動化エンジニアは、「状態の確定(Ready)」を待つ設計を行います。SendKeysを叩く前に、アプリがその入力を受け入れ可能な状態にあるかを、ループ処理で監視するのです。
—
2. 堅牢なSendKeysラッパーの設計思想
以下のコードは、単にキーを送るだけでなく、「ウィンドウのフォーカス確保」と「確実なキー送信」を担保するためのプロダクションコードです。
‘ WSHによる堅牢なGUI制御モジュール
Option Explicit
Dim objShell
Set objShell = CreateObject(“WScript.Shell”)
‘ メイン処理
Sub SendKeysRobust(targetTitle, keysToSend, waitTime)
‘ 1. アプリを最前面に持ってくる
If objShell.AppActivate(targetTitle) Then
WScript.Sleep 500 ‘ フォーカス遷移の安定化待ち
‘ 2. 入力
objShell.SendKeys keysToSend
‘ 3. 後処理としての待機
WScript.Sleep waitTime
Else
‘ フォーカス取得失敗時は即座に例外処理
Err.Raise 1, “Automation”, “Target Window [” & targetTitle & “] not found.”
End If
End Sub
‘ 使用例
On Error Resume Next
SendKeysRobust “基幹システム – [受注入力]”, “12345{ENTER}”, 200
If Err.Number <> 0 Then
WScript.Echo “エラー発生: ” & Err.Description
End If
—
3. 実務で「詰まない」ための3つの極意
① AppActivateの過信を捨てる
`AppActivate` はプロセスIDではなく「タイトルの一部」でウィンドウを検索します。複数の同名ウィンドウがある場合、意図しないアプリを操作するリスクがあります。可能な限り、タイトルを一意に特定できる文字列を指定してください。
② 入力バッファのフラッシュを意識する
連続して `SendKeys` を叩くと、バッファが溢れて文字化けや取りこぼしが発生します。複雑な文字列を入力する場合は、一度に送るのではなく、`{PAUSE}` を挟むか、クリップボード経由での貼り付け(`^v`)を検討してください。クリップボード経由の方が圧倒的に高速かつ正確です。
③ データベースとの連携は「書き込み」のタイミングに注意
自動入力した後にデータベースへ書き出す際、「入力確定(Enterキー)」がOSのメッセージキューで処理される前に次のステップへ進むと、データが欠落します。
確実にキーが届いたかを確認するには、SendKeys後の画面変化(特定のピクセル色の変化や、ウィンドウのタイトル変化)を監視するループを追加するのが、中級者から上級者へのステップアップです。
—
4. アーキテクトからの助言:引き際を見極める
SendKeysは、あくまで「最終手段」です。以下の順序で代替案を検討するのが、プロとしての誠実さです。
1. API/CLI: アプリがコマンドライン引数やCOMオブジェクトを公開していないか?
2. データベース直叩き: アプリを通さず直接DBを更新できないか?
3. UI Automation: Windows 10/11環境であれば、PowerShell経由で `UIAutomation` を使う方が、SendKeysよりも遥かに堅牢です。
それでもSendKeysを使う必要があるなら、「エラーハンドリングを完璧に書くこと」。何が起きた時に処理を停止し、管理者に何を通知するか。その「失敗の設計」こそが、業務自動化ツールを「動くゴミ」から「信頼できる資産」へと変えるのです。
さあ、コードを書いてください。そして、レガシーなシステムをあなたの手でスマートに支配しましょう。
