VBScriptで差分を制する:FSOとDictionaryで作る「最強のファイル照合エンジン」
こんにちは。自動化の世界へようこそ。
マクロの記録で操作を覚え、「もう少し高度なことがしたい」と感じているあなたへ。今日紹介するのは、VBScriptの真骨頂である「Scripting.Dictionary」と「FileSystemObject (FSO)」を組み合わせた、超高速ファイル差分抽出エンジンです。
多くの初学者が「ファイルの一覧を2重ループで回して比較」という、計算量が爆発する(=PCが重くなる)非効率なコードを書きがちです。今回は、メモリ上でスマートに照合を行う、プロの設計思想をお伝えします。
—
なぜ「2重ループ」は悪なのか?
2つのフォルダにあるファイルを比較する際、単純に「フォルダAのファイルを取り出し、フォルダBを全探索して同じものがあるか探す」という処理を繰り返すと、ファイル数が増えるほど指数関数的に時間がかかります。
「賢いエンジニアは、まず片方のフォルダをメモリ上の辞書(Dictionary)にインデックス化する」
これだけで、検索速度は劇的に向上します。準備はいいですか?
—
実装コード:高速ファイル差分マトリックス生成
以下のコードをコピーし、`.vbs` ファイルとして保存してください。
Option Explicit
‘ メイン処理:フォルダAとフォルダBを比較する
Call CompareFolders(“C:\Test\FolderA”, “C:\Test\FolderB”, “C:\Test\Report.txt”)
Sub CompareFolders(pathA, pathB, reportPath)
Dim fso, dictA, dictB
Dim folderA, folderB, file
Dim reportFile, fileName
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set dictA = CreateObject(“Scripting.Dictionary”)
Set dictB = CreateObject(“Scripting.Dictionary”)
‘ — ステップ1: フォルダAを辞書に登録 —
For Each file In fso.GetFolder(pathA).Files
dictA.Add file.Name, True
Next
‘ — ステップ2: フォルダBを辞書に登録 —
For Each file In fso.GetFolder(pathB).Files
dictB.Add file.Name, True
Next
‘ — ステップ3: 比較とレポート出力 —
Set reportFile = fso.CreateTextFile(reportPath, True)
reportFile.WriteLine “ファイル名” & vbTab & “判定”
‘ dictAを基準に比較
For Each fileName In dictA.Keys
If dictB.Exists(fileName) Then
reportFile.WriteLine fileName & vbTab & “[両方に存在]”
Else
reportFile.WriteLine fileName & vbTab & “[Aのみ存在]”
End If
Next
‘ dictBのみにあるファイルを確認
For Each fileName In dictB.Keys
If Not dictA.Exists(fileName) Then
reportFile.WriteLine fileName & vbTab & “[Bのみ存在]”
End If
Next
reportFile.Close
MsgBox “差分レポートが生成されました!”, 64, “完了”
End Sub
—
プロのコードを読み解くポイント
1. Dictionaryの「キー検索」が最強である理由
`dict.Exists(fileName)` は、内部的にハッシュテーブルという仕組みを使っています。これは、どれだけファイル数が多くても、瞬時に「その名前が登録されているか」を判定できる魔法のツールです。これを使えば、2重ループを脱却し、処理時間を大幅に短縮できます。
2. FSO (FileSystemObject) の作法
`CreateObject(“Scripting.FileSystemObject”)` は、Windowsにおけるファイル操作の司令塔です。
- ポイント: 最後にオブジェクトを `Set … = Nothing` で解放するのが「メモリの行儀」が良いエンジニアの嗜みですが、VBScript終了時に自動解放されるため、小規模スクリプトでは必須ではありません。しかし、大規模な処理では意識しておきましょう。
3. 陥りやすいエラーと回避策
- 「ファイル名が重複している場合」: もし同じフォルダに同名ファイルが存在する(ありえませんが)と、`dict.Add` でエラーになります。`If Not dict.Exists(file.Name) Then` でチェックを入れるのが安全な実装です。
- 「権限エラー」: 特定のシステムフォルダを読みに行くと `Permission Denied` になります。必要に応じて `On Error Resume Next` を使用し、エラーをハンドリングしてください。
—
次のステップへ
このスクリプトは、単なる「比較」ですが、ここから応用は無限大です。
- 差分があるファイルだけを `fso.CopyFile` で別の場所に移動させる。
- 最終更新日時を比較して、古いファイルを削除する。
VBScriptは古くからある言語ですが、OSの深部に直接触れられる強力な武器です。この「Dictionaryを使った照合」というアルゴリズムさえマスターすれば、どんな言語(VBA、Python、PowerShell)に転向しても、あなたのコードは常に高速でエレガントであり続けるはずです。
ここをクリアしたあなたは、もう初心者ではありません。自信を持って、次の自動化の壁に挑んでくださいね!
