【実務・中級編】【実務中級者向け】2つの設定テキスト(INI/CONF)をFSOで比較し、不足しているキーと値だけをマージする差分統合VBS – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptを掌握せよ:FSOを用いた「設定ファイル差分統合」の極意

業務自動化の現場において、設定ファイル(INIやCONF)の更新は最も神経を使う作業の一つだ。「新しい設定項目が追加されたが、既存のカスタマイズ設定を壊さずに統合してほしい」という要求は、手作業で行えば必ずヒューマンエラーを誘発する。

今日伝授するのは、FSO(FileSystemObject)を駆使し、「旧設定を汚さずに新設定の不足分だけを抽出・追記する」という、堅牢かつ洗練された差分統合ロジックだ。

—

1. なぜ「力技」が失敗するのか:設計の根本思想

多くの初級者が陥る罠は、ファイルを全行読み込んで配列に入れ、ループを二重に回して比較する実装だ。これではファイルサイズが肥大化した際、メモリ消費が爆発し、パフォーマンスが著しく低下する。

真のエンジニアが守るべき原則は以下の3つだ。

  • Dictionaryオブジェクトの活用: キーの検索速度はO(1)に近付けろ。配列の逐次探索(O(n))は、大規模データにおいて害悪でしかない。
  • ストリームの最小化: ファイルへの書き込みは一度に行え。何度も`OpenTextFile`を繰り返すのはI/O負荷を増大させる。
  • 不可逆操作の回避: 元ファイルを破壊してはならない。必ずバックアップを作成し、予期せぬクラッシュに備えるのが「プロ」の流儀だ。

—

2. 差分統合の実装:プロダクションコード

このスクリプトは、新旧2つのファイルを読み込み、`Dictionary`オブジェクトを使って「キーの差異」を特定し、不足分のみを旧ファイルへ追記する。

Option Explicit

‘ — 設定エリア —
Const OLD_FILE = “C:\Config\settings.old.ini”
Const NEW_FILE = “C:\Config\settings.new.ini”
Const BACKUP_FILE = “C:\Config\settings.bak”

‘ — メイン処理 —
Call MergeConfigFiles(OLD_FILE, NEW_FILE)

Sub MergeConfigFiles(oldPath, newPath)
Dim fso, dictOld, dictNew, key, line
Set fso = CreateObject(“Scripting.FileSystemObject”)

‘ バックアップ作成(鉄則)
fso.CopyFile oldPath, BACKUP_FILE, True

Set dictOld = LoadFileToDict(fso, oldPath)
Set dictNew = LoadFileToDict(fso, newPath)

‘ 新しい設定にあって古い設定にないキーを特定し、追記する
Dim tsOut
Set tsOut = fso.OpenTextFile(oldPath, 8, False) ‘ 8 = ForAppending

For Each key In dictNew.Keys
If Not dictOld.Exists(key) Then
tsOut.WriteLine key & “=” & dictNew(key)
End If
Next

tsOut.Close
WScript.Echo “統合完了:設定の更新に成功しました。”
End Sub

‘ ファイルを読み込み、Dictionaryに格納する関数
Function LoadFileToDict(fso, filePath)
Dim ts, line, parts, dict
Set dict = CreateObject(“Scripting.Dictionary”)
Set ts = fso.OpenTextFile(filePath, 1) ‘ 1 = ForReading

Do Until ts.AtEndOfStream
line = Trim(ts.ReadLine)
‘ 空行やコメント行(;)を無視する堅牢なパース
If line <> “” And Left(line, 1) <> “;” Then
If InStr(line, “=”) > 0 Then
parts = Split(line, “=”, 2)
dict(Trim(parts(0))) = Trim(parts(1))
End If
End If
Loop

ts.Close
Set LoadFileToDict = dict
End Function

—

3. 実務で「バグらせない」ための3つの知見

① コメント行と空行のハンドリング

単純な`Split`関数は、値の中に`=`が含まれている場合や、セミコロン`;`で始まるコメント行を考慮していない。上記の関数では、`InStr`で存在確認を行い、かつ`Split`の第3引数に`2`を指定することで、値側に含まれるイコールまで分割しないよう制御している。

② 文字コードの落とし穴

VBScriptの`OpenTextFile`は、デフォルトでシステム標準のエンコーディング(日本語環境ならShift-JIS)を使用する。もしUTF-8の設定ファイルを取り扱う必要がある場合は、`ADODB.Stream`オブジェクトへ切り替えるのが定石だ。FSO単体でのUTF-8制御は限界があることを忘れてはならない。

③ 排他制御という視点

もしこのスクリプトを複数人が同時に実行する環境で使うなら、ファイルロックの考慮が必須だ。`fso.OpenTextFile`が失敗した際にエラーをトラップする`On Error Resume Next`を適切に配置し、誰かが設定ファイルを編集中であれば「現在使用中です」と明示的にメッセージを出す丁寧さが、後のトラブルシューティングを激減させる。

—

結びに:エンジニアの誇り

スクリプトを書くことは単なるコードの羅列ではない。「二度と手動で触らせない」という運用設計をシステムに落とし込むことだ。

今回のロジックはシンプルだが、Dictionaryによる高速な検索と、Appendモードによる安全な追記という、業務自動化の骨格を備えている。この基盤を理解すれば、INIファイルだけでなく、CSVやログの解析ツールへの応用も容易だろう。

さあ、このコードを武器に、無駄な手作業を現場から根絶してほしい。君のコードが、誰かの貴重な時間を救うことを期待している。

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