【入門編】【中級者向け】WBSの階層構造を再帰関数で走査し、親タスクの進捗率を子タスクから自動計算する – Project VBA解析バイブル

スポンサーリンク

【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を操る側」のエンジニアです。応援しています!

タイトルとURLをコピーしました