こんにちは!Project VBAの世界へようこそ。
マクロの記録ボタンを押すだけのステージを卒業し、「いよいよ本格的なツールを作りたい!」と一歩を踏み出したあなたへ。
今回は、実務で絶対に避けて通れない「エラーハンドリングとロールバック処理」についてお話しします。
「途中でエラーが起きたら、プロジェクトのスケジュールが中途半端に書き換わってしまった……」
こんな悪夢、経験したくありませんよね。Excelと違って、MS Projectは複数のタスクやリソースが複雑に絡み合う「生き物」です。だからこそ、プログラミングの世界ではトランザクション(一連の処理の不可分性)の概念が極めて重要になります。
ここをクリアすれば、あなたの書くVBAコードは一気に「プロのエンジニアの品質」に到達します。さあ、一緒に本質をマスターしていきましょう!
—
1. なぜProject VBAには「ロールバック」が必要なのか?
Excel VBAであれば、マクロが途中で止まっても、ファイルを保存しなければ「Ctrl + Z」で元に戻せます。しかし、Project VBAの実行時、変更は容赦なくプロジェクトデータベースに反映されていきます。
もし、100個のタスクを一括更新するマクロの「50個目」でエラーが起きたらどうなるでしょう?
- 1番目〜50番目は「更新された状態」
- 51番目〜100番目は「古い状態」
……こんな「半端なスケジュール」が完成してしまいます。これではプロジェクトは大混乱です。
これを防ぐのが、「エラーが起きたら、処理を始める前の状態に綺麗に戻す(ロールバックする)」という設計思想です。
—
2. Project VBAの基本構造とエラー対策のステップ
Project VBAで安全なトランザクションを組むためには、以下の3つのステップをコードに組み込みます。
1. バックアップの確保(または変更前の状態の保持)
2. 実行ブロック(エラーが発生するかもしれない処理)
3. 例外処理とロールバック(エラー時の復旧、または変更の破棄)
実は、MS Projectにはアプリケーションレベルでの強力な「元に戻す(Undo)」の仕組みがあります。これを利用するのが、もっともエレガントで確実なロールバック手法です。
—
3. 実装パターン:トランザクション制御のテンプレートコード
実際の開発現場でそのままコピペして使える、堅牢なエラーハンドリングのテンプレートを用意しました。
Sub UpdateTasksWithRollback()
Dim proj As Project
Set proj = ActiveProject
‘ 【重要】「元に戻す(Undo)」のコンテキスト(単位)を開始する
‘ これにより、この後の操作をひとまとめにして取り消せるようにします
App.UndoContextStart “一括タスク更新処理”
‘ エラーが発生した際のジャンプ先を指定
On Error GoTo ErrorHandler
‘ — 【実行ブロック】 —
Dim t As Task
For Each t in proj.Tasks
If Not t Is Nothing Then
‘ 例として、すべてのタスクのコストに強制的にアクセス
‘ ここで何らかのビジネスロジックエラー(例:ゼロ除算など)が起きると想定
t.Text1 = “処理済み”
‘ わざとエラーを起こすテスト用コード(通常はコメントアウト)
‘ If t.ID = 5 Then Err.Raise 9999, , “意図的なテストエラー”
End If
Next t
‘ 正常終了した場合の処理
App.UndoContextEnd
MsgBox “すべての処理が正常に完了しました。”, vbInformation
Exit Sub
ErrorHandler:
‘ — 【例外処理・ロールバックブロック】 —
‘ エラー情報を保持
Dim errNum As Long, errDesc As String
errNum = Err.Number
errDesc = Err.Description
‘ エラーが発生したため、UndoContextStartに戻す(変更をすべて破棄)
‘ ProjectのUndo機能を利用して一網打尽にロールバックします
App.UndoContextEnd
‘ ※注意: Projectの仕様やバージョンによっては、
‘ アプリケーションレベルでのEditUndoメソッドが必要な場合もあります
On Error Resume Next
App.EditUndo
On Error GoTo 0
‘ ユーザーに分かりやすく通知
MsgBox “エラーが発生したため、変更をロールバックしました。” & vbCrLf & _
“エラー内容: ” & errDesc, vbCritical, “処理中断”
End Sub
—
4. コードの解説:ここがプロの技
`App.UndoContextStart` と `App.UndoContextEnd`
このメソッドのペアは、Projectの「元に戻す」の履歴をグループ化します。
この中で行われた変更は、あたかも「1つの操作」であるかのように扱われます。エラーが起きたときに `App.EditUndo` を呼び出すことで、このブロック内の変更を美しく無かったことにできるのです。
二重エラーを防ぐ `On Error Resume Next`
エラーハンドラ(`ErrorHandler:`)の内部で万が一別のエラーが起きた場合、無限ループや予期せぬクラッシュを引き起こすリスクがあります。そのため、ロールバックを実行するコードの周辺では一時的に `On Error Resume Next` を挟むのが、現場で生き抜くための防衛術です。
—
5. 陥りやすい罠とアドバイス
初心者がやりがちなミスとして、「エラーが起きたことに気づかず、そのままファイルを上書き保存してしまう」という最悪のパターンがあります。
必ず以下の鉄則を守ってください。
- マクロの冒頭で自動保存をしない(ユーザーが意図したタイミングでのみ保存させる)
- イミディエイトウインドウを活用する(`Debug.Print`でどこまで処理が進んだかを必ずトレースできるようにする)
—
まとめ
いかがでしたでしょうか?
今回は、Project VBAにおけるエラーハンドリングとロールバックの設計思想について解説しました。
「動けばいいや」のコードから、「エラーが起きてもシステムを壊さない」プロのコードへ。
ここをクリアすれば、あなたはもう立派なProject VBAのエンジニアです。現場で信頼される堅牢なツールを、ぜひご自身の手で作り上げてくださいね。応援しています!
