VBScriptを掌握せよ:VBA資産を「無改造」で再利用する動的ローダー設計論
業務自動化の現場で、私たちは常に「二重管理」の悪夢に悩まされる。Excelマクロで作り込んだ計算ロジックや業務バリデーションを、なぜVBScript環境(WSH)で使い回すためにわざわざ書き写さなければならないのか?
VBAとVBScriptは兄弟だが、血筋は同じではない。しかし、`ExecuteGlobal`という禁断の果実を正しく制御できれば、既存の`.bas`ファイルを物理的にそのまま読み込み、WSH環境で稼働させることは可能だ。
今日は、場当たり的なスクリプト作成を卒業し、プロフェッショナルとして「資産」を最大限に活かすアーキテクチャを伝授する。
—
1. なぜ「そのまま読み込む」ことが難しいのか
VBAの`.bas`ファイルには、VBScriptが解釈できない構文が山ほど含まれている。
- `Public Sub/Function` の型指定(As Stringなど)
- `Option Explicit` 以外のコンパイルオプション
- VBA専用のオブジェクトライブラリ参照
これらを放置して`ExecuteGlobal`に放り込めば、当然ながらスクリプトは沈黙する。我々が構築すべきは、「VBAコードのノイズをリアルタイムにフィルタリングして実行時メモリに展開するローダー」だ。
—
2. 堅牢な「VBA互換ローダー」の実装
以下のコードは、単にファイルを読み込むだけではない。VBScriptが解釈できない「型定義」や「Attribute」を動的に除去し、クリーンな状態でメモリにロードするプロトタイプだ。
‘ VbaBridgeLoader.vbs
Option Explicit
‘ 既存のVBAモジュールを動的に読み込むローダー
Function LoadVbaModule(strFilePath)
Dim fso, file, strContent
Set fso = CreateObject(“Scripting.FileSystemObject”)
If Not fso.FileExists(strFilePath) Then
Err.Raise 53, , “モジュールファイルが見つかりません: ” & strFilePath
End If
Set file = fso.OpenTextFile(strFilePath, 1)
strContent = file.ReadAll
file.Close
‘ — プロダクション向けのフィルタリング処理 —
‘ 1. VBA特有の「Attribute」行を削除
strContent = RegExReplace(strContent, “Attribute\s+VB_.?\n”, “”)
‘ 2. 「As 型名」を削除(VBScriptは変数の型指定を許容しない)
strContent = RegExReplace(strContent, “As\s+[A-Za-z0-9_]+”, “”)
‘ 3. 「Public/Private」を削除(全てグローバルスコープとして扱う)
strContent = RegExReplace(strContent, “(Public|Private)\s+”, “”)
‘ 実行時メモリへ展開
On Error Resume Next
ExecuteGlobal strContent
If Err.Number <> 0 Then
WScript.Echo “構文解析エラーが発生しました: ” & Err.Description
WScript.Quit 1
End If
On Error Goto 0
End Function
‘ 正規表現による置換ヘルパー
Function RegExReplace(strSource, strPattern, strReplace)
Dim re
Set re = CreateObject(“VBScript.RegExp”)
re.Global = True
re.IgnoreCase = True
re.Pattern = strPattern
RegExReplace = re.Replace(strSource, strReplace)
End Function
—
3. 実務で生き残るための「3つの鉄則」
① 「型」への執着を捨てる
VBAで`As String`や`As Long`と書いている箇所は、VBScriptでは単なる「構文エラー」だ。ローダーで全て除去する必要がある。もし「どうしても型が必要なライブラリ」がある場合は、それはVBScriptで動かすべきではない。COMオブジェクト(DLL)としてビルドし直すのがエンジニアの矜持だ。
② ファイルパスと権限の管理
FileSystemObjectは強力だが、ネットワークドライブ上の`.bas`ファイルを読み込む際は注意が必要だ。実行権限がない場所からのロードは、ランタイムエラー以前にセキュリティポリシーで弾かれる。必ずローカル、または許可されたUNCパスに配置せよ。
③ デバッグの難易度を考慮する
`ExecuteGlobal`で読み込んだコードは、実行時エラーが発生しても「何行目か」を正確に特定するのが困難になる。
- 対策: 開発時は個別のファイルとしてテストし、結合環境でのみローダーを通すCI(継続的インテグレーション)的な思考を持つこと。
—
結論:なぜこの設計なのか
「コードをコピペして修正し、二つのファイルをメンテナンスする」。これは自動化エンジニアとしては最悪の手法だ。
今回提示したローダーは、「ソースコードの真実を一つにする(Single Source of Truth)」ための第一歩だ。VBAの資産をそのままVBScriptで動かすことは、単なる互換性の問題ではなく、保守コストを劇的に下げるための戦略的決断である。
さあ、君のプロジェクトにある眠れる`.bas`ファイルを、今すぐWSHの世界で再覚醒させてみろ。それが、技術で業務を変えるということだ。
