【実務・中級編】Project VBAにおける「Undo(元に戻す)」スタックの制御とトランザクション管理 – Project VBA解析バイブル

スポンサーリンク

Project VBAを掌握する:破綻なきタスク制御と「Undoスタック」の設計思想

MS ProjectのVBA開発において、最も多くのエンジニアが犯す致命的なミスをご存知だろうか。それは「単一のタスク更新を逐次的に実行し、エラーハンドリングを怠ること」だ。

WBSの階層構造、依存関係、制約条件。これらは全て相互にリンクしている。一箇所でも不正な値を流し込めば、プロジェクト全体が不整合を起こし、取り返しのつかないデータ破壊を招く。特に、外部DBやCSVから一括インポートするようなツールにおいて、「Undo(元に戻す)スタックの制御」は、単なる機能ではなく「プロダクトの信頼性そのもの」である。

今回は、伝説的アーキテクトの視点から、VBAで堅牢なトランザクションを疑似構築する極限の手法を伝授する。

1. なぜVBA標準の「Undo」は当てにならないのか

MS ProjectのVBAには、SQLのような`BEGIN TRANSACTION`や`ROLLBACK`命令は存在しない。`Application.Undo`はあくまでユーザーの操作をスタックするものであり、マクロの実行単位は「一つの大きなUndo単位」として処理されることもあれば、処理内容によってはスタックが分断されることもある。

「なぜそのコードは危険なのか?」

  • 非アトミックな処理: ループの途中でエラーが発生し、処理が中断されたとき、ゴミデータがWBSに残る。
  • 再計算コストの爆発: タスクを一括変更する際、`Calculate`が内部で無数に走り、パフォーマンスを著しく低下させる。

2. 実践的設計パターン: 「ステージング&一括コミット」

エラー時にプロジェクトを汚さないための黄金律は、「計算負荷の高い処理は極力遅延させ、検証プロセスを通過したものだけを実データに適用する」ことだ。

プロダクションコード:セーフ・トランザクション設計

以下のコードは、タスクの依存関係を更新する際に、検証→適用→エラーハンドリングを完遂するテンプレートだ。

‘ プロジェクトの整合性を保つためのトランザクション・ラッパー
Public Sub SafeUpdateTaskDependency(targetTaskID As Long, predecessorID As Long)
Dim proj As Project
Set proj = ActiveProject

‘ 1. パフォーマンス最適化:自動計算を一旦停止
Dim calcMode As Long
calcMode = Application.Calculation
Application.Calculation = pjManual

On Error GoTo RollbackHandler

‘ 2. バリデーション:ここにビジネスロジックを配置
‘ 不整合な依存関係を作らせないためのガード節
If targetTaskID = predecessorID Then Err.Raise 1001, , “循環参照の検知”

‘ 3. 実行(メイン処理)
Dim t As Task
Set t = proj.Tasks(targetTaskID)
t.Predecessors = predecessorID

‘ 4. コミット(一括計算)
Application.Calculation = calcMode
Application.Calculate

Exit Sub

RollbackHandler:
‘ 5. 安全な復旧
Application.Calculation = calcMode
MsgBox “更新中にエラーが発生しました。変更は破棄されます。” & vbCrLf & _
“エラー詳細: ” & Err.Description, vbCritical
‘ 必要に応じて、ここからログ出力やDB側のロールバック処理を呼び出す
End Sub

3. 開発現場で死なないための「鉄の掟」

① `Calculation`プロパティの制御

タスクを1000件更新する際、一行ごとに計算させてはならない。`Application.Calculation = pjManual` に設定し、最後に `Application.Calculate` を呼び出す。これがパフォーマンス維持と、更新の一貫性を保つ唯一の道だ。

② データベース連携時の落とし穴

外部DB(SQL ServerやAccess)と連携する場合、「VBA側のタスクID」と「DB側の主キー」を直結させてはならない。
MS ProjectのタスクIDは、行の削除や挿入で簡単に変わる。必ず `UniqueID` を介してマッピングし、処理の直前で常に最新のID状態をスキャンする仕組みを構築すること。

③ 「元に戻す」情報の保存

もしユーザーの操作を完全にロールバックしたいなら、処理前に「プロジェクトファイル(mpp)の一時的なスナップショット(名前を付けて保存)」を生成し、エラー発生時にそれを上書き復元するロジックを組み込むのが、最も原始的かつ確実な「Undoの実装」である。

結論:エンジニアの誇りとして

「とりあえず動くコード」と「プロダクション品質のコード」の差は、エラー発生時に何を残すかという一点に集約される。

Project VBAは古い言語だが、その背後にあるプロジェクト管理の理論は深遠だ。WBSを操作するということは、誰かの時間とリソースの未来を書き換えることに他ならない。

次にあなたがコードを書くとき、その「トランザクション」が失敗した瞬間の光景を想像してほしい。そこでゴミデータを撒き散らすのか、それとも静かに元の状態へ収束させるのか。
その判断ができる者だけが、真の業務自動化エンジニアと名乗れるのだ。

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