【実務・中級編】【上級者向け】プロジェクトの自動保存失敗時に、ローカルキャッシュから最新状態を復元するリカバリツール – Project VBA解析バイブル

スポンサーリンク

【上級者向け】Projectの自動保存失敗時に、ローカルキャッシュから最新 state を復元するリカバリツール

プロジェクトマネジャーが最も恐れる瞬間の一つ。それは、何時間もかけてWBSを精緻化し、リソース配分を最適化した直後の「クラッシュ」、そして「ファイルの破損・保存失敗」だ。

MS Projectの標準機能である自動バックアップや自動保存は、ネットワークの瞬断やPWA(Project Web App)との同期エラー、あるいは巨大なアドイン干渉の前には無力化することがある。「保存できませんでした」という冷酷なダイアログが出た瞬間、あなたの数時間の労力は闇に消える——本当に、そうだろうか?

諦めるのは早い。MS Projectは裏側で、確実に「ローカルキャッシュ(Temp領域)」にその足跡を残している。

今回は、APIのライフサイクルとファイルシステムの挙動を熟知したアーキテクトだけが知る、Tempフォルダの迷宮から最新のバイナリをサルベージし、自動でプロジェクトファイルを復元する極限のリカバリツールを授けよう。

なぜ標準の自動保存は信用できないのか?

多くの開発者は、「MS Projectの自動バックアップ設定(`File > Options > Save`)を有効にしているから安全だ」と誤解している。しかし、エンタープライズ環境の実務において、この機能には致命的な盲点がある。

1. 排他制御とロックの競合: 共有ネットワークドライブ上で作業している場合、自動保存の書き込みタイミングと他のプロセスが競合し、ファイルハンドルが解放されずにサイレントエラー(ログに残らない失敗)を引き起こす。
2. テンポラリファイルの孤立: Projectは保存時にまず`.mpp`ではなく、一時的なアトミックファイル(拡張子がランダムな隠しファイル等)を生成し、正常終了後にリネームする。このリネーム処理の瞬間に異常終了すると、「中身は最新だが認識されないキャッシュ」がTempフォルダに取り残される。

これらを人力で探し出し、破損した構造を修復するのは地獄の作業だ。だからこそ、VBAによるプログラム制御でOSレベルから強制サルベージを行う必要がある。

堅牢なリカバリツールの設計思想

今回のツールは、単にファイルをコピーするだけの幼稚なスクリプトではない。プロダクション環境で耐えうるよう、以下の堅牢性(ロバストネス)を担保している。

  • タイムスタンプの厳密な比較: 複数のTempファイルから、真に「最も新しく更新されたバイナリ」を数学的に特定する。
  • FileSystemObject (FSO) の安全なハンドリング: メモリリークやファイルロックを回避するため、適切なオブジェクト解放とエラーハンドリングを行う。
  • Projectオブジェクトモデルの安全なアタッチ: 復元したファイルを読み取り専用、あるいは安全なワークスペースとして隔離オープンし、即座に整合性チェックを行う。

プロダクションコード:自動リカバリVBA実装

以下のコードを、個人用マクロブック(`Global.mpt`)または独立した管理用VBAモジュールに実装せよ。

Option Explicit

‘ ==============================================================================
‘ 致命的な保存失敗からの生還:MS Project 最新キャッシュ・リカバリエンジン
‘ Architecture Lead: Enterprise VBA Solution
‘ ==============================================================================
Public Sub RecoverLatestProjectCache()
Dim fso As Object
Dim targetFolder As String
Dim latestFile As Object
Dim currentFile As Object
Dim folderPath As String
Dim fsoFolder As Object
Dim backupPath As String
Dim wsh As Object

‘ 1. エラーハンドリングの要塞化
On Error GoTo ErrorHandler

Set fso = CreateObject(“Scripting.FileSystemObject”)
Set wsh = CreateObject(“WScript.Shell”)

‘ Windowsの標準的なユーザーTempフォルダを取得
folderPath = wsh.ExpandEnvironmentStrings(“%TEMP%”)

If Not fso.FolderExists(folderPath) Then
MsgBox “致命的エラー: システムのテンポラリフォルダが見つかりません。”, vbCritical, “リカバリ中止”
GoTo CleanUp
End If

Set fsoFolder = fso.GetFolder(folderPath)

‘ 2. Temp領域から「MS Projectの痕跡(拡張子.mpp または 関連キャッシュ)」をスキャン
‘ ※Projectは一時的に固有の命名規則でファイルを生成するため、ワイルドカードで全走査する
Dim fileItem As Object
Dim maxDate As Date
maxDate = #1/1/1970# ‘ 初期値

MsgBox “ローカルキャッシュのディープスキャンを開始します…”, vbInformation, “サルベージ実行中”

