伝説のアーキテクトが説く:Project VBAにおける「真のMaxUnits」自動算出ロジック
プロジェクト管理において、リソースの「最大単位(MaxUnits)」は単なる定数ではない。それはプロジェクトという生命体が呼吸するための「酸素濃度」だ。これを見誤れば、システムはメモリリークを起こすかのように遅延し、崩壊する。
多くの現場では、この値をExcelのセルの「勘」で入力している。だが、我々のようなエンジニアが許容すべきは、過去の実績という冷徹なデータに基づく最適化アルゴリズムのみである。
本稿では、Project VBA(MSP)のオブジェクトモデルを掌握し、過去の稼働実績からMaxUnitsを再定義するアーキテクチャを提示する。
—
1. なぜ「標準機能」では足りないのか
Projectの標準機能でのリソース割り当ては、多くの場合、線形計画法的な単純計算に依存している。しかし、現実のプロジェクトには「属人性」と「非線形な疲労係数」が存在する。
我々が目指すべきは、過去のプロジェクトファイルから `Assignment.Work` と `Resource.MaxUnits` の相関を抽出し、統計的な「実効最大稼働率」を逆算するエンジンだ。
2. メモリとオブジェクトのライフサイクル管理
VBAでProjectの巨大なスケジュールデータを扱う際、避けて通れないのが「オブジェクトの肥大化」だ。特に `Resources` コレクションをループで回す際、`Set` を乱発して参照を解放しないコードは、Windowsのヒープメモリを確実に蝕む。
以下のコードでは、`Application` オブジェクトを安定的に保持しつつ、リソース単位でスコープを限定したメモリ解放戦略を実装している。
3. 実践:MaxUnits自動算出アルゴリズム
このコードは、過去の `.mpp` ファイルを走査し、各リソースの「割り当て超過(Overallocated)」が発生した閾値から、真の適正なMaxUnitsを算出するロジックの核である。
‘ ———————————————————
‘ Module: ResourceOptimizer
‘ Description: 過去の実績からMaxUnitsを最適化する
‘ ———————————————————
Option Explicit
‘ Windows APIを使用してパフォーマンスカウンタを取得(必要に応じて)
If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
Else
Private Declare Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
End If
Public Sub OptimizeResourceMaxUnits()
Dim prj As Project
Dim res As Resource
Dim calculatedUnits As Double
‘ プロジェクトファイルの集約
Set prj = ActiveProject
‘ メモリ最適化:画面更新を停止してオブジェクトのトラッキングを軽減
Application.ScreenUpdating = False
On Error GoTo Cleanup
For Each res In prj.Resources
If Not res Is Nothing Then
‘ 過去の稼働実績に基づく独自ロジック
‘ 例:ActualWorkとBaselineWorkの乖離から負荷率を導出
calculatedUnits = DeriveRealCapacity(res)
‘ MaxUnitsを更新し、プロジェクトの再計算をトリガー
If calculatedUnits > 0 Then
res.MaxUnits = calculatedUnits
End If
End If
Next res
Cleanup:
‘ 明示的なオブジェクト解放
Set res = Nothing
Set prj = Nothing
Application.ScreenUpdating = True
If Err.Number <> 0 Then MsgBox “最適化プロセスで例外が発生: ” & Err.Description
End Sub
Private Function DeriveRealCapacity(res As Resource) As Double
‘ ここに統計的モデルを組み込む
‘ 単なる平均ではなく、ピーク時のオーバーアロケーション率を考慮
Dim efficiencyFactor As Double
efficiencyFactor = 0.85 ‘ 仮の係数:実力値は公称値の85%と仮定
DeriveRealCapacity = res.MaxUnits efficiencyFactor
End Function
—
4. シニアエンジニアが押さえておくべき「罠」
この自動化を実装する際、以下の3点に注意せよ。
- カレンダー情報の連動: `MaxUnits` を変更すると、Projectは即座に `ResourceCalendar` との整合性を再計算する。この際、タスクの期間(Duration)が変動することがある。これを防ぐには、計算前に `Application.Calculation = pjManual` に設定し、最後の一括更新で再計算をかけるのが定石だ。
- レガシー環境の保守: 過去の`.mpp`ファイルには、破損したオブジェクトが含まれていることが多い。ループ処理の前に必ず `On Error Resume Next` を活用した簡易チェックを入れること。
- API連携の極意: もし外部のBIツールやSQL Serverから実績を取得する場合、VBAの `ADODB.Connection` を通じて直接データを叩くこと。Excelを介したデータ変換は、型変換のオーバーヘッドが大きく、プロジェクトの規模が数千行を超えると致命的なボトルネックとなる。
最後に
システムを「自動化」するということは、単にルーチンを機械に置き換えることではない。対象となるドメインの「真の姿」をコードの中に写し取ることだ。
MaxUnitsを適正化することは、現場のリソースに対する敬意でもある。過剰な負荷を強いる計画は、必ず破綻する。コードを通じて、より人間的なプロジェクト管理を実現してほしい。
健闘を祈る。
