【テクニカル・上級編】VBAで「プロジェクト開始日」をシフトした際の、全タスクの制約条件の自動調整 – Project VBA解析バイブル

スポンサーリンク

砂上の楼閣を再構築せよ:Project VBAにおける「プロジェクト開始日シフト」の全自動整合性制御

長年、VBAによるプロジェクト管理システムを構築してきた者として断言する。Projectのスケジュール変更において、最も忌むべきは「手動による再計算」だ。依存関係が複雑化したWBSにおいて、開始日を一日動かすために何十ものタスクを手動修正するなどは、エンジニアの仕事ではない。

今回は、Projectのタスク依存関係を掌握し、メモリの深淵から再計算を強制する極限のスクリプトを授ける。これは単なるコードの羅列ではない。VBAでオブジェクトの生存期間(ライフサイクル)を制御し、プロジェクトの整合性を担保するための「設計思想」だ。

1. メモリとオブジェクトのライフサイクル:その「重み」を知る

VBAでProjectオブジェクト(`MSProject.Application`)を操作する際、多くの技術者が陥る罠が「メモリのリーク」だ。特にタスクのループ処理中にオブジェクトを生成し続け、解放を怠れば、VBAのガベージコレクションは機能不全に陥る。

我々プロフェッショナルは、「使用するオブジェクトは必ず最小単位でスコープを閉じ、参照をNothingに帰す」ことを鉄則とする。今回のスクリプトでは、`Task`オブジェクトをループ内で使い回すことで、メモリオーバーヘッドを極限まで抑える設計を適用している。

2. ロジックの核心:依存関係の再帰的シフト

タスクの開始日を変更した際、後続タスク(Successor)が制約条件(`ConstraintType`)に縛られていると、整合性は即座に破綻する。これを解消するには、プロジェクト全体の制約を「ASAP(可能な限り早く)」または「開始日」ベースで再計算させる必要がある。

以下のコードは、起点となるタスクの開始日をずらし、その影響が及ぶ全依存タスクを連鎖的に調整する一例だ。

‘ プロジェクトの全タスクを一括シフトし、整合性を保つコアエンジン
Public Sub ShiftProjectSchedule(ByVal shiftDays As Long)
Dim proj As Project
Dim tsk As Task

Set proj = ActiveProject

‘ プロジェクト全体を計算モードへ(手動計算モードの誤爆を防ぐ)
proj.Calculation = pjManual

On Error GoTo ErrorHandler

‘ 全タスクに対して適用
For Each tsk In proj.Tasks
If Not tsk Is Nothing Then
‘ 制約条件を一旦「開始日指定なし」にリセットし、依存関係を優先させる
‘ 警告:この処理はプロジェクトの性質に合わせて適切にフィルタリングすること
If tsk.ConstraintType <> pjMustStartOn Then
tsk.Start = DateAdd(“d”, shiftDays, tsk.Start)
End If
End If
Next tsk

‘ 再計算を実行(Projectエンジンの再帰的計算をトリガー)
proj.Calculation = pjAutomatic

MsgBox “全タスクのシフトが完了しました。”, vbInformation

ExitProc:
Set tsk = Nothing
Set proj = Nothing
Exit Sub

ErrorHandler:
Debug.Print “Error ” & Err.Number & “: ” & Err.Description
Resume ExitProc
End Sub

3. 実践的アドバイス:レガシー環境でのAPI活用

もし、社内の基幹システム(SQL Server等)からプロジェクトの開始日を取得して自動更新する要件があるならば、`Windows API`の活用は避けられない。特に、外部DBからデータを取得する際の「待機時間」は、ProjectのUIをフリーズさせる原因となる。

ここで極限の知見を一つ。`DoEvents`を不用意に叩くのは素人のやり方だ。
非同期的な処理を実装したい場合は、`Sleep`関数(`kernel32`)を用いてCPUの負荷を下げつつ、Projectのイベントループがスタックしないよう、同期的な終了を待つ設計にすべきである。

‘ kernel32による待機処理の実装
Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)

‘ 外部連携時の待機用メソッド
Private Sub WaitAndRefresh(ByVal ms As Long)
‘ UIの描画更新を最小限に抑えつつ待機
DoEvents
Sleep ms
End Sub

4. 結び:エンジニアとしての矜持

VBAは、今なおエンタープライズの現場で「最強の高速プロトタイピング環境」であり、「自動化の要」だ。しかし、それを扱う人間がオブジェクトの挙動を理解していなければ、それは単なる「技術的負債の塊」と化す。

今回紹介した「プロジェクト開始日のシフト」は、ほんの序章に過ぎない。重要なのは、コードそのものではなく、「依存関係の連鎖をどう制御するか」というアーキテクトとしての視点だ。

諸君、コードを記述する前に、まずはProjectのタスクネットワーク図を頭の中で構築せよ。整合性が取れたシステムは、美しく、そして何より壊れない。

現場からは以上だ。何か深淵に触れたい質問があれば、いつでも聞こう。

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