こんにちは!エンジニアリングの世界へようこそ。
マクロの記録ボタンを押すだけの世界から一歩抜け出し、「自分の手でシステムをコントロールしたい」と思えるようになったあなたなら、きっと今日のテーマにワクワクするはずです。
今回は、外部の便利なライブラリやツールを一切使わず、Windows標準のVBScriptとFSO(FileSystemObject)だけで、2つのテキストファイルの差分(追加・変更された行)を綺麗に抽出する「実務で使えるDiffツール」の作り方を解説します。
「社内の設定ファイルの変更履歴を追いたい」「膨大なマスターデータの差分だけをサクッと抜き出したい」……そんな現場の泥臭い課題を、VBScriptの渋い機能でスマートに解決していきましょう。ここをクリアすれば、ファイル操作の基本はもうバッチリですよ!
—
なぜFSOなのか? VBScriptが現場で愛され続ける理由
業務を自動化するツールはPythonやPowerShellなど華やかな言語がたくさんありますが、Windows環境においてVBScriptには圧倒的なアドバンテージがあります。
1. 「何もインストールしなくていい」: メモ帳さえあれば、明日からでも全Windows端末で動く。
2. 「環境に依存しない」: Pythonのバージョン違いやライブラリの依存関係に悩まされない。
3. 「FSOの破壊力」: `Scripting.FileSystemObject`さえあれば、ファイルやフォルダの作成・読み書き・走査が自由自在。
特にFSOは、OSのファイルシステムを操作するためのVBScriptにおける「最強の右腕」です。今回はこのFSOを使って、新旧のテキストファイルを効率よくメモリ上に展開し、差分を炙り出していきます。
—
差分抽出のアルゴリズム(全体像)
今回のDiffツールは、単純に上から順に見比べるだけではありません。実務でよくある「行の追加」や「変更」に対応するため、以下のような戦略をとります。
1. 旧マスターの全行を読み込み、「辞書オブジェクト(Dictionary)」にキーとして登録する。
2. 新マスターを1行ずつ読み込み、「旧マスターの辞書にその行が存在するか?」を高速チェックする。
3. 存在しなければ、それは「追加・変更された行(差分)」とみなして、新規のログファイルに書き出す。
この「Dictionaryオブジェクト」を使うのがポイントです。全行を総当たりで比較するとファイルが大きい場合に処理が重くなりますが、Dictionaryを使えば一瞬で存在チェック(O(1)の計算量)ができます。
—
実装コード:実務仕様 差分抽出スクリプト
以下のコードをコピーして、メモ帳に貼り付け、拡張子を `.vbs` (例: `diff_checker.vbs`)として保存してください。
‘ =================================================================0
‘ ファイル名: diff_checker.vbs
‘ 概要: 新旧のテキストファイルを比較し、差分行のみを抽出する実務向けDiffツール
‘ 著者: チーフアーキテクト
‘ =================================================================0
Option Explicit
‘ 定数の定義
Const ForReading = 1
Const ForWriting = 2
Const TriStateUseDefault = -2
‘ メイン処理の実行
Call Main()
Sub Main()
Dim fso, dictOld, fileNew, fileLog
Dim pathOld, pathNew, pathLog
Dim strLine, diffCount
‘ ファイルパスの設定(同一フォルダ内にある前提)
pathOld = “old_master.txt”
pathNew = “new_master.txt”
pathLog = “diff_result.log”
‘ FSOのインスタンス化(ここからファイル操作の魔法が始まります)
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ 前提チェック:旧・新マスターが存在するか
If Not fso.FileExists(pathOld) Then
MsgBox “旧マスターファイルが見つかりません: ” & pathOld, vbCritical, “エラー”
Exit Sub
End If
If Not fso.FileExists(pathNew) Then
MsgBox “新マスターファイルが見つかりません: ” & pathNew, vbCritical, “エラー”
Exit Sub
End If
WScript.Echo “差分抽出処理を開始します…”
‘ 1. 旧マスターのデータを辞書(Dictionary)にロード
Set dictOld = CreateObject(“Scripting.Dictionary”)
Dim tsOld
Set tsOld = fso.OpenTextFile(pathOld, ForReading, False, TriStateUseDefault)
Do Until tsOld.AtEndOfStream
strLine = Trim(tsOld.ReadLine)
‘ 空行はスキップするなどの実務的な調整(必要に応じてコメントアウト解除)
If strLine <> “” Then
‘ キーとして登録(重複は上書きされるが今回は存在有無のチェック用)
If Not dictOld.Exists(strLine) Then
dictOld.Add strLine, True
End If
End If
Loop
tsOld.Close
‘ 2. 新マスターを読み込み、旧マスターにない行(差分)をログに出力
Set fileLog = fso.CreateTextFile(pathLog, True, False) ‘ True = 上書き作成
Set fileNew = fso.OpenTextFile(pathNew, ForReading, False, TriStateUseDefault)
diffCount = 0
fileLog.WriteLine “=== 差分抽出ログ (” & Now & “) ===”
Do Until fileNew.AtEndOfStream
strLine = Trim(fileNew.ReadLine)
If strLine <> “” Then
‘ 旧マスターの辞書に存在しない場合、それは「差分」である
If Not dictOld.Exists(strLine) Then
fileLog.WriteLine strLine
diffCount = diffCount + 1
End If
End If
Loop
fileNew.Close
fileLog.Close
‘ 3. 後片付けと結果通知
Set dictOld = Nothing
Set fso = Nothing
WScript.Echo “処理が完了しました。” & vbCrLf & _
“検出された差分行数: ” & diffCount & ” 行” & vbCrLf & _
“出力ファイル: ” & pathLog
End Sub
—
コードの深掘り解説:ここがVBScriptを極めるポイント
初学者のうちにつまづきやすいポイントや、プロのエンジニアが仕込んだ「知見」をいくつか解説します。
1. `Option Explicit` はエンジニアの命綱
コードの先頭にあるこの宣言、実はめちゃくちゃ重要です。これを書いておくと、変数名義のタイポ(誤字)をしたときにVBScriptが即座にエラーで止めてくれます。これがないと、変数のスペルミスで「データが消えた!動かない!」という深夜の絶望を味わうことになります。必ず書く癖をつけましょう。
2. メモリ効率と高速化を支える `Scripting.Dictionary`
今回のコードのキモは、`Scripting.Dictionary` を使って旧マスターの全行をメモリに保持している点です。
もしこれを配列やループでの総当たりでやると、ファイルが1万行、10万行と増えたときに処理時間が爆発的に伸びます(O(N^2)の悲劇)。Dictionary(連想配列)を使うことで、検索コストを最小限(O(1))に抑え、大規模なデータでも一瞬で処理しきることができます。
3. 文字コードの罠を防ぐ `TriStateUseDefault`
FSOでテキストファイルを開く際、日本語環境で最も恐ろしいのが「文字化け(Shift-JISとUTF-8の衝突)」です。
`OpenTextFile` の第4引数に `-2` (`TriStateUseDefault`) を指定することで、システムのデフォルト設定に合わせた安全な読み込みを行います。実務ではテキストファイルの文字コードが混ざることもあるため、このおまじないは覚えておいて損はありません。
—
現場でよくあるトラブルと回避策
- 「ファイルが別のプロセスによって使用されています」エラー
- Excelや他のエディタで `old_master.txt` や `diff_result.log` を開いたままスクリプトを実行すると、FSOがファイルを掴めずにエラーを起こします。処理の前には必ず対象ファイルを閉じましょう。
- 改行コードの違い(CRLF と LF)
- Windows環境とLinux環境を行き来するテキストファイルの場合、末尾の改行やスペースで別物扱いされることがあります。上記のコードでは `Trim()` を挟んで前後の空白を削る工夫を入れていますが、必要に応じて正規表現などを組み合わせるとさらに精度が上がります。
—
おわりに
いかがでしたでしょうか?
外部の重厚なツールや開発環境がなくても、VBScriptとFSOを正しく組み合わせれば、これほどパワフルで実用的なデータ検証ツールをわずか数十行で作り上げることができます。
「動くコードを書く」から「仕組みを理解してコントロールする」へ。
この感覚を掴んだあなたなら、日常の面倒なルーティンワークはすべて自動化の餌食にできるはずです。
ここをクリアしたあなたなら、VBScriptの基本はもうバッチリです。ぜひ、実際の業務データを使って試してみてくださいね。次回の応用編もお楽しみに!
