【実務・中級編】【実務中級】FileSystemObject(FSO)を用いた、プロジェクトのバージョン管理バックアップシステム – Project VBA解析バイブル

スポンサーリンク

【実務中級】FileSystemObjectで構築する! MS Project自動バージョン管理バックアップシステム

開発現場でMicrosoft Project(MSP)を運用していて、こんな絶望を味わったことはないか?

  • 「先週のベースラインからどこがどうズレたのか、スケジュールが改ざんされて追跡できない」
  • 「上司の一声でスケジュールを修正したが、元の状態に戻せなくなった」
  • 「『最終版_final(2).mpp』みたいな呪いのファイル名がデスクトップに氾濫している」

Project標準の「ベースライン」機能だけでは、タスクの削除やリソースの根本的なアサイン変更の歴史までは追いきれない。真にプロジェクトを守るのは、「保存の瞬間に、不可逆な時系列スナップショットを自動生成する仕組み」である。

今回は、VBAの真髄を知るアーキテクトである私が、`Scripting.FileSystemObject`(以下、FSO)を駆使した、実務で絶対に破綻しない堅牢なバックアップシステムの設計思想とプロダクションコードを伝授する。

1. なぜ「普通のVBAファイル保存」では実務で破綻するのか?

素人が書くVBAコードは、決まってこうなる。

‘ 【アンチパターン】絶対に真似してはいけないコード
ActiveProject.SaveAs “C:\Backups\” & ActiveProject.Name & “_” & Date & “.mpp”

これの何がダメか、プロの視点で叩き込もう。

1. エラーハンドリングの欠如:保存先フォルダが存在しない、あるいは別ユーザーがファイルを開いていてロックされている場合、容赦なく実行時エラーでマクロがクラッシュする。
2. 日付フォーマットの罠:`Date`関数をそのまま文字列結合すると、環境によってスラッシュ(`/`)が含まれ、「Windowsがパスとして認識できない無効な文字エラー」を引き起こす。
3. 世代管理の欠如:バックアップが無限に増殖し、ストレージを圧迫するか、同名ファイルで上書きされて一巻の終わりになる。

我々が目指すべきは、「環境に依存せず、エラーを完全に吸収し、スマートに世代を刻む」プロフェッショナルなコードだ。

2. 堅牢なバックアップシステムを支える3つのアーキテクチャ

今回のコードで実装する核心のロジックは以下の3点だ。

  • FSOによる遅延バインディングとパス正規化:実行環境の参照設定に依存せず、フォルダの存在確認・自動生成を安全に行う。
  • ISO 8601準拠のタイムスタンプ:`YYYYMMDD_HHMMSS`形式を採用し、ファイル名のソート順と時系列を完全に一致させる。
  • イベントプロシージャの安全なフック:`BeforeSave`イベントを捉え、ユーザーに意識させずにバックアップを裏で完結させる。

3. 【コピペ即採用】プロダクションコード

以下のコードは、そのままあなたのProjectファイル(またはグローバルテンプレート)の `ThisProject` モジュールに貼り付けて即座に稼働させることが可能だ。

実装手順

1. MS Projectを開き、`Alt + F11` でVBAエディタを起動。
2. 左側のプロジェクトエクスプローラから `ThisProject` をダブルクリック。
3. 以下のコードをすべて貼り付け。

Option Explicit

‘ ==============================================================================
‘ 模块名: ThisProject (イベントハンドラ)
‘ 概要: Project保存時にFileSystemObjectを用いて自動バックアップを生成する
‘ ==============================================================================

Private Sub Project_BeforeSave(ByVal AS_Project As Project)
‘ エラーハンドリングの要
On Error GoTo ErrorHandler

Dim fso As Object
Dim originalPath As String
Dim originalName As String
Dim ext As String
Dim backupDir As String
Dim timeStamp As String
Dim targetBackupPath As String

‘ 1. 未保存の新規プロジェクトの場合はバックアップスキップ(パスがないため)
If AS_Project.Path = “” Then
Exit Sub
End If

