【実務・中級編】【独自構文設定ファイルパース】JSON/INI以外のKeyValue形式テキストを高速解析する自作設定ファイル読み込みモジュール – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptを極める:独自設定ファイル解析の「高速・堅牢」アーキテクチャ

世の中にはJSONやXMLといった構造化データのライブラリが溢れている。だが、現場の自動化ツール開発において、我々が直面するのは「もっと単純で、非エンジニアでも書き換え可能な設定ファイル」という要求だ。

「とりあえず `Split` 関数で分割すればいいだろう」という安易な実装は、今すぐ捨てろ。その場しのぎのパース処理は、コメント行の混入や、値の中に含まれる区切り文字(`=`や`:`)によって容易に崩壊する。

今日は、VBScriptの限界を知り尽くした私が、「高速・堅牢・保守性」を両立させた設定ファイル読み込みモジュールの設計思想を授ける。

—

1. なぜ「単純な分割」が地雷なのか

初心者が書くコードは、往々にしてこうなる。
`parts = Split(line, “=”)`
これでは、値の中に「=」が含まれていた場合、後半が切り捨てられる。また、前後の空白トリミングを忘れて `If` 文で死ぬ未来が見える。

我々が目指すべきは、「入力の揺れを許容し、かつエラーを確実に握りつぶさない」パーサーだ。

—

2. 堅牢なパースエンジンの設計指針

1. 正規化の徹底: 行のトリミングはもちろん、コメント `#` や `;` 以降の文字列は、パースの初期段階で完全に除去する。
2. Dictionaryオブジェクトの活用: 検索コストを $O(1)$ に保つ。
3. ストリーム処理: ファイル全体をメモリにロードするのではなく、1行ずつ読み込むことで、巨大な設定ファイルでも低メモリ消費を実現する。

—

3. プロダクション品質のコード:`ConfigLoader` クラス

このコードは、そのままモジュールとして組み込めるように設計している。

‘ — ConfigLoader.vbs —
Class ConfigLoader
Private dict

Private Sub Class_Initialize()
Set dict = CreateObject(“Scripting.Dictionary”)
dict.CompareMode = 1 ‘ テキスト比較(大文字小文字を区別しない)
End Sub

Public Function LoadFromFile(filePath)
Dim fso, ts, line, delimiterPos, key, value
Set fso = CreateObject(“Scripting.FileSystemObject”)

If Not fso.FileExists(filePath) Then Err.Raise 53, , “設定ファイルが見つかりません: ” & filePath

Set ts = fso.OpenTextFile(filePath, 1) ‘ 1 = ForReading

Do Until ts.AtEndOfStream
line = Trim(ts.ReadLine)

‘ コメント行・空行のスキップ
If Len(line) > 0 And Left(line, 1) <> “#” And Left(line, 1) <> “;” Then
‘ コメントのインライン除去(セミコロンまたは#以降を削除)
line = Split(line, “#”)(0)
line = Split(line, “;”)(0)

‘ 区切り文字の探索(最初の = または : を基準にする)
delimiterPos = InStr(line, “=”)
If delimiterPos = 0 Then delimiterPos = InStr(line, “:”)

If delimiterPos > 1 Then
key = Trim(Left(line, delimiterPos – 1))
value = Trim(Mid(line, delimiterPos + 1))

If Not dict.Exists(key) Then dict.Add key, value
End If
End If
Loop
ts.Close
Set LoadFromFile = dict
End Function
End Class

—

4. この設計が「プロ」である理由

① `CompareMode = 1` の魔法

`Scripting.Dictionary` の `CompareMode` を `1` (TextCompare) に設定している点が重要だ。これにより、設定ファイル内で `ServerName` と `servername` を同一キーとして扱うことができる。現場の人間が書く設定の「揺れ」を、コード側で吸収する設計だ。

② 先頭の区切り文字だけを認識する

`Split` ではなく `InStr` を採用した理由がこれだ。`Value = “path=C:\data”` のようなケースでも、最初の `=` で正確に分割するため、設定値の中に区切り文字が含まれていても問題なく解析できる。

③ エラーハンドリングの意識

`Err.Raise` を適切に配置している。自動化ツールにおいて「設定ファイルがない」という事態は致命的だ。曖昧な動作をさせず、即座に例外を投げてプロセスを停止させるのが、長期的には運用コストを下げる。

—

5. 運用上の注意点

このモジュールを実務で使う際、以下の点だけは守ってほしい。

  • 文字コード: `Scripting.FileSystemObject` はデフォルトで `ASCII` 読み込みを行う。UTF-8(BOMなし)の設定ファイルを扱う場合は、`ADODB.Stream` を使用して `Charset = “utf-8″` で読み込む別実装が必要になる。
  • 権限の分離: 設定ファイルは読み取り専用で運用すること。書き込みを伴うツールを作る場合は、設定ファイルを動的に書き換えるのではなく、データベースやレジストリと役割を明確に分けるべきだ。

VBScriptは古い言語かもしれない。だが、その特性を理解し、堅牢なクラス設計を施せば、Windows環境における最強の自動化ツールに化ける。

コードは、ただ動けばいいのではない。「次に触る人間(半年後の自分を含む)が絶望しない」ために書くものだ。健闘を祈る。

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