【テクニカル・上級編】タスクの工数見積もりからリソース割り当てを自動算出する計算ロジック – Project VBA解析バイブル

スポンサーリンク

プロジェクトの死を回避する:VBAによるリソース自動割り当てエンジンの深淵

VBAを単なる「事務作業の自動化ツール」と見なしている間は、真のエンジニアとは呼べない。Project VBA、そしてMS Projectのオブジェクトモデルを掌握する者は、工数という「不可視の負債」をリアルタイムで制御するアーキテクトになれる。

今回は、タスクのWork量からリソースの稼働可能時間を逆算し、Assignment(割り当て)を自動生成するロジックの深淵に触れる。メモリリークと戦い、計算の整合性を担保する、極限のコードを提示しよう。

—

1. オブジェクトのライフサイクルとメモリの呪縛

MS Projectのオブジェクトモデル(`PJProject`, `Task`, `Assignment`)は、不適切な参照管理を行うと、たちまちメモリリークの温床となる。VBAにおいては、`.Assignment`オブジェクトを生成するたびに明示的な解放を行わなければ、COMインターフェースがメモリを食いつぶす。

‘ 悪い例: ループ内で生成し、後始末をしない
‘ 良い例: Set … = Nothing を確実に実行するスコープ設計を行う

Private Sub AssignResourceOptimized(ByRef tsk As Object, ByVal resName As String, ByVal units As Double)
Dim asn As Object
‘ オブジェクトの生成
Set asn = tsk.Assignments.Add(ResourceName:=resName, Units:=units)

‘ ここで計算ロジックを実行
‘ …

‘ 重要: COMオブジェクトの参照を即座に破棄する
Set asn = Nothing
End Sub

2. 工数見積もりと稼働率の自動算出ロジック

単純な`Work / Duration`の計算では、リソースの休暇(Calendar)や重複タスクによる負荷を無視することになる。ここでは、「利用可能時間(Available Time)」をAPI経由で取得し、オーバーアロケーションを未然に防ぐ動的ロジックを実装する。

リソースの稼働能力を算出するロジックの断片

‘ リソースの空き時間を計算し、自動割り当てを行う関数
Public Function CalculateOptimalAssignment(ByRef tsk As Object, ByRef res As Object) As Double
Dim availTime As Double
Dim workRequired As Double

workRequired = tsk.Work / 60 ‘ 分単位を時間に変換

‘ Windows API等を用いてリソースカレンダーから実稼働可能時間を取得
‘ ※ここでは簡略化しているが、実際はCalendarオブジェクトを走査する
availTime = GetResourceEffectiveAvailability(res, tsk.Start, tsk.Finish)

‘ 稼働率が100%を超える場合は調整値を返す
If workRequired > availTime Then
CalculateOptimalAssignment = availTime / workRequired
Else
CalculateOptimalAssignment = 1.0
End If
End Function

3. レガシー環境とWindows API連携の極意

プロジェクトが大規模化すると、MS Projectの標準機能だけでは計算速度が頭打ちになる。この時、Win32 API(`kernel32`)を用いてメモリ割り当てを最適化し、プロセスの優先度を動的に変更するテクニックが有効だ。

特に、`SetProcessWorkingSetSize`を呼び出し、計算処理の直後にメモリを強制解放させる手法は、長時間のバッチ処理における「VBAのフリーズ」を回避する唯一の解となる。

If VBA7 Then
Private Declare PtrSafe Function SetProcessWorkingSetSize Lib “kernel32” _
(ByVal hProcess As LongPtr, ByVal dwMinimumWorkingSetSize As LongPtr, _
ByVal dwMaximumWorkingSetSize As LongPtr) As Long
Private Declare PtrSafe Function GetCurrentProcess Lib “kernel32” () As LongPtr
End If

‘ メモリ最適化用関数: 大規模なAssignment生成後に呼び出す
Public Sub FlushMemory()
Dim hProc As LongPtr
hProc = GetCurrentProcess()
‘ メモリをOSに強制的に戻す
Call SetProcessWorkingSetSize(hProc, -1, -1)
End Sub

4. アーキテクトからの提言:自動化の真髄

リソース管理の自動化において、最も犯してはならない過ちは「ロジックの硬直化」だ。
タスクの工数見積もりは、常に揺らぐ。そのため、コードは「決定論的な出力」を目指すのではなく、「ビジネスの制約(予算・納期・スキルセット)をパラメーターとして受け取り、最適解をイテレーションする」構造にしなければならない。

1. 疎結合な計算エンジン: Assignment生成ロジックを独立したクラスモジュール(`clsAssignmentEngine`)に切り出すこと。
2. ログの可視化: どのリソースが、なぜその稼働率になったのかを必ずテキストログ(またはHiddenシート)に残すこと。ブラックボックス化された自動化は、現場の不信感を招く。
3. 例外処理の徹底: 存在しないリソース名や、不正な日付計算で止まるようでは、プロの道具とは言えない。

最後に

VBAは古い言語ではない。それは、OSの深部とアプリケーションのロジックを直結させるための、極めて鋭利なメスだ。このメスを使いこなせるかどうかは、あなたの設計思想にかかっている。

もし、リソース割り当てでプロジェクトが炎上しているなら、ツールを責める前に、その背後にある「ロジックの不整合」を見直せ。コードは、あなたの思考の写し鏡に過ぎないのだから。

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