プロジェクトの「保存」に失敗したらすべてが台無し?VBAで実現する「強制トランザクション制御」の極意
こんにちは。現場で泥臭いトラブルを何度も乗り越えてきた、VBAアーキテクトです。
MS Projectを使っていて、こんな経験はありませんか?
「保存ボタンを押した直後にエラーが出て、ファイルが壊れた(あるいは中途半端な状態になった)」
「カスタムフィールドを大量に計算した後に保存したが、一部のデータだけが更新され、整合性が取れなくなった」
プロジェクト管理において、「保存」は単なるファイル操作ではありません。「データの整合性を担保する生命線」です。今回は、単なるマクロの記録を超え、プロフェッショナルな現場で求められる「保存のトランザクション制御」について深掘りしましょう。
—
なぜ「保存」はリスクが高いのか?
Project VBAにおける `FileSave` メソッドは、呼び出せば自動的にディスクへ書き込みに行きます。しかし、途中でネットワークが切れたり、外部参照しているリソースプールがロックされていたりすると、処理は「宙ぶらりん」になります。
トランザクション管理とは、いわば「すべて成功するか、さもなくば何もしなかったこと(ロールバック)にするか」という二択をシステムに強制する考え方です。VBA単体では真のトランザクション制御は難しいですが、「バックアップを介した仮想ロールバック」という手法で、堅牢なシステムを構築できます。
—
ステップ1:強制保存をラップする「ガード関数」を作る
まずは、単純な保存ではなく、失敗を検知して元の状態に戻すための「安全な保存ロジック」を設計します。
‘ プロジェクトを安全に保存するためのラッパー関数
Public Sub SafeSaveProject()
Dim currentPath As String
Dim backupPath As String
currentPath = ActiveProject.FullName
backupPath = Environ(“TEMP”) & “\tmp_project_backup.mpp”
On Error GoTo ErrorHandler
‘ 1. 現在の状態を一時ファイルにバックアップ
ActiveProject.SaveAs Name:=backupPath
‘ 2. 本番環境への保存を実行
ActiveProject.Save
MsgBox “保存が正常に完了しました。”, vbInformation
Exit Sub
ErrorHandler:
‘ 3. エラー発生!バックアップから復元を試みる
MsgBox “保存中に深刻なエラーが発生しました。バックアップから復元します。”, vbCritical
‘ バックアップを上書きしてロールバック(整合性の維持)
Application.FileOpen Name:=backupPath
‘ エラー処理を終了
Resume Next
End Sub
—
ステップ2:COMアドインによる「監視」の概念(上級編)
VBAだけでは「ユーザーが手動で保存ボタンを押した瞬間」を捕捉するのが難しい場合があります。ここで登場するのが COMアドイン(VSTOなど) です。
COMアドインを使えば、`Application.ProjectBeforeSave` というイベントをインターセプト(横取り)できます。これにより、「保存前に行うべきバリデーション(整合性チェック)」を強制的に走らせることが可能です。
コンセプトコード(VB.NET / VSTO)
‘ COMアドイン側でプロジェクト保存イベントをフック
Private Sub Application_ProjectBeforeSave(ByVal pj As Microsoft.Office.Interop.MSProject.Project, ByVal SaveAs As Boolean, ByRef Cancel As Boolean) Handles Application.ProjectBeforeSave
‘ ここで全タスクの整合性をチェックする関数を呼ぶ
If Not IsProjectDataValid(pj) Then
MsgBox(“データの整合性が取れていません。保存を中止します。”)
Cancel = True ‘ 保存処理を強制キャンセル
End If
End Sub
—
陥りやすい「落とし穴」を回避する3つのポイント
1. ActiveProjectの迷子:
プロジェクトが複数開かれている場合、`ActiveProject` は常に不安定です。必ず `Projects(i)` とインデックスで指定するか、プロジェクトのGUIDで特定する癖をつけてください。
2. バックアップパスの固定化:
`C:\` 直下などに保存しようとすると、権限エラーで死にます。必ず `Environ(“TEMP”)` など、OSが許可した一時フォルダを使いましょう。
3. 計算のタイミング:
Projectは保存時に自動計算を行う設定がある場合があります。`Calculation` モードを一時的にオフにしてから保存し、完了後にオンに戻すのが、大規模プロジェクトでの鉄則です。
—
先輩エンジニアからのメッセージ
「マクロの記録」で生成されたコードは、いわば「おもちゃのピアノ」です。しかし、今日紹介したような「例外処理(`On Error`)」や「イベントフック」を意識し始めたあなたは、もう立派な自動化エンジニアの入り口に立っています。
プログラムは「うまく動くとき」ではなく、「どう失敗するか」を設計したときに、初めてプロの仕事になります。
まずは、あなたのプロジェクトでこの「SafeSave」の考え方を試してみてください。もしわからないことがあれば、いつでも聞いてくださいね。あなたのコードが、現場の安心を支える強固な基盤になることを願っています。
さあ、次はどの領域を自動化しましょうか?
