【Project VBA極意】再帰関数で操るWBS:サマリータスクの進捗率を自動計算する
こんにちは。現場の最前線でコードを書き続けるエンジニアです。
Project VBAを触り始めると、誰もが一度は「タスクの進捗率を、配下のタスクから自動で計算できないか?」という壁にぶつかります。手動で入力してはズレが生じ、メンテナンスに追われる……そんな日々は今日で終わりにしましょう。
今回は、Project VBAにおける「再帰処理」という最強の武器を使って、WBSの階層構造を魔法のように駆け巡り、サマリータスクを自動計算する極上のロジックを伝授します。
—
1. なぜ「再帰関数」なのか?
WBS(Work Breakdown Structure)は、ツリー構造です。親タスクの中に子タスクがあり、その中にさらに孫タスクがある……。この階層の深さはプロジェクトによってバラバラですよね。
ここで「繰り返し処理(Forループ)」だけで対応しようとすると、階層が変わるたびにコードを書き直す羽目になります。そこで登場するのが「自分自身を呼び出す関数」=「再帰関数」です。
再帰関数は、「自分の配下に子がいるなら、その子に計算を任せる。もし子がいなければ、自分の進捗を返す」というシンプルなルールで、どんなに深い階層でも自動的に走査してくれます。
—
2. 実装コード:魂を込めた再帰ロジック
以下のコードは、選択したサマリータスク配下の進捗率を、子タスクの重み付け(今回は単純平均)で計算するモジュールです。
‘ Project VBA: サマリータスクの進捗自動計算エンジン
Sub CalculateSummaryProgress()
Dim selTask As Task
‘ 選択したタスクを起点にする
If ActiveSelection.Tasks.Count = 0 Then Exit Sub
Set selTask = ActiveSelection.Tasks(1)
‘ 再帰的に進捗を計算して書き戻す
Call UpdateProgressRecursive(selTask)
MsgBox “進捗計算が完了しました。”, vbInformation
End Sub
‘ 再帰関数本体
Function UpdateProgressRecursive(t As Task) As Double
Dim child As Task
Dim totalProgress As Double
Dim childCount As Integer
‘ 子タスクが存在しない場合(末端タスク)
If t.OutlineChildren.Count = 0 Then
UpdateProgressRecursive = t.PercentComplete
Exit Function
End If
‘ 子タスクが存在する場合、再帰的に計算を依頼
totalProgress = 0
childCount = t.OutlineChildren.Count
For Each child In t.OutlineChildren
totalProgress = totalProgress + UpdateProgressRecursive(child)
Next child
‘ 子タスクの平均値で親の進捗を更新(ここで重み付けを変えることも可能)
t.PercentComplete = totalProgress / childCount
‘ 呼び出し元に自分の値を返す
UpdateProgressRecursive = t.PercentComplete
End Function
—
3. コードの読み解き:ここが極限のポイント
このコードには、エンジニアとして押さえておきたい3つのエッセンスが詰まっています。
1. `t.OutlineChildren` の利用:
Projectオブジェクトにおいて、これが「直下の子タスク」にアクセスする唯一無二のプロパティです。これを知っているだけで、タスク操作の柔軟性が劇的に上がります。
2. 再帰の脱出条件:
`If t.OutlineChildren.Count = 0` が重要です。これがないと、関数が自分自身を呼び出し続けてスタックオーバーフロー(メモリ不足)を起こします。再帰を書くときは、必ず「どこで止まるか」を最初に定義してください。
3. 戻り値の活用:
関数自体に進捗率を計算させ、それを親へ引き渡すことで、計算結果がボトムアップで伝搬していく仕組みです。
—
4. 陥りやすいエラーと対策
- 「計算対象が多すぎて遅い」問題:
Projectのタスク数が多い場合、この処理を走らせる前に `Application.ScreenUpdating = False` を記述しましょう。画面描画を止めるだけで、処理速度は数倍に跳ね上がります。
- サマリータスクの「手動入力」との競合:
通常、Projectではサマリータスクの進捗は自動計算されます。もしこのマクロを使う場合は、「サマリータスクの自動計算を無効にする設定」と組み合わせて運用するのがプロの定石です。
—
最後に:自動化の先にあるもの
この再帰ロジックをマスターすれば、進捗計算だけでなく、工数の合計や、特定のリソースがアサインされているタスクの抽出など、あらゆる「階層構造の走査」に応用が利きます。
「マクロの記録」の向こう側には、こうした美しいロジックの世界が広がっています。まずはこのコードをコピーして、ご自身のプロジェクトの小さなセクションで試してみてください。
ここをクリアすれば、あなたはもう「Project VBAを操る側」のエンジニアです。応援しています!
