Project VBAを掌握せよ:タスク依存関係をコードで支配する「Predecessors」の極意
Project VBA(Microsoft Project Object Model)の世界へようこそ。
多くの初心者は、UI上の「リンク」ボタンをポチポチと押す作業から卒業できず、大規模なWBSの構築をExcelからのコピペに頼っている。だが、我々が扱うべきは「動的なプロジェクト管理」だ。
今回は、タスク間の依存関係をプログラムで制御する心臓部、`Predecessors`(前提条件)プロパティの操作術を伝授する。ただコードを動かすだけではない。メモリの残滓を許さず、将来のエンハンスにも耐えうる「伝説のコード」の書き方を叩き込む。
1. なぜ「Predecessors」の直書きは危険なのか?
`Task.Predecessors` プロパティに文字列を代入するのは最も手軽だが、それは「プロ」のやり方ではない。文字列の解析(Parsing)は計算コストを浪費し、タスクIDのズレに極めて脆弱だ。
真に熟練したエンジニアは、`Task.TaskDependencies.Add` メソッドを用いる。これにより、依存関係は一級市民(ファーストクラス・オブジェクト)として扱われ、プロジェクト全体の整合性が担保される。
2. 実践:依存関係自動構築の「極限実装」
以下のコードは、単にリンクを貼るだけではない。オブジェクトの明示的な解放、エラーハンドリングの徹底、そしてメモリリークを未然に防ぐアーキテクチャを意識している。
Option Explicit
‘ ———————————————————
‘ @brief タスク間のFS依存関係を構築するプロフェッショナル・実装
‘ @param targetTask 依存先となるタスクオブジェクト
‘ @param predTask 依存元となるタスクオブジェクト
‘ ———————————————————
Public Sub AddFSLink(ByRef targetTask As MSProject.Task, ByRef predTask As MSProject.Task)
‘ オブジェクトの有効性チェック:Null参照によるシステムクラッシュを未然に防ぐ
If targetTask Is Nothing Or predTask Is Nothing Then Exit Sub
On Error GoTo ErrHandler
‘ TaskDependenciesコレクションへ明示的に追加
‘ pjFinishToStart(0)を指定し、FS関係を固定する
targetTask.TaskDependencies.Add From:=predTask, Type:=pjFinishToStart
Exit Sub
ErrHandler:
‘ ログ出力やエラーハンドリングをここに集約
Debug.Print “Error: ” & Err.Description & ” (Task ID: ” & targetTask.ID & “)”
End Sub
‘ ———————————————————
‘ @brief メモリ最適化を意識したメイン処理例
‘ ———————————————————
Public Sub BuildProjectSchedule()
Dim proj As MSProject.Project
Dim t1 As MSProject.Task, t2 As MSProject.Task
Set proj = ActiveProject
‘ タスクを特定(IDによる直接参照は高速だが、動的変動に注意)
Set t1 = proj.Tasks(1)
Set t2 = proj.Tasks(2)
Call AddFSLink(t2, t1)
‘ オブジェクトの明示的解放:VBAのGCを待つな
Set t1 = Nothing
Set t2 = Nothing
Set proj = Nothing
End Sub
3. シニアエンジニアが意識すべき「隠れた仕様」
オブジェクトのライフサイクル管理
VBAはCOMベースの言語だ。`Set` をしたオブジェクトは参照カウントが増加する。ループ処理内でタスクを操作する場合、必ずループの最後で `Set = Nothing` を実行せよ。これを怠れば、数千行のWBSを操作する際にProjectの動作は劇的に重くなる。
Windows APIの併用(高度な制御)
大規模なプロジェクトにおいて、画面の描画更新(`Application.ScreenUpdating = False`)を停止させるのは基本だが、さらに一歩進むなら、Windows APIを用いてProjectのウィンドウハンドルを制御し、バックグラウンドでの同期計算を一時停止させる手法も有効だ。計算ロジックが走るたびに再描画が行われるのは、リソースの無駄遣いである。
レガシー環境との対話
もし貴方が、古い.mppファイルやSQL Serverで管理されたエンタープライズ環境にいるなら、`Predecessors` の値は `TaskDependencies` コレクションを経由せず、直接 `Task.Predecessors` 文字列を書き換える手法が必要になるケースがある。しかし、それは「最終手段」だ。可能な限りコレクション・オブジェクト経由で操作し、整合性を保つこと。
結論:コードは「生き物」である
WBSは一度作って終わりではない。要件変更とともに依存関係は組み変わる。
「動けばいい」という考えは、明日には負債になる。オブジェクトの寿命を制御し、例外を叩き潰し、そして何より「プロジェクトの構造」をコードで表現する。
この技術を体得したとき、貴方は単なるVBAユーザーではなく、プロジェクトの構造そのものを司るアーキテクトへと進化しているはずだ。
次は、タスクの「制約(Constraints)」と「カレンダー」を組み合わせた、より深い階層の自動化について掘り下げるとしよう。準備はいいか。
