Project VBAを掌握する:リソース稼働率の「予実乖離」を可視化する極限の実装論
プロジェクトマネジメントにおいて、MS ProjectのVBA操作は「地雷原」だ。安易にオブジェクトを生成し、ループを回せば、メモリリークとCOMサーバーのハングアップが諸君を待ち受けている。
今回は、Projectの「稼働率(Assignment Units)」を監視し、プロジェクトの崩壊を未然に防ぐための「予実乖離ダッシュボード」の構築論を説く。これは単なるコードの提供ではない。巨大なレガシーシステムを沈没させないための、アーキテクトとしての心得である。
—
1. なぜ「標準機能」では不十分なのか
MS Projectの標準レポートは、過去の視認には優れているが、「予実乖離の予兆検知」には向いていない。我々が求めるのは、「現在のBaselineと実際のWork(実績工数)の差分」を、リソースの稼働率として瞬時に抽出し、ボトルネックを可視化する動的な仕組みだ。
ここで注意すべきは、`ActiveProject.Assignments`への無防備なアクセスだ。数千行のタスクを回せば、ExcelやProjectのCOMインターフェースは容易にスタックする。
2. メモリ最適化とCOM解放の鉄則
VBAにおいて「オブジェクトをNothingにする」だけでは不十分だ。Project VBAでは、`Application`や`Project`オブジェクトへの参照を保持したままループを回すと、Windowsのプロセス内でCOM参照カウントが肥大化し、最悪の場合、OSレベルでメモリが開放されない。
実装の極意:オブジェクトの完全解放
‘ 必要な参照を最小限に絞り、明示的に解放する
Public Sub CleanUpProjectData()
Dim proj As Project
Dim res As Resource
Dim asn As Assignment
Set proj = ActiveProject
‘ ここで重要なのは、内部ループでのオブジェクト生成を避けること。
‘ 可能な限りIDやインデックスでアクセスし、参照保持を最小化する。
For Each res In proj.Resources
‘ リソース単位の処理
DoEvents ‘ UIスレッドを殺さないための最低限の配慮
Next res
‘ 参照の破棄は生成と逆順に行う
Set asn = Nothing
Set res = Nothing
Set proj = Nothing
End Sub
—
3. 予実乖離可視化エンジン:核心コード
以下のコードは、リソースごとの「予定工数(Baseline Work)」と「実績工数(Actual Work)」を抽出し、稼働率の乖離を算出するロジックだ。
‘ プロジェクトの全リソースに対して予実乖離を算出
Public Sub CalculateResourceVariance()
Dim proj As Project: Set proj = ActiveProject
Dim res As Resource
Dim bLineWork As Double, actWork As Double
Dim variance As Double
‘ 画面更新を停止してパフォーマンスを極限まで引き上げる
Application.ScreenUpdating = False
For Each res In proj.Resources
‘ リソースが割り当てられていない場合はスキップ
If Not res Is Nothing Then
‘ Baseline Workは分単位で保持されるため、時間単位(60分)に変換
bLineWork = res.BaselineWork / 60
actWork = res.ActualWork / 60
‘ 乖離率の算出 (0除算対策は必須)
If bLineWork > 0 Then
variance = (actWork – bLineWork) / bLineWork
‘ 乖離が20%を超えたらフラグを立てる(ダッシュボード用のフラグ付け)
If variance > 0.2 Then
res.Notes = “【警告】予実乖離: ” & Format(variance, “0.0%”)
End If
End If
End If
Next res
Application.ScreenUpdating = True
MsgBox “稼働率監視プロセス完了”, vbInformation
End Sub
—
4. シニアエンジニアへの提言:システム間連携の罠
このロジックをExcelダッシュボードに反映させる場合、「直接的なProject-Excel間連携」は避けるべきだ。
1. 中間ファイル方式の採用: 巨大なProjectファイルをExcelが直接読み込むと、COMの同期でロックが発生する。Project側でCSV/XMLに書き出し、Excel側でPower Queryを用いて取り込むのが、現代的なアーキテクチャの基本だ。
2. Windows APIの活用: もし大規模なプロジェクトでProjectの起動時間が問題になるなら、`FindWindow` APIを使用して、既にProjectが開かれているかを判定し、多重起動によるリソース枯渇を防止せよ。
Windows APIによるプロセス管理のヒント
If VBA7 Then
Private Declare PtrSafe Function FindWindow Lib “user32” Alias “FindWindowA” (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Else
Private Declare Function FindWindow Lib “user32” Alias “FindWindowA” (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
End If
結びに:レガシーを「武器」に変える
VBAは死んだ技術ではない。MS Projectという巨大なブラックボックスを制御するための、最も強力な「外科手術用メス」だ。
メモリを解放し、ループを最適化し、予兆を数値化する。この工程をサボらないこと。それが、プロジェクトを破綻させる無能な管理者と、プロジェクトを完遂させる伝説的アーキテクトを分かつ境界線である。
君のコードが、次のプロジェクトの救命艇となることを願っている。
