【仕様書】VBA-PowerShell連携型 ハイブリッドRPA操作エンジン構築
1. システム概要・目的
VBA(親プロセス)からPowerShell 5.1(子プロセス)を標準入出力(JSON)で非同期制御し、
WebView2(Web自動化)および Win32/UIA(デスクトップ自動化)を高速かつ堅牢に実行するRPAエンジンを構築する。
2. 技術スタック & 動作環境
- 制御元: Excel VBA (VBA-JSON 2.3.1 ライブラリ使用)
- 実行エンジン: PowerShell 5.1 (STAモード)
- ブラウザ制御: Microsoft.Web.WebView2 (WinForms) + CDP (WebSocket / Port: 9222)
- デスクトップ制御: System.Windows.Automation (UIAutomation) + Win32 API
3. モジュール構成 (全9ファイル)
-
Ps_Engine_Core.ps1: 司令塔・ルーター・JSON受送信・イベントループ -
Lib-WebView2_Init.ps1: Form生成、WebView2非同期初期化、仮想タブ・ゴースト破棄管理 -
Lib-WebView2_Native.ps1: ExecuteScriptAsyncによるJS非同期実行ラッパー -
Lib-WebCDP.ps1: WebSocket直接通信による低レイテンシCDP操作 -
Lib-WebAction.ps1: DOM操作(Click, Input, Select, Fetchサイレントダウンロード) -
Lib-DesktopUIA.ps1: Win32/UIA操作(SendKeys, UiaAction, SafeSaveAs) -
Lib-WebSafeAction.ps1: Robust DOM(isVisible判定、自動スクロール、SafeClick) -
Lib-WebXPath.ps1: XPath正規化・document.evaluateによる多段iframe貫通操作 -
Lib-WebDebug.ps1: スクショ保存、HTML/CSVエクスポート、デバッグログ機能
4. 厳格なコーディング規約・命名ルール
- 変数命名:
- ローカル変数 / JS埋め込み用変数:
camelCase(例:$xpathEscaped) - パラメータ / グローバル変数:
PascalCase(例:$TimeoutSec) - システム設定定数:
大文字(例:$global:CONFIG)
- ローカル変数 / JS埋め込み用変数:
- 時間表記:
- 時間・間隔変数には必ず単位を接尾辞として明記(例:
TimeoutSec,PollIntervalMs)
- 時間・間隔変数には必ず単位を接尾辞として明記(例:
- 通信フラグ:
- VBAから文字列で受けるBooleanには
Flg接尾辞(例:[string]$IsDebugModeFlg)
- VBAから文字列で受けるBooleanには
- JS展開ルール:
- ヒアドキュメント(
@""@)に埋め込むPowerShell変数は必ず事前にエスケープしcamelCaseで埋め込むこと。
- ヒアドキュメント(
5. 通信プロトコル仕様 (IPC)
- 標準入力 (StdIn): JSONフォーマット
{"Command": "関数名", "Parameters": {...}} - 標準出力 (StdOut):
- 正常終了:
[RESULT]データ→[SUCCESS] - 異常終了:
[ERROR][関数名] [エラー種別]: メッセージ (詳細)
- 正常終了:
- 親プロセス監視 (Watchdog): 親PIDを監視し、親消失時はエンジンを自己強制終了 (
Stop-Process)
6. 特殊ノウハウ・現場の罠への対策要件
-
DOM探索:
Shadow DOM (open)および多段iframeを深層再帰探索するJSユーティリティ (deepQuerySelector,utilFindInFrames) を共通定義すること。 -
サイレントダウンロード: OSのダイアログに頼らず、
CoreWebView2.DownloadStartingでパスを固定し、JSのFetch API+new URL(src, location.href).hrefで絶対URL化して裏側で直接取得・完了待機すること。 -
PDF要素の揺らぎ:
embedタグはtype="application/pdf"属性が省略されるケースがあるため、embed[src*='.pdf']やembed単体にフォールバックして柔軟に捕捉すること。 -
UIフリーズ防止: ポーリングループやタスク待機時には必ず
[System.Windows.Forms.Application]::DoEvents()を呼び出し、UIスレッドを殺さないこと。
GITHUBに移動しました。