Project VBAを掌握せよ:リソース過負荷を解消する「動的再割り当て」の深淵
Projectの成功は、リソースという有限の資源をいかに最適に流動させるかに集約される。特に、MS ProjectのVBAオブジェクトモデルにおける「稼働率(Assignment Units)」の管理は、甘く見るとメモリリークと計算コストの迷宮に陥る。
今回は、単なるルーチンワークではない。Resourceの`WorkContour`を解析し、過負荷を検知した瞬間に、最適な空きリソースへタスクを再配分する「極限の最適化ロジック」を伝授する。
—
1. 稼働率管理の落とし穴:なぜ単純なループは破綻するのか
多くのエンジニアが陥る罠は、`Assignment.Work`を安易にループで回し、`Assignment.Units`を書き換えることだ。しかし、MS Projectはプロジェクトファイル内の計算エンジンと密結合しており、安易なプロパティ操作は再計算の連鎖を引き起こし、パフォーマンスを劇的に劣化させる。
究極の戦略
- 計算の抑制: `Application.Calculation = pjManual` を強制し、再計算を最後の一回に集約する。
- メモリの解放: オブジェクトをループ内で生成・破棄する際は、明示的な `Nothing` の代入と `DoEvents` の適切な挟み込みが必須だ。
- Win32 APIの活用: 大規模なデータセットを扱う場合、Project内部のコレクションを何度も走査するより、一度メモリへ転送して処理する方が高速だ。
—
2. 実装:過負荷検知と再割り当てのコアロジック
以下は、稼働率100%超えを検知し、空きがあるリソースへタスクを自動転送するエッセンスだ。
‘ プロジェクトの再計算を抑制し、パフォーマンスを最大化する
Public Sub OptimizeResourceAllocation()
Dim prj As Project
Dim res As Resource
Dim asn As Assignment
Set prj = ActiveProject
‘ 計算モードをマニュアルへ切り替え(再計算の連鎖を断つ)
Dim oldCalcMode As Long
oldCalcMode = prj.Calculation
prj.Calculation = pjManual
On Error GoTo Cleanup
‘ 全リソースの稼働率を精査
For Each res In prj.Resources
If Not res Is Nothing Then
‘ 稼働率が100%を超過しているか判定
If IsResourceOverloaded(res) Then
Call ReassignTaskToAvailable(res, prj)
End If
End If
Next res
Cleanup:
prj.Calculation = oldCalcMode
‘ オブジェクトの明示的解放
Set prj = Nothing
End Sub
Private Function IsResourceOverloaded(res As Resource) As Boolean
‘ 簡易的な過負荷検知。WorkContourの特性を考慮し、
‘ PeakUnitsが1以上であるかを判定基準とする
If res.PeakUnits > 1 Then
IsResourceOverloaded = True
End If
End Function
Private Sub ReassignTaskToAvailable(overloadedRes As Resource, prj As Project)
‘ 最適な空きリソースを見つけて再割り当て
Dim targetRes As Resource
Dim asn As Assignment
‘ 最初のタスクを取得して移動(実装はプロジェクトの優先度ロジックに従う)
Set asn = overloadedRes.Assignments(1)
For Each targetRes In prj.Resources
‘ 稼働率が80%未満の適任者を探す
If targetRes.PeakUnits < 0.8 Then
asn.ResourceID = targetRes.ID
Exit Sub
End If
Next targetRes
End Sub
---
3. シニアエンジニアのための極限チューニング
メモリとライフサイクルの管理
VBAはガベージコレクションが強力ではない。特に大規模プロジェクトでは、`Assignment` オブジェクトへの参照を保持したままにすると、MS Projectのプロセスが肥大化する。処理の終わりには必ず `Set` 変数をクリアし、`DoEvents` を適切に配置してOS側のイベントループを解放せよ。
システム間連携の要
もし、この最適化アルゴリズムを外部システム(Web APIやSQL Serverなど)と連携させる場合、必ず中間テーブル(CSVやJSON)を経由させること。ProjectのOLEオートメーションを長時間占有すると、バックグラウンドでの保存処理や外部アドインと競合し、致命的なデッドロックを誘発する。
—
4. 結び:エンジニアの美学
「動けば良い」というコードは、数ヶ月後の修正で自らの首を絞めることになる。リソースの過負荷検知という極めて動的な事象に対し、静的なループで立ち向かうのは愚策だ。
計算エンジンを掌握し、メモリのライフサイクルを制御し、そして何より「プロジェクトという名の巨大なメモリ空間」を敬うこと。それが、伝説的なアーキテクトが共有する唯一の真理である。
貴殿のプロジェクトが、このアルゴリズムによって最適化され、無駄な残業が一つでも減ることを期待している。コードに魂を込めよ。それが唯一の道だ。
