大規模WBSの断絶を許すな:Project VBAによる「階層切り出し」と「依存関係継承」の極意
プロジェクトが肥大化し、数千行を超えるWBS(Work Breakdown Structure)を扱うとき、単一の `.mpp` ファイルはもはや「爆弾」でしかない。レスポンスの低下、予期せぬリンク切れ、そして共有時の排他制御。これらに苦しむ諸君に、現場のエンジニアとして断言する。
「大規模プロジェクトは、物理的に分割せよ。ただし、論理的な依存関係を殺してはならない。」
今日は、Project VBAを用いて特定の階層を別ファイルへ抽出し、かつ先行タスク・後続タスクのリンク情報を堅牢に維持する方法を伝授する。
—
なぜ「手作業のコピペ」が地獄を招くのか
多くの現場で、WBSの切り出しを「手動のコピー&ペースト」で行っている。これがいかに危険か、理解しているだろうか。
1. Unique IDの不整合: Projectのリンク情報は `UniqueID` を参照している。コピペで新しいファイルに貼り付ければ、IDが再採番され、先行タスクとの論理関係が瞬時に崩壊する。
2. リソース情報の乖離: 割り当てられたリソースの単価やカレンダー情報が親ファイルと乖離し、プロジェクト全体のコスト算出が破綻する。
3. リンクの未定義: 外部ファイルへのリンク設定を怠れば、クリティカルパスが途切れ、プロジェクト全体の進捗管理が不可能になる。
この問題を解決するには、「プロジェクト全体の構造をオブジェクトとして捉え、Linkオブジェクトを介したマッピング」を行うしかない。
—
プロダクションコード:階層抽出&リンク保持モジュール
以下は、選択した階層を別ファイルとして保存しつつ、外部参照としてのリンクを疑似的に維持するためのプロトタイプだ。
Option Explicit
‘ 選択したタスクの階層を別ファイルに切り出し、依存関係を保持する
Sub ExportSelectedTasksToNewProject()
Dim app As Object
Dim projSource As Project
Dim projTarget As Project
Dim tsk As Task
Dim newTsk As Task
Set projSource = ActiveProject
‘ 新規プロジェクトの作成
Set projTarget = FileNew(False)
‘ 選択タスクのコピー&ペースト(※ここでは実装を簡略化しているが、
‘ 本来はTask.Copy後にPasteし、UniqueIDをマッピングテーブルで管理する)
‘ 【重要】リンクの再構築ロジック
Dim pred As TaskDependency
For Each tsk In ActiveSelection.Tasks
‘ 対象タスクの先行タスクをループ
For Each pred In tsk.TaskDependencies
‘ ここで外部参照情報を付与するか、
‘ ファイル間のパスを含めたリンク情報を別テーブル(DB)で管理する
Debug.Print “依存関係検出: ” & pred.From.Name & ” -> ” & tsk.Name
Next pred
Next tsk
‘ 保存処理:メタデータとして親ファイルのパスを埋め込む
projTarget.ProjectSummaryInfo.Comments = “ParentFile: ” & projSource.FullName
projTarget.SaveAs “C:\Projects\Split_” & Format(Now, “yyyymmdd_hhnn”) & “.mpp”
MsgBox “切り出し完了。依存関係の再構築には外部DB参照を推奨する。”
End Sub
—
堅牢な設計のための3つの鉄則
1. Unique IDではなく「GUID」で追跡せよ
`UniqueID` はファイルが変われば変わる。しかし、Projectオブジェクトが保持する `GUID` は、ファイルを跨いでもプロジェクト内の個体を一意に特定できる。依存関係を記録する際は、必ず `Task.GUID` をキーにしてデータベース(AccessやSQL Server)に書き出すこと。これが、リンク切れを永久に防ぐ唯一の手段だ。
2. ファイルをまたぐリンクは「外部プロジェクトリンク」として扱う
MS Project標準の「プロジェクト間のリンク」機能は不安定だ。大規模運用では、「ハブ&スポーク型」の構成を採用せよ。
- ハブファイル: 全体のマイルストーンのみを管理。
- スポークファイル: 各階層の詳細WBSを管理。
各ファイルは共通の「リソースプール」を参照させ、リンク情報はアドインで定期的に同期させるのが、最もバグの少ない設計である。
3. エラーハンドリングの徹底(ライフサイクルの管理)
Project VBAにおいて `ActiveProject` や `ActiveSelection` を連呼するのはNGだ。大規模な処理を行う際は、必ずオブジェクト変数を宣言し、`Set` して `Nothing` で解放する。メモリリークは、MS Projectをクラッシュさせる最大の要因だ。
—
伝説のアーキテクトからのアドバイス
「ツールを作ること」は手段に過ぎない。君たちが目指すべきは、「誰が操作してもプロジェクトの整合性が壊れない仕組み」を構築することだ。
もし、この自動化をさらに推し進めたいなら、次は「Excelの定義ファイルからWBSを生成し、かつ依存関係を自動構築するインポーター」の実装に挑むといい。UI/UXを切り離し、コアとなるロジックをクラスモジュールに閉じ込める。それが、真に保守可能な「業務自動化」の姿だ。
コードをコピペして満足するな。そのコードが、3年後の君のチームを救う武器になるよう、常に設計思想を磨き続けろ。健闘を祈る。
