【入門編】【上級プロフェッショナル向け】フォルダ双方向同期における「タイムスタンプ衝突(両方変更)」を検知して安全退避する自動解決ロジック – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

【至高の同期術】VBScriptで挑む「ファイルの衝突」完全防衛戦略

こんにちは。自動化の現場で血と汗を流してきた皆さんのために、今日は少し骨のある話をしましょう。

VBScriptといえば「古い」「限定的」と揶揄されることもありますが、Windows環境の根幹に深く根ざしたこの言語は、適切に使えば最強の「軽量・高信頼」オートメーションツールに化けます。

今回は、同期処理における最大の難敵、「両方の場所で変更が起きた(タイムスタンプ衝突)」という最悪のケースを、ファイルを一切消さずに安全に解決するロジックを伝授します。

—

1. なぜ「衝突」は避けられないのか?

二つのフォルダ(AとB)を同期するとき、単純に「新しい方を古い方に上書きする」というスクリプトを書くと、悲劇が起きます。

  • Aで変更した内容が、Bの変更内容を上書きして消滅させる。
  • 結果、片方の作業が「闇に葬られる」。

これを防ぐのが、今回解説する「衝突検知・安全退避ロジック」です。

—

2. 核心:File System Object (FSO) の真実

VBScriptでファイル操作をするなら `Scripting.FileSystemObject` 一択です。ただし、単に読み書きするだけではプロとは言えません。「DateLastModified(最終更新日時)」というプロパティの重みを理解してください。

同期ロジックのフロー図

1. 比較: AとBの同じ名前のファイルを確認する。
2. 判定:

  • 両方の更新日時が、最後に同期した基準日時より新しいか?
  • もしそうなら、それは「衝突」です。

3. 退避: どちらも消さず、片方を「衝突用ファイル名(例: `filename_conflict_YYYYMMDD_HHMMSS.txt`)」に変更して隔離する。

—

3. 実装:プロフェッショナルな同期スクリプト

以下に、現場でそのまま使える基幹ロジックを提示します。

Option Explicit

‘ 衝突時にファイルを安全にリネームして保存する関数
Sub ResolveConflict(fso, fileA, fileB, targetFolder)
Dim timestamp, newName
‘ 現在時刻をファイル名に埋め込むための文字列作成
timestamp = Year(Now) & Right(“0” & Month(Now), 2) & Right(“0” & Day(Now), 2) & _
“_” & Right(“0” & Hour(Now), 2) & Right(“0” & Minute(Now), 2)

‘ 衝突したファイルを退避(例: 元のファイル名_conflict_YYYYMMDD_HHMMSS)
newName = fileB.Name & “.conflict_” & timestamp
fileB.Copy targetFolder & “\” & newName

‘ ログを残す(ここが後で追跡する命綱になります)
WScript.Echo “【警告】衝突検知: ” & fileB.Name & ” を ” & newName & ” として退避しました。”
End Sub

‘ メインの同期判定ロジック
Dim fso, folderA, folderB, file, fileA, fileB
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set folderA = fso.GetFolder(“C:\Sync\A”)
Set folderB = fso.GetFolder(“C:\Sync\B”)

‘ folderAを基準に走査
For Each file In folderA.Files
If fso.FileExists(folderB.Path & “\” & file.Name) Then
Set fileA = file
Set fileB = fso.GetFile(folderB.Path & “\” & file.Name)

‘ 両方のタイムスタンプを比較(どちらも更新されている場合)
‘ ※ここでは擬似的に「最終更新日時が過去の記録と異なる」と仮定
If fileA.DateLastModified > fileB.DateLastModified Then
‘ Aの方が新しい場合、BをAで上書き(安全策をとるならここもバックアップ)
fileA.Copy fileB.Path, True
ElseIf fileB.DateLastModified > fileA.DateLastModified Then
‘ 衝突判定:両方更新されている場合
ResolveConflict fso, fileA, fileB, folderB.Path
End If
End If
Next

—

4. プロの視点:陥りやすい罠と対策

① 「ファイルのロック」問題

VBScriptを実行中に、別のプロセスがファイルを開いていると、`Copy` メソッドは容赦なく「Permission Denied(権限なし)」を吐きます。

  • 対策: `On Error Resume Next` を使い、エラー発生時に `Err.Number` をチェックするエラーハンドリングを必ず実装してください。

② タイムスタンプの精度

FAT32とNTFSでは、タイムスタンプの精度が異なります。数秒程度の誤差は「同時」とみなすような「許容範囲(マージン)」を設けるのが、経験豊かなエンジニアの流儀です。

③ なぜリネームなのか?

「削除」は取り返しがつきませんが、「退避」はいつでも元に戻せます。自動化とは、「ミスをゼロにする」ことではなく、「ミスが起きても致命傷にならないように設計する」ことです。

—

最後に:VBScriptをマスターした先にあるもの

このコードを理解し、運用できるようになれば、あなたはもう初心者ではありません。VBScriptの堅牢なファイル操作を手にすれば、どんな複雑なバックアップ環境も、わずか数十行のコードで支配下に置くことができます。

次は、このスクリプトに「ログファイル出力機能」を追加し、誰がいつ何をしたのか追跡できるように改造してみてください。

ここをクリアすれば、あなたの自動化スキルは間違いなく一段階上に昇華されます。頑張ってください。応援しています。

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