MS Project VBAの深淵:依存関係の「強制固定」を極限まで制御する
Projectの標準機能である「依存関係(FS: Finish-to-Start)」は、リソースの空き状況やカレンダーの制約により、時に我々の意図を超えて「勝手に」スケジュールを再計算する。これは動的なスケジュール管理としては正しい挙動だが、PMOの厳しいマイルストーン管理や、特定のビジネスロジックに基づいた厳格な固定運用においては、時に「邪魔」でしかない。
本稿では、先行タスクの完了をトリガーに、後続タスクの開始日をプログラムコードで「強制固定(ConstraintType: msoConstraintStartNoEarlierThan)」し、Projectの自律的な変動をVBAで封じ込めるアーキテクチャを解説する。
—
1. 依存関係の「動的ゆらぎ」を排除する設計思想
Projectの計算エンジンは強力だが、大規模プロジェクトでは「予期せぬ日付の連鎖」が致命傷になる。我々が構築すべきは、先行タスクの完了イベントをトリガーとし、後続タスクの制約条件をその瞬間に「固定値(Hard Constraint)」へと書き換えるイベント駆動型アーキテクチャだ。
実装の要諦
1. Applicationレベルのイベント監視: `Project_AfterTaskChange` をフックし、変更対象が先行タスクかどうかを判定する。
2. メモリ解放の徹底: オブジェクト変数の再利用と破棄を厳格に行い、巨大なプロジェクトファイル操作時のメモリリークを防ぐ。
3. APIによる制御: `ConstraintType` を `pjMSL` (Must Start On) または `pjSNET` (Start No Earlier Than) に設定し、計算ロジックをバイパスする。
—
2. 実装:強制固定ロジックの核
以下は、先行タスクが「100%完了」になった瞬間に、後続タスクの開始日をその完了日の翌日に固定するプロシージャである。
‘ プロジェクトのイベントモジュール(ThisProject)に記述
Private Sub Project_AfterTaskChange(ByVal pj As Project, ByVal Tasks As Tasks)
Dim tsk As Task
Dim succTsk As Task
‘ パフォーマンス最適化のため画面更新を停止
Application.ScreenUpdating = False
On Error GoTo Cleanup
For Each tsk In Tasks
‘ 100%完了したタスクをトリガーにする
If tsk.PercentComplete = 100 Then
For Each succTsk In tsk.SuccessorTasks
‘ 後続タスクの開始日を先行タスクの完了日の翌日に固定
With succTsk
.ConstraintType = pjSNET
.ConstraintDate = tsk.Finish + 1
‘ 固定することでProjectの自動再計算から除外する
End With
Next succTsk
End If
Next tsk
Cleanup:
‘ オブジェクトの明示的解放(VBAではNothingへの代入が鉄則)
Set tsk = Nothing
Set succTsk = Nothing
Application.ScreenUpdating = True
End Sub
—
3. シニアエンジニアが意識すべき「極限の最適化」
この実装を実戦レベルに引き上げるために、以下の技術的配慮を忘れてはならない。
メモリとパフォーマンスの管理
- イベントの再帰防止: `Project_AfterTaskChange` 内でタスクを更新すると、再びイベントが発火し、無限ループに陥るリスクがある。`Application.EnableEvents = False` を必ず前後に配置し、処理の安全性を確保すること。
- 巨大タスクリストへの対応: `For Each` は便利だが、数千タスク規模では `Tasks(i)` を用いたインデックスアクセスの方が、COMオブジェクトのオーバーヘッドを削減できる。
レガシー環境でのAPI活用
もしWindowsの外部リソース(共有ドライブの進捗ログ等)と連携する場合、`Kernel32` の `Sleep` を利用した待機や、`CreateObject(“Scripting.FileSystemObject”)` の多用は避けよ。特にProjectはシングルスレッドで動作するため、重いIO処理は「非同期プロセス」として別立てにし、VBAからはコマンドライン経由で結果を受け取るのが、システム全体をクラッシュさせないための知恵である。
—
4. チーフアーキテクトからの助言
「自動化」とは、単に手作業を置き換えることではない。「計算エンジンの暴走を、人間の意思で制御する」ことこそが、VBAプログラミングにおける真の自動化である。
このコードを実装した後は、必ず「固定されたタスク」を視覚的に識別できるよう、カスタムフィールド(Flag1等)を使って色分けを行うこと。機械は「なぜ固定したのか」を記憶しない。その文脈を保持するのは、我々設計者の責任である。
システムは、書いた通りの挙動しか示さない。しかし、書き方次第で、それは巨大なプロジェクトを制御する強靭な盾となる。健闘を祈る。
