プロジェクト計画の「死の連鎖」を断つ:VBAによるタスク制約の動的再配置アーキテクチャ
プロジェクト管理において、開始日の変更は「悪魔のトリガー」だ。MS ProjectのVBAを叩く際、多くのエンジニアが直面するのは、手動で設定された「制約(ConstraintType)」という名の呪縛である。
計画変更時に全タスクがガチガチに固定され、依存関係(Predecessors)を無視した「ゾンビのようなスケジュール」が生成される。これを手動で解くのは、現代のエンジニアがすることではない。今回は、Project VBAの深淵に触れ、この制約地獄をプログラムの力で一掃し、計画を再構築する極限のロジックを伝授する。
—
1. 制約の本質とメモリの「墓場」
MS Projectのオブジェクトモデルにおいて、`Task.ConstraintType` は、プロジェクトの柔軟性を殺す諸刃の剣だ。これを一括解除し、`pjASAP`(できる限り早く)状態へ戻すことは、再計算を正しく機能させるための必須条件である。
ただし、注意せよ。ProjectのCOMラッパーはメモリリークに極めて敏感だ。数千タスクをループ処理する際、オブジェクトの参照を安易に保持し続けることは、アプリケーションのクラッシュを意味する。
最適化の鉄則
- 参照の早期解放: ループ内でのオブジェクト参照は `Set obj = Nothing` を徹底せよ。
- 再計算の抑制: `Application.Calculation = pjManual` で、タスク一つを更新するたびに走る再計算を停止させろ。全更新が終わった後に `CalculateAll` を呼ぶのが、アーキテクトの作法だ。
—
2. 実装:制約解除と再配置のエンジニアリング
以下のコードは、単なる制約解除ツールではない。大規模プロジェクトの整合性を維持しつつ、安全に計画をシフトさせるためのプロトタイプである。
‘ プロジェクト計画シフト用エンジン
Public Sub ResetAndShiftProject(ByVal shiftDays As Long)
Dim proj As Project
Dim tsk As Task
Set proj = ActiveProject
‘ パフォーマンスの極限化:再計算をオフにする
Application.Calculation = pjManual
Application.ScreenUpdating = False
On Error GoTo Cleanup
‘ 全タスクを巡回し、制約を解放
For Each tsk In proj.Tasks
If Not tsk Is Nothing Then
‘ 制約を「できる限り早く」に変更することで依存関係の連鎖を復元する
If tsk.ConstraintType <> pjASAP Then
tsk.ConstraintType = pjASAP
End If
‘ 開始日が既に設定されているタスクの強制シフト
If Not IsEmpty(tsk.Start) Then
tsk.Start = DateAdd(“d”, shiftDays, tsk.Start)
End If
End If
Next tsk
Cleanup:
‘ 最後に一括で再計算を行い、メモリを解放
Application.Calculation = pjAutomatic
Application.ScreenUpdating = True
‘ オブジェクト参照の明示的破棄
Set tsk = Nothing
Set proj = Nothing
If Err.Number <> 0 Then
MsgBox “Critical Error: ” & Err.Description, vbCritical
End If
End Sub
—
3. なぜ「Windows API」が必要になるのか
大規模なプロジェクトファイル(数万行クラス)を扱う場合、VBAのネイティブな挙動だけではUIスレッドがロックし、Windowsから「応答なし」と見なされる。ここで、Windows APIの `Sleep` を利用したウェイト処理や、`DoEvents` の適切な挿入が必要になる。
だが、安易な `DoEvents` は再帰呼び出しのスタックオーバーフローを招く。本当に信頼できるシステムを構築するなら、「タスクのブロック単位で処理を分割し、Application.OnTime を使用して非同期的にキューを処理する」という設計が求められる。これが、シニアとジュニアの境界線だ。
—
4. チーフアーキテクトからの助言:システム間連携の罠
もしあなたが、このVBAをExcelや外部のWeb APIと連携させているなら、「データの整合性」に命を懸けろ。
外部から渡された日付データが、Project側のカレンダー設定(稼働日・休日)と衝突した瞬間、スケジュールは崩壊する。必ず `tsk.Calendar` プロパティを参照し、そのタスクが「いつ稼働できるのか」を計算式に組み込むこと。
最後に
VBAはレガシーではない。使い手の知性次第で、それは最強のプロジェクト管理兵器となる。コードを書く前に、タスクの依存関係という「グラフ構造」を脳内で描け。制約を解除するということは、システムに自由を与えることだ。自由を与えられた計画は、本来あるべき正しい形へと自ずと収束していく。
現場の健闘を祈る。
