VBScriptを掌握する極限の知見:FSOとRegExpを融合させた「ワイルドカード」の真実
現場で遭遇する「レガシーの呪縛」。VBScriptにおいて、`FileSystemObject` (FSO) は強力だが、そのファイル走査能力はあまりに貧弱だ。特に、`.log` のような柔軟なワイルドカード検索を求められた際、多くのエンジニアは「愚直なループ」に逃げる。
だが、それはエンジニアとしての敗北だ。今回は、FSOの物理的なファイルアクセス能力と、`RegExp` オブジェクトの論理的なパターンマッチング能力を極限まで融合させ、パフォーマンスと保守性を両立させる「ワイルドカード疑似実装」の真髄を伝授する。
—
1. なぜ「愚直なループ」ではいけないのか
FSOの `GetFolder(path).Files` で取得したコレクションを、単に `If InStr(…)` や `Like` 演算子で絞り込む手法は、ファイル数が数千、数万と増大した瞬間にシステムを破綻させる。
メモリの肥大化を防ぎ、かつ複雑なパターン(`[0-9]{4}_.log` など)にも対応するには、「走査フェーズ」と「評価フェーズ」を明示的に分離するアーキテクチャが必要だ。
2. 実装の核心:RegExp 融合型スキャン
以下のコードは、単なる検索ではない。メモリ消費を最小限に抑え、パターンマッチングを高速化するための「クラス的アプローチ」を採用している。
‘ — 極限のファイル検索エンジン:PatternSearch —
Function FindFilesByPattern(strFolderPath, strPattern)
Dim fso, folder, file, regEx, colMatches
‘ オブジェクト生成を最小化するためにスコープを限定
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set regEx = New RegExp
‘ ワイルドカードを正規表現に変換(極めて重要)
‘ -> . , ? -> .
‘ 文字列の先頭から末尾までを保証するため ^ と $ を付与
regEx.Pattern = “^” & Replace(Replace(Replace(strPattern, “.”, “\.”), “”, “.”), “?”, “.”) & “$”
regEx.IgnoreCase = True ‘ Windowsファイルシステムに準拠
If Not fso.FolderExists(strFolderPath) Then Exit Function
Set folder = fso.GetFolder(strFolderPath)
‘ 結果格納用の配列(動的配列を最小限のリサイズで運用)
Dim results()
Dim count: count = 0
For Each file In folder.Files
If regEx.Test(file.Name) Then
ReDim Preserve results(count)
results(count) = file.Path
count = count + 1
End If
Next
FindFilesByPattern = results
‘ 明示的な解放:VBScriptのガベージコレクションを待たない
Set regEx = Nothing
Set folder = Nothing
Set fso = Nothing
End Function
3. シニアエンジニアが意識すべき「メモリの重み」
上記のコードで最も重要なのは、「オブジェクトの明示的解放」である。VBScriptは参照カウンタ方式を採用しているが、循環参照や長時間のプロセス滞留が発生すると、メモリリークの温床となる。
特に、`FileSystemObject` や `RegExp` をループ内でむやみに `CreateObject` してはならない。上記の実装では、関数のスコープ内で一度だけ生成し、処理終了後に直ちに `Nothing` を代入している。これは、限られたリソースで動くWindows環境における「礼儀」であり、安定したシステムを構築するための鉄則だ。
4. さらに高度なチューニング:パフォーマンスの最適化
もし、対象のディレクトリが数百万ファイルを超えるような環境であれば、上記のような「全件配列保持」はメモリ不足(Out of Memory)を招く。その場合は、「コールバック関数」の利用を検討せよ。
1. 関数に引数として「処理を行うための関数ポインタ」を渡す(VBScriptでは `ExecuteGlobal` や `Eval` を駆使する高度なテクニックが必要)。
2. あるいは、検索結果を配列ではなく、`Dictionary` オブジェクトに格納し、キーによる一意性を保証しつつインメモリで高速にアクセスする。
5. 結びに代えて
「VBScriptは古い」と言うのは簡単だ。だが、この「古くて枯れた技術」の中にこそ、システムの挙動を完全に制御し、OSの深層部までを見通すためのスキルが詰まっている。
`RegExp` を使ったワイルドカード実装は、単なる機能拡張ではない。それは、「柔軟性と堅牢性を両立させる」というアーキテクトの矜持そのものだ。
君たちが今日書くその数行のコードが、数年後の保守担当者の負担を劇的に減らす。それこそが、伝説のエンジニアの仕事である。
—
追記:レガシーなWindows Server環境で実行する場合、WMI経由の `Win32_LogicalFileSecuritySetting` などと組み合わせると、権限管理まで含めた高度なファイル操作が可能になる。機会があればまた触れるとしよう。