‘ 2. FSOのインスタンス生成(遅延バインディングで参照設定のトラブルを回避)
Set fso = CreateObject(“Scripting.FileSystemObject”)

‘ 3. ファイルパスと名前の分解
originalPath = AS_Project.Path
originalName = fso.GetBaseName(AS_Project.Name)
ext = “.” & fso.GetExtensionName(AS_Project.Name)

‘ 4. バックアップ格納先の設定(元のファイルと同じ階層に “Backup” フォルダを作成)
backupDir = originalPath & “\Backup”

If Not fso.FolderExists(backupDir) Then
fso.CreateFolder (backupDir)
End If

‘ 5. タイムスタンプの生成 (YYYYMMDD_HHMMSS形式でソート性を担保)
timeStamp = Format(Now, “yyyymmdd_hhnnss”)

‘ 6. バックアップファイルのフルパス構築
targetBackupPath = backupDir & “\” & originalName & “_” & timeStamp & ext

‘ 7. 現在アクティブなプロジェクトの状態を一度ディスクに確実に保存した上でコピー
‘ ※ SaveAsではなく、一度実体を保存させてからFSO.CopyFileを使うのが最も安全
AS_Project.Save

fso.CopyFile originalPath & “\” & AS_Project.Name, targetBackupPath, True

‘ クリーンアップ
Set fso = Nothing
Exit Sub

ErrorHandler:
‘ 業務を止める致命的なエラーにしないよう、警告を出して処理を継続させる
MsgBox “自動バックアップの作成中に予期せぬエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“エラー内容: ” & Err.Description, vbCritical, “バックアップシステム警告”

Set fso = Nothing
End Sub

4. コードの急所:プロが解説する設計のポイント

① 遅延バインディング (`CreateObject(“Scripting.FileSystemObject”)`) の採用

早期バインディング(`Dim fso As New Scripting.FileSystemObject`)は、開発環境が変わると参照設定の不整合(COMコンポーネントのバージョン違い等)でコンパイルエラーを吐くリスクがある。実務で配布するツールにおいて、このリスクは致命傷だ。`CreateObject`による実行時生成こそが、マクロ職人の正しい選択である。

② `Project_BeforeSave` イベントの妙

ユーザーが「上書き保存」ボタンを押した、あるいは `Ctrl + S` を叩いた瞬間に割り込むのがこのイベントだ。ユーザーに「バックアップを取っていますか?」と問う必要すらない。「気づいた時には、安全網が張られている」状態を作るのが、真の自動化エンジニアの仕事である。

③ 世代管理とファイル構造の美学

元のファイルが `ProjectA.mpp` だとしたら、生成されるバックアップは以下のようになる。

C:\Projects\
┣ ProjectA.mpp (本体)
┗ Backup\
┣ ProjectA_20231024_091530.mpp
┣ ProjectA_20231024_174500.mpp
┗ ProjectA_20231025_100012.mpp

同一階層を汚さず、`Backup`フォルダの中に綺麗に時系列順で格納されるため、後から「昨日の15時点の状態に戻して比較したい」と思った時に、MS Projectの「比較(Compare Projects)」機能の生贄として完璧に機能する。

5. チーフアーキテクトからの実践アドバイス

このシステムを導入するにあたり、現場の運用者へ1点だけ釘を刺しておいてほしい。
それは「バックアップフォルダの容量肥大化対策」だ。

FSOを使えば、古いバックアップ(例えば30日以上経過したもの)を自動削除するロジックを上記のコードに組み込むことは容易い。しかし、プロジェクトのスケジュールファイルは軽量であるため、まずはこの「全保存時スナップショット」の安心感を現場に体感してもらうことを強く推奨する。

小手技のコードを寄せ集めて動かなくなるVBAから脱却し、堅牢で美しいオブジェクトモデルの操作を手に入れてほしい。あなたのプロジェクト管理の信頼性は、この数行のコードによって劇的に引き上げられるはずだ。

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