Project VBAの深淵へ:リソース過負荷を自動検知し、最適化する「守護者」の作り方
こんにちは。プロジェクト管理の自動化を追求するエンジニアの皆さん。
「マクロの記録」から一歩踏み出し、プロジェクトを自在に操るVBAの深淵へようこそ。
今回は、現場で最も頭を悩ませる「特定のメンバーに仕事が集中し、パンクする」という事象を、VBAの力で自動的に平準化するロジックを伝授します。単なるツール作りではなく、プロジェクトという「生き物」を最適化するアーキテクトの視点をお伝えしましょう。
—
1. なぜ「自動再割り当て」が必要なのか?
Project VBAにおいて、リソースの稼働率(Peak Units)は単なる数値ではありません。それはメンバーの命の灯火です。
- 100%超えの警告: 複数のタスクが重なり、リソースが「過負荷(Overallocated)」状態になると、プロジェクト全体のクリティカルパスが崩れます。
- 機械的な再割り当ての罠: 人力で調整すると、スキルの適合性や優先順位を見失いがちです。
私たちが目指すのは、「負荷を検知し、空きのあるリソースへタスクを押し出す(=平準化する)アルゴリズム」です。
—
2. 核心:リソースの「空き」をどう計算するか
Project VBAで最も重要なオブジェクトは `Resource` と `Assignment` です。
`Assignment.Work`(作業時間)と `Resource.Calendar` を組み合わせることで、そのリソースが「いつ、どれだけ空いているか」を逆算できます。
陥りやすい罠:単なる「100%」という幻想
Project VBAの `Resource.PeakUnits` を見るだけでは不十分です。WorkContour(作業配分)を考慮しないと、特定の期間だけ突き抜けている「局所的な過負荷」を見逃します。
—
3. 実践:リソース最適化ロジックの構築
以下は、過負荷なリソースを検出し、代替リソースへタスクを転送するロジックの骨子です。
Sub AutoRescheduleOverloadedTasks()
Dim tsk As Task
Dim asn As Assignment
Dim rsc As Resource
Dim altRsc As Resource
‘ プロジェクト内の全タスクを巡回
For Each tsk In ActiveProject.Tasks
If Not tsk Is Nothing Then
For Each asn In tsk.Assignments
‘ 稼働率が100%を超えているかチェック
‘ ※本来はTimephasedDataで期間ごとの負荷を見るのがベスト
If asn.Units > 1 Then
Debug.Print “過負荷検知: ” & tsk.Name & ” (担当: ” & asn.ResourceName & “)”
‘ 代替リソースを探す(この例では単純なスキル属性比較を想定)
Set altRsc = FindAvailableResource(asn)
If Not altRsc Is Nothing Then
‘ タスクを新しいリソースへ再割り当て
asn.ResourceName = altRsc.Name
Debug.Print “転送完了: ” & altRsc.Name & ” へ割り当てました。”
End If
End If
Next asn
End If
Next tsk
End Sub
‘ 代替リソースを探索する関数
Function FindAvailableResource(currentAsn As Assignment) As Resource
Dim r As Resource
For Each r In ActiveProject.Resources
‘ 稼働率が100%未満のリソースを探す(簡易的な判定)
If r.PeakUnits < 1 Then
Set FindAvailableResource = r
Exit Function
End If
Next r
End Function
コードの解説
1. `ActiveProject.Tasks` の巡回: プロジェクト全体を俯瞰する基本のループです。
2. `asn.Units > 1`: ここが「100%」の閾値です。Project VBAでは1.0が100%を意味します。
3. `FindAvailableResource`: ここが「判断の脳」です。今回は単純な稼働率で見ましたが、実際には `Resource.Notes` やカスタムフィールドでスキルタグを管理し、一致するものを選ぶように拡張するのが現場の定石です。
—
4. 現場で使える「プロの知見」
エラーを回避する「防壁」
- Nothing判定: `For Each` ループでは、削除されたタスクや空のオブジェクトに触れると即座にエラーになります。必ず `If Not tsk Is Nothing Then` を入れましょう。
- Undo(取り消し)の考慮: 自動化は強力ですが、一瞬でプロジェクトを破壊する危険もあります。実行前に `Application.UndoBlockStart` を入れることで、失敗した際に「Ctrl+Z」で一括復旧できるようにするのが、ベテランの作法です。
パフォーマンスの極意
リソース数やタスク数が多い場合、ループの中で `ActiveProject` に何度もアクセスするのは非効率です。必要なデータは一度メモリ(配列)に読み込んでから処理するだけで、実行速度は10倍変わります。
—
最後に:自動化は「対話」である
今回紹介したコードは、あくまで「自動化の種」です。
本当に優れたプロジェクトマネージャーは、VBAにすべてを任せるのではなく、「VBAが提案した再割り当て案を人間が承認する」というフローを構築します。
「ここをクリアすれば、Project VBAの基本はバッチリ」です。
まずはこのコードをデバッグウィンドウで追いかけながら、リソースの動きを観察してみてください。次は、特定のリソースカレンダーを考慮した、より緻密な負荷分散に挑戦してみましょう。
皆さんのプロジェクトが、より円滑に進むことを願っています。質問があれば、いつでも現場の熱量を持ってコメントしてくださいね。
