プロジェクト管理を自動化せよ:Project VBAによる「タスク階層操作」の極致
プロジェクトマネジメントにおいて、WBS(Work Breakdown Structure)のメンテナンスは「最もコストがかかり、かつ最も軽視されがちな」作業だ。Excelで練り上げた計画をProjectに転記し、階層を整える。この単純作業に時間を浪費するのは、エンジニアとしてあまりに非効率だ。
今回は、MS Projectのタスク階層(インデント・アウトデント)をプログラムから安全に、かつ「壊れない」手法で操作する極意を伝授する。
—
1. なぜ「単純な操作」でバグが生まれるのか
多くの開発者が陥る罠は、`OutlineIndent` や `OutlineOutdent` を何の制御もなしにループ内で叩くことだ。
- 無効な操作の抑止: 階層レベルが0(プロジェクトサマリー)やマイナスになるような不正な操作を弾くロジックがない。
- 選択範囲の不確実性: `ActiveSelection` に依存したコードは、ユーザーが画面を触った瞬間に予期せぬ挙動を示す。
- 依存関係の破壊: 親タスクを動かした際、それに紐づく依存関係や制約条件がどう再計算されるかを考慮していない。
真の自動化ツールは、「操作の妥当性」をプログラム側で完全に担保し、ユーザーの操作ミスを許容しない設計でなければならない。
—
2. 堅牢な階層操作のための「安全策」
プロダクションコードを書く際、私は以下の3つの鉄則を守る。
1. Selectionを排除せよ: `ActiveSelection` は使わない。操作対象の `Task` オブジェクトを直接指定する。
2. 境界チェックの徹底: 昇格(Outdent)させる際、そのタスクが既に最上位レベルにないかを確認する。
3. エラーハンドリングとログ: 予期せぬ失敗時にプロジェクト全体が破損しないよう、トランザクション的な処理を意識する。
—
3. 実装:プロフェッショナル・タスク操作メソッド
以下に、階層移動を安全に実行するためのモジュールを紹介する。これをそのままライブラリとして活用してほしい。
‘ —————————————————————————
‘ @description: タスクの階層を安全に操作するためのユーティリティクラス
‘ @author: Chief Architect
‘ —————————————————————————
Public Sub SafeIndentTask(targetTask As MSProject.Task)
‘ 階層を深くする(インデント)
‘ 前提: 親タスクが存在し、親子関係として成立可能か
On Error GoTo ErrorHandler
If targetTask Is Nothing Then Exit Sub
‘ プロジェクトサマリータスク(ID=0)はインデント不可
If targetTask.ID = 0 Then Exit Sub
targetTask.OutlineIndent
Exit Sub
ErrorHandler:
Debug.Print “Indent Error: Task ID ” & targetTask.ID & ” – ” & Err.Description
End Sub
Public Sub SafeOutdentTask(targetTask As MSProject.Task)
‘ 階層を浅くする(アウトデント)
‘ 前提: OutlineLevelが1の場合はそれ以上アウトデントしない
On Error GoTo ErrorHandler
If targetTask Is Nothing Then Exit Sub
‘ 最上位レベルなら操作をスキップする安全策
If targetTask.OutlineLevel > 1 Then
targetTask.OutlineOutdent
End If
Exit Sub
ErrorHandler:
Debug.Print “Outdent Error: Task ID ” & targetTask.ID & ” – ” & Err.Description
End Sub
このコードのポイント
- オブジェクト直接参照: `ActiveSelection` を介さず、引数で `Task` オブジェクトを受け取ることで、どのタスクを操作しているか明示的に管理できる。
- ガード節: `If targetTask.OutlineLevel > 1` を入れることで、ルートレベルへの不正アクセスを防いでいる。
—
4. 実務への応用:CSV/データベース連携時の注意点
外部データ(ExcelやSQL Serverなど)からWBSを自動生成する際は、「親タスクから順に作成し、IDを確定させてから子タスクをぶら下げる」のが鉄則だ。
- ソート順の保証: データソース側で、親→子の順に並んでいることをコード側でバリデーションする。
- 再計算の抑制: 大規模なWBSを構築する場合、`Application.Calculation = pjManual` で一旦自動計算を停止させ、全タスク構築後に `Application.CalculateAll` を呼ぶことでパフォーマンスが劇的に向上する。
—
結論:自動化は「責任」である
VBAによる自動化は、単なるコードの記述ではない。プロジェクトの計画という「経営資源」をプログラムに預ける行為だ。
もしあなたが今後ツールを作成するなら、コードの行数ではなく、「例外発生時にいかに安全に停止できるか」「後任者がメンテナンスできるほどシンプルか」に魂を注いでほしい。この階層操作のメソッドが、あなたのプロジェクトをより強固なものにすることを期待している。
さあ、退屈な手作業を自動化し、君が本来集中すべき「マネジメントの意思決定」に時間を使う準備はできたか?
