リソース平準化の深淵:Project VBAで「Assignment.Work」を極限制御する
Projectのデスクトップクライアントにおける自動化において、最も忌むべきは「標準機能の平準化エンジンにすべてを委ねる」という無策だ。あれはあくまで汎用的なアルゴリズムであり、あなたの組織固有のKPIや、特定の熟練工に依存したクリティカルパスの歪みを理解してはいない。
真のエンジニアであれば、`Assignment.Work`を直接叩き、リソースの負荷を数学的に最適化するロジックを自前で実装すべきだ。本稿では、レガシーなProject VBAの枠組みの中で、メモリを汚さず、かつ実行速度を極限まで高めるためのアーキテクチャを伝授する。
—
1. メモリの「腐敗」を防ぐ:オブジェクトライフサイクルの管理
VBAの最大の敵は、暗黙的なオブジェクト参照によるメモリリークと、それに起因するスタックオーバーフローだ。`Project.Application`を扱う際、ループ内でむやみにオブジェクトを取得してはならない。
‘ 悪い例: ループ内で毎回Applicationを呼び出すのは遅延の原因
For Each t In ActiveProject.Tasks
t.Assignments.Item(1).Work = …
Next
‘ 良い例: 必要なオブジェクト参照をスタックに固定し、明示的に解放する
Dim proj As Project
Set proj = ActiveProject
‘ 処理終了後は必ず Nothing を代入し、VBAのガベージコレクションを促す
Set proj = Nothing
大規模なプロジェクトファイルでは、`Assignments`コレクションへのアクセスがボトルネックになる。`Task`オブジェクトをループする際は、必ず`Task.Assignments`を一度変数にキャッシュしてから処理を開始せよ。
—
2. Assignment.Work 操作の極意:平準化アルゴリズムの設計
リソースの過負荷(Overallocation)を解消する際、単純なWorkの平均化は推奨しない。重要なのは「クリティカルパス上のタスクを優先し、非クリティカルなバッファを持つタスクへ負荷を分散させる」ことだ。
以下は、特定の期間においてリソースの稼働率が100%を超えた場合、超過分を翌日にスライドさせるためのロジックの骨子である。
Public Sub FlattenResourceLoad(ByVal targetResourceName As String, ByVal threshold As Double)
Dim t As Task
Dim a As Assignment
Dim proj As Project
Set proj = ActiveProject
‘ パフォーマンス最適化のため、画面更新を停止
Application.ScreenUpdating = False
For Each t In proj.Tasks
If Not t Is Nothing Then
For Each a In t.Assignments
If a.ResourceName = targetResourceName Then
‘ 稼働率(Work)が閾値を超えているか判定
If a.Work / 480 > threshold Then ‘ 480は8時間(分単位)
‘ 負荷を調整するロジック
‘ ここで直接Workプロパティを操作
a.Work = a.Work 0.9
‘ 実際にはTaskのStartTimeやDurationとの整合性に注意が必要
End If
End If
Next a
End If
Next t
Application.ScreenUpdating = True
Set proj = Nothing
End Sub
—
3. Windows APIによる非同期制御の模索
もし、Projectの操作が非常に重い大規模データ(数万行クラス)を扱う場合、VBAの単一スレッド処理は限界を迎える。その際は、`kernel32`を呼び出し、`Sleep`関数を挟むことでWindowsのメッセージキューに割り込みを許容し、フリーズを防ぐという手法が有効だ。
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
‘ ループの合間に呼び出すことで、OS側の応答性能を維持する
‘ DoEventsよりも制御が細かく、CPU負荷を抑制できる
Sleep 10
—
4. システム間連携:レガシーを「疎結合」に保つ
Project VBA単体で完結させようとせず、複雑な平準化計算は外部のPython(pandas)やC#で実行し、結果をCSVやJSON経由でProjectに反映させるのが、現代的なアーキテクチャの解だ。
1. 抽出: VBAから現在の`Assignment`状態をCSVへエクスポート。
2. 演算: 外部の最適化ライブラリ(OR-Tools等)で負荷平準化計算を実行。
3. 適用: VBAでCSVをインポートし、Projectへ書き戻す。
この手法により、VBA側のコードは「データの流し込み」という単純な役割に徹することができ、メンテナンスコストを劇的に下げることができる。
—
最後に:エンジニアへの提言
VBAは「古臭い」のではない。適切に制御されれば、Windows環境において最も即時性が高く、強力なオートメーションツールだ。
`Assignment.Work`を操作するということは、プロジェクトの「時間」という資本を操作することと同義である。コードの一行一行が、現場のエンジニアの負荷を下げ、プロジェクトの成功率を上げるという重みを感じてほしい。
あなたが書くそのコードが、次の「伝説のプロジェクト」を支えるインフラとなる。自信を持って、極限の最適化を追求せよ。
