脱・マクロ記録!FSOとDictionaryを操り、設定ファイルを自動更新する「パッチ適用エンジン」の構築
こんにちは。自動化の世界へようこそ。
「マクロの記録」を使って、ボタン一つでExcelが動く。それは素晴らしい第一歩です。しかし、あなたがもし「システムの設定ファイルを書き換えたい」「大量の構成ファイルを一括で、しかも安全に更新したい」と願うなら、その先にある「ロジックによる制御」の領域へ踏み出す必要があります。
今日、私たちが挑戦するのは、単なるファイル操作ではありません。
「差分定義ファイル(パッチ)を読み込み、ターゲットの設定ファイルを、バックアップを取りながら安全に書き換える」という、インフラ自動化の極めて実践的なエンジンの構築です。
このコードを理解したとき、あなたは「記録された操作」をなぞるユーザーから、「仕組みを作る」エンジニアへと進化を遂げているはずですよ。
1. 戦略の設計図:なぜ「FSO」と「Dictionary」なのか?
このツールを作るにあたり、2つの強力な武器を手に取ります。
FileSystemObject (FSO) :ファイル操作の司令塔
FSOは、ファイルの存在確認、コピー、削除、そして中身の読み書きを司るオブジェクトです。しかし、プロフェッショナルはただ「開く」だけではありません。「ファイルが既に存在するか?」「書き込み権限はあるか?」といった生存確認を徹底することで、システムの暴走を防ぎます。
Scripting.Dictionary :メモリ上の高速な作業机
ここが今日一番の「知恵」です。
テキストファイルを1行ずつ読み込んで、特定の行を探して書き換える……。そんな非効率なことはしません。
まず、ターゲットとなる設定ファイルを丸ごと Dictionary(連想配列) という「メモリ上の作業机」に展開します。
- Key(鍵): 設定項目の名前(例:`ServerIP`)
- Item(値): その設定値(例:`192.168.1.1`)
Dictionaryを使えば、特定の項目を「一瞬で」見つけ出し、追加したり、消したり、書き換えたりできます。最後に、その机の上をファイルに書き戻す。これが最も高速で、かつロジックが明快な手法です。
2. パッチ形式の定義
今回は、以下のようなシンプルな「パッチファイル(`.patch`)」を解析する仕様にします。
| 命令 | 書式 | 内容 | ||
|---|---|---|---|---|
| ADD | `ADD | Key | Value` | 新しい設定を追加する |
| SET | `SET | Key | Value` | 既存の設定を更新する |
| DEL | `DEL | Key` | 設定を削除する |
3. 実装:簡易パッチ適用エンジン
それでは、魂を込めて書いたコードをご覧ください。このまま `.vbs` ファイルとして保存して動かすことができます。
' ==========================================================================
' Engine Name: Professional Patch Application Engine
' Description: FSO and Dictionaryを利用した設定ファイル自動更新ツール
' Author: Legend Architect
' ==========================================================================
Option Explicit
' --- メイン処理 ---
Sub Main()
Dim fso, patchFile, targetFile
' パスは環境に合わせて変更してください
patchFile = "config.patch"
targetFile = "settings.conf"
Set fso = CreateObject("Scripting.FileSystemObject")
' 1. 事前チェック
If Not fso.FileExists(patchFile) Then
MsgBox "エラー: パッチファイルが見つかりません。" & vbCrLf & patchFile, vbCritical
Exit Sub
End If
If Not fso.FileExists(targetFile) Then
MsgBox "エラー: ターゲットファイルが見つかりません。" & vbCrLf & targetFile, vbCritical
Exit Sub
End If
' 2. 安全のためのバックアップ作成
' 失敗した時に元の状態に戻せるよう、プロの現場では必須の工程です
On Error Resume Next
fso.CopyFile targetFile, targetFile & ".bak", True
If Err.Number <> 0 Then
MsgBox "エラー: バックアップの作成に失敗しました。書き込み権限を確認してください。", vbCritical
Exit Sub
End If
On Error GoTo 0
' 3. パッチ適用実行
If ApplyPatch(patchFile, targetFile) Then
MsgBox "パッチの適用が完了しました!" & vbCrLf & "バックアップ: " & targetFile & ".bak", vbInformation
Else
MsgBox "パッチの適用中にエラーが発生しました。", vbExclamation
End If
Set fso = Nothing
End Sub
' --- パッチ適用ロジック ---
Function ApplyPatch(strPatchPath, strTargetPath)
Dim fso, dict, ts, line, parts
Dim strLine, strKey, strValue, strCommand
Set fso = CreateObject("Scripting.FileSystemObject")
Set dict = CreateObject("Scripting.Dictionary")
ApplyPatch = False ' デフォルトは失敗
' --- STEP A: ターゲットファイルをDictionaryにロード ---
' 設定ファイルを「Key=Value」形式と想定して読み込みます
Set ts = fso.OpenTextFile(strTargetPath, 1) ' 1 = ForReading
Do Until ts.AtEndOfStream
strLine = Trim(ts.ReadLine)
If strLine <> "" And InStr(strLine, "=") > 0 Then
parts = Split(strLine, "=")
' KeyとValueを分離して格納
dict.Add Trim(parts(0)), Trim(parts(1))
End If
Loop
ts.Close
' --- STEP B: パッチファイルを解析してDictionaryを操作 ---
Set ts = fso.OpenTextFile(strPatchPath, 1)
Do Until ts.AtEndOfStream
strLine = Trim(ts.ReadLine)
If strLine <> "" Then
' 区切り文字 "|" で分割
parts = Split(strLine, "|")
strCommand = parts(0) ' ADD, SET, DEL
Select Case strCommand
Case "ADD"
strKey = Trim(parts(1))
strValue = Trim(parts(2))
If Not dict.Exists(strKey) Then
dict.Add strKey, strValue
End If
Case "SET"
strKey = Trim(parts(1))
strValue = Trim(parts(2))
If dict.Exists(strKey) Then
dict(strKey) = strValue
End If
Case "DEL"
strKey = Trim(parts(1))
If dict.Exists(strKey) Then
dict.Remove strKey
End If
End Select
End If
Loop
ts.Close
' --- STEP C: 更新されたDictionaryをファイルに書き戻す ---
' 一旦、既存のファイルを上書き(または新規作成)します
Set ts = fso.CreateTextFile(strTargetPath, True)
Dim k
For Each k In dict.Keys
ts.WriteLine k & "=" & dict(k)
Next
ts.Close
ApplyPatch = True ' すべて成功
Set dict = Nothing
Set fso = Nothing
End Function
' 実行
Main
4. ここがプロの分かれ道:陥りやすいエラーと回避策
このコードを動かして「あれ?」と思ったとき、あなたはエンジニアとして成長しています。以下の3点は、現場で必ず直面する壁です。
① ファイルの「掴み(ロック)」問題
`OpenTextFile` でファイルを開いたまま、同じファイルに対して `CreateTextFile` で書き込もうとすると、「書き込み禁止」のエラーが出ます。
解決策: 必ず `ts.Close` を呼び出し、ファイルへのアクセス権を解放してから次の操作に移る。これはオブジェクトのライフサイクル管理の基本です。
② エンコーディングの罠
VBScriptのFSOは、デフォルトでは「ANSI(Shift-JIS)」として動作します。もしターゲットファイルが「UTF-8」で保存されている場合、日本語が文字化けしたり、ファイル構造が壊れたりします。
解決策: システム全体の文字コードを確認するか、必要に応じてADODB.Streamオブジェクトを使用してUTF-8を扱う高度な手法を検討してください。
③ Dictionaryの「重複」エラー
`dict.Add` メソッドは、既に存在するKeyを追加しようとすると、即座にランタイムエラーを吐いて停止します。
解決策: `If Not dict.Exists(strKey) Then` を使い、存在確認を行ってから追加する。この「慎重さ」が、止まらないプログラムを作ります。
最後に
いかがでしたか?
単に「ファイルの中身を書き換える」という動作の裏側には、「データの持ち方(Dictionary)」「安全性の確保(Backup)」「解析のロジック(Parsing)」という、エンジニアリングの神髄が詰まっています。
このコードをベースに、例えば「削除した項目をログに残す機能」や「設定値のバリデーション(数値かどうかチェックする)機能」を追加してみてください。それが、あなた独自の「最強のツール」への道です。
一歩ずつ、確実に。次はもっと複雑な自動化の戦場で会いましょう!