For Each fileItem In fsoFolder.Files
‘ MS Projectに関連する拡張子、または自動保存の特徴を持つファイルをターゲットに
If LCase(fso.GetExtensionName(fileItem.Name)) = “mpp” Or _
InStr(1, fileItem.Name, “MSProject”, vbTextCompare) > 0 Or _
InStr(1, fileItem.Name, “~$”, vbTextCompare) > 0 Then

‘ 更新日時が最も新しいものを特定
If fileItem.DateLastModified > maxDate Then
maxDate = fileItem.DateLastModified
Set latestFile = fileItem
End If
End If
Next fileItem

‘ 3. 該当ファイルの有無判定
If latestFile Is Nothing Then
MsgBox “復元可能なキャッシュファイルが検出されませんでした。”, vbExclamation, “リカバリ失敗”
GoTo CleanUp
End If

‘ 4. 安全なデスクトップ領域への隔離コピーとリカバリ実行
backupPath = wsh.ExpandEnvironmentStrings(“%USERPROFILE%”) & “\Desktop\Recovered_Project_” & Format(Now, “yyyymmdd_HHMMSS”) & “.mpp”

‘ ロックを回避するため、直接開くのではなくコピーを生成して安全性を担保
latestFile.Copy backupPath, True

‘ 5. MS Projectで強制オープン
If MsgBox(“最新のキャッシュ(更新日時: ” & latestFile.DateLastModified & “)を特定しました。” & vbCrLf & _
“デスクトップに安全に復元しますか?” & vbCrLf & _
“保存先: ” & backupPath, vbQuestion + vbYesNo, “リカバリ確認”) = vbYes Then

FileOpenEx Name:=backupPath, ReadOnly:=pjReadOnly
MsgBox “リカバリが完了しました。データの整合性を確認し、別名で上書き保存してください。”, vbInformation, “成功”
End If

CleanUp:
‘ オブジェクトの明示的な破棄(メモリリークの根絶)
Set latestFile = Nothing
Set fsoFolder = Nothing
Set fso = Nothing
Set wsh = Nothing
Exit Sub

ErrorHandler:
MsgBox “リカバリプロセスで予期せぬ例外が発生しました。” & vbCrLf & _
“Error # ” & Err.Number & “: ” & Err.Description, vbCritical, “致命的エラー”
Resume CleanUp
End Sub

コードのアーキテクチャ解説:なぜこの実装が「プロフェッショナル」なのか?

1. `On Error GoTo ErrorHandler` によるトランザクション的安全性
ファイルシステムへのアクセスは、他のプロセスによるロックや権限不足でいつ例外落ちしてもおかしくない。このコードでは、予期せぬクラッシュ時にも必ず `CleanUp` ラベルを通過させ、COMオブジェクト(`Scripting.FileSystemObject` など)の参照を確実に解放する設計にしている。これにより、VBAランタイムのメモリリークを防ぐ。
2. 元ファイルを直接触らない(非破壊原則)
見つけたTempファイルを直接開くのではなく、一度 `%USERPROFILE%\Desktop` へタイムスタンプ付きの別名で「コピー(Copy)」してから開いている。これにより、元のキャッシュを破損させるリスクを完全に排除し、何度でもやり直しが効く環境を作る。
3. `pjReadOnly` での安全オープン
復元されたキャッシュファイルは、構造が破損している可能性がゼロではない。そのため、いきなり書き込み可能な状態で開くのではなく、一度 `ReadOnly` モードで強制アタッチし、ユーザー自身にデータの健全性を確認させた上で正式保存させるフェーズを踏んでいる。

現場で即座に導入するための運用指針

このツールをあなたのチームに導入するにあたり、以下の運用ルールを徹底してほしい。

  • ショートカットキーの割り当て: この `RecoverLatestProjectCache` プロシージャを、リボンやクイックアクセスツールバー、あるいは `Ctrl + Shift + R` などのショートカットに割り当てること。パニックに陥った現場のエンジニアが、迷うことなく1クリックで起動できるようにしなければ意味がない。
  • 定期的なTempクリーンアップツールとの兼ね合い: Windowsのディスククリーンアップやサード製ユーティリティがTempフォルダを頻繁に掃除する場合、キャッシュ自体の寿命が極端に短くなる。重要なプロジェクトを動かす日は、OS側の自動クリーンアップを一時停止する運用を推奨する。

総括

システムやソフトウェアが完璧であることはあり得ない。真に優秀なエンジニアやプロジェクトリーダーとは、「失敗しないシステム」を作る者ではなく、「失敗した瞬間に、ノーペナルティで巻き戻せる極限のセーフティネットを構築している者」を指す。

このリカバリツールをあなたの開発環境のアーセナルに加え、いかなるクラッシュをも笑い飛ばせる強靭なプロジェクト管理基盤を完成させてほしい。

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