【Project VBA極限論】ベースラインの局所的更新:WBS階層を制御するアーキテクチャ
プロジェクト管理において、「ベースライン」は神聖な不可逆点だ。しかし、大規模プロジェクトの現場では、WBSの末端や特定のフェーズのみを再評価したいという要求が後を絶たない。標準機能の「ベースラインの保存」は全タスクを対象とするため、不用意に実行すれば全工程の過去が塗り替えられてしまう。
今回は、VBAを用いて「特定のWBSレベル以下のみ」を抽出・選択し、そのサブセットに対してのみベースラインを適用するという、高度な管理手法を伝授する。
—
1. なぜ「全保存」はリスクなのか
標準の `Application.BaselineSave` は、プロジェクトファイル全体の情報を上書きする。これは大規模なマルチユーザー環境や、複雑な依存関係を持つスケジュールにおいて、予期せぬ「履歴破壊」を招く。
我々アーキテクトが目指すべきは、「ターゲットを絞り、影響範囲を最小化する」ことだ。これには、MS Projectのオブジェクトモデルを深く理解し、メモリ上でタスクを動的に制御する技術が求められる。
—
2. 実装の要諦:オブジェクトの動的制御とメモリ管理
今回のコードでは、以下の設計思想を貫く。
1. Selectionの排他利用: プロジェクトのUI状態に依存せず、プログラム的にタスクを選択状態に遷移させる。
2. オブジェクトの明示的解放: 長大なプロジェクトファイル(数千行規模)を扱う際、VBAのガベージコレクションに頼ることは自殺行為だ。`Set Nothing` を徹底せよ。
3. WBSレベルの判定: `Task.OutlineLevel` を活用し、再帰的に条件判定を行う。
特定WBSレベル以下へのベースライン適用ロジック
‘ —————————————————————————
‘ 目的: 指定したWBSレベル以下のタスクのみを対象にベースラインを保存
‘ —————————————————————————
Public Sub ApplySelectiveBaseline(ByVal TargetLevel As Integer)
Dim proj As Project
Dim tsk As Task
Dim selectedTasks As Collection
Set proj = ActiveProject
Set selectedTasks = New Collection
On Error GoTo Cleanup
‘ 1. 既存の選択状態をクリア(パフォーマンスと誤操作防止)
SelectBeginning
‘ 2. 特定レベル以下のタスクを特定し、メモリ上のコレクションに格納
For Each tsk In proj.Tasks
If Not tsk Is Nothing Then
If tsk.OutlineLevel >= TargetLevel Then
‘ プロジェクトの選択状態を操作(SelectTaskFieldは負荷がかかるため最小限に)
SelectTaskField Row:=tsk.ID, Column:=”Name”, Append:=True
End If
End If
Next tsk
‘ 3. 選択されたタスクに対してベースラインを実行
‘ AllSelectedTasks: True を指定することで、現在選択されている行のみを対象とする
Application.BaselineSave SaveOption:=pjBaselineSaveSelected, _
AllSelectedTasks:=True, _
BaselineNumber:=pjBaseline1
MsgBox “ベースライン適用完了:レベル ” & TargetLevel & ” 以下の範囲”, vbInformation
Cleanup:
‘ 4. メモリ解放の徹底
Set tsk = Nothing
Set proj = Nothing
Set selectedTasks = Nothing
If Err.Number <> 0 Then
MsgBox “エラー発生: ” & Err.Description, vbCritical
End If
End Sub
—
3. シニアエンジニアが意識すべき「裏側の挙動」
Windows APIとパフォーマンスの壁
大規模なプロジェクトファイルでこのマクロを走らせると、`SelectTaskField` の呼び出しコストが無視できなくなる。数千タスクある場合、GUIへの描画更新がボトルネックとなるのだ。
真のプロフェッショナルは、ここで `Application.ScreenUpdating = False` を活用する。これにより、描画処理を抑制し、処理速度を劇的に向上させることが可能だ。
レガシー環境の保守性
もしあなたが古いMS Project(2010/2013等)を扱う現場にいるなら、`BaselineSave` の引数に注意が必要だ。`pjBaselineSaveSelected` は比較的安定しているが、旧バージョンではタスクの並び順がメモリ上で断片化していると、予期せぬタスクが選択範囲に含まれるケースがある。必ず `SelectBeginning` でカーソルを初期化してから処理を開始せよ。
—
4. チーフアーキテクトからの助言
VBAは、MS Projectを「単なる管理ツール」から「エンジニアリングプラットフォーム」へと昇華させるための強力な武器だ。今回紹介したフィルタリング技術は、大規模組織のPMOが求める「部分最適と全体最適の調和」を実現するための第一歩に過ぎない。
次にあなたが追求すべきは、「ベースライン保存前の比較検証(Diff)」の実装だ。`Task.BaselineStart` と現行の `Task.Start` を比較するロジックをこのコードに組み込めば、変更履歴の追跡はより堅牢なものとなる。
技術を磨き続けろ。コードこそが、プロジェクトという混沌を統制する唯一の規律なのだから。
