Project VBAを掌握せよ:タスク自動化における「究極のロールバック」術
こんにちは。プロジェクト管理の深淵へようこそ。
マクロの記録ボタンを押して「なんとなく動いた」段階から、一歩先へ進みたいと願うあなたへ。
Microsoft ProjectのVBAを扱う上で、多くの開発者が最後に直面する「最大の壁」。それは「一括処理の失敗によるデータの不整合」です。何百ものタスクを一気に更新した結果、計算ロジックが破綻し、プロジェクト全体が収集つかなくなった経験はありませんか?
今回は、Project VBAにおける「Undo(元に戻す)」の制御と、エンジニアが現場で必ず実装する「トランザクション設計」の極意を伝授します。
—
1. なぜ「Undoスタック」が開発の命運を分けるのか
Projectにおいて、VBAでタスクを操作することは「DBの行を書き換える」ような単純な作業ではありません。依存関係(Predecessors)や制約、WBS階層が複雑に絡み合っているため、一つのミスが連鎖的なエラーを引き起こします。
VBAで命令を投げると、Projectは即座に再計算(Calculation)を開始します。しかし、途中でエラーが発生した場合、「中途半端に更新されたタスク」が残る。これが最も恐ろしい事態です。
これを防ぐのが「トランザクション的な設計」、つまり「成功しなければ、何一つ書き込まなかったことにする」という考え方です。
—
2. 現場で使える「安全な一括更新」パターン
Project VBAには、残念ながらSQLのような `BEGIN TRANSACTION` 命令は存在しません。しかし、私たちは「Application.UndoEnabled」と「エラーハンドリング」を組み合わせることで、擬似的なトランザクションを構築できます。
以下のコードは、タスクの依存関係を更新する際に、安全にロールバックを管理するテンプレートです。
Sub SafeTaskUpdate()
‘ 1. エラーハンドリングの開始
On Error GoTo ErrorHandler
‘ 2. 自動計算を停止(パフォーマンス向上と安定化のため)
Application.Calculation = pjManual
‘ 3. 処理開始
Dim tsk As Task
For Each tsk In ActiveProject.Tasks
If Not tsk Is Nothing Then
‘ ここでタスクの依存関係や階層を操作
‘ 例: tsk.Predecessors = “1”
‘ もし特定の条件で失敗するロジックならここでエラーを発生させる
If tsk.Name = “危険なタスク” Then Err.Raise vbObjectError + 513
End If
Next tsk
‘ 4. 正常終了: 再計算を実行
Application.Calculation = pjAutomatic
MsgBox “更新が完了しました。”
Exit Sub
ErrorHandler:
‘ 5. ロールバック処理
Application.Calculation = pjAutomatic
‘ Undo機能を使って、変更を全て元に戻す(重要!)
If Application.CanUndo Then
Application.EditUndo
MsgBox “エラーが発生したため、変更をロールバックしました。” & vbCrLf & _
“エラー番号: ” & Err.Number, vbCritical
End If
End Sub
—
3. このコードが「プロの設計」である理由
① `Application.Calculation = pjManual` の重要性
Projectはデフォルトで自動再計算を行います。大量のタスクを更新している最中に再計算が走ると、依存関係のチェックで処理が非常に重くなるばかりか、予期せぬ制約エラーを引き起こします。「手動」に切り替えてから処理し、最後に一度だけ再計算させるのが、パフォーマンスを維持する鉄則です。
② `Application.EditUndo` による擬似ロールバック
Project VBAの `EditUndo` は、直前の操作スタックを一つ戻します。一括処理を一つの「操作」として認識させるために、このスタック制御を活用します。
③ 陥りやすい罠:`On Error Resume Next` の乱用
初心者はエラーを隠蔽するために `Resume Next` を使いがちですが、これは「壊れたデータを放置する」行為です。必ず `On Error GoTo` でエラーをキャッチし、ログを出力し、ロールバックする。これが大規模開発における「エンジニアの作法」です。
—
4. 次のステップへ:WBSの階層構造を操作する際の注意点
タスクの階層(アウトライン)を操作する場合、`tsk.OutlineIndent` や `tsk.OutlineOutdent` を使用しますが、これらは「親タスク」が削除されると子タスクの参照が切れるという特性があります。
- 鉄則:下から上へ処理せよ
タスクを削除したり移動したりする場合は、必ずIDの大きい方(下部)から処理してください。上から削除するとIDが繰り上がり、残りの処理対象タスクが意図しないIDに変わってしまうからです。
—
最後に:完璧を目指さず、強靭であれ
Project VBAの世界において、100%完璧な自動化などありません。あるのは「失敗した時にどれだけ素早く、かつ安全に復旧できるか」という「レジリエンス(回復力)」だけです。
まずはこのロールバックのパターンを、あなたのプロジェクトに組み込んでみてください。これだけで、マクロを走らせる時の「冷や汗」が少し減るはずです。
「ここをクリアすれば、Project VBAの基本はバッチリですよ」。
次回の記事では、カスタムフィールドを用いた高度な依存関係の解析手法について触れていきましょう。
一緒に、現場を楽にする最高のツールを創り上げていきましょう。
