Project VBAの深淵:標準レポートを凌駕する「リソース稼働率」抽出の極意
多くのエンジニアがProjectの標準レポートに限界を感じた時、VBAに手を伸ばす。だが、MS Projectのオブジェクトモデルを甘く見てはいけない。`Resource.Work`を単純に集計して満足しているようでは、プロジェクトの「真の歪み」は見えてこないのだ。
今日は、Projectの膨大なデータからリソースの負荷を期間ごとに切り出し、Excelでヒートマップを描画するための「極限のデータ抽出術」を伝授する。
—
1. オブジェクトモデルの罠と「真の負荷」へのアクセス
Projectの`Resource`オブジェクトにおける`Work`プロパティは、あくまで「総作業量」だ。これを期間別(週単位や月単位)に分解するには、`Assignment`(割り当て)オブジェクトの`TimeScaleData`メソッドを避けて通れない。
ここで多くの者が陥る罠が、メモリリークと再計算によるパフォーマンス低下だ。数千件のタスクを持つプロジェクトで、安易なループ処理を書けばVBAはフリーズする。
極限の最適化戦略:
- 計算の先送り: `Application.Calculation = pjManual`で計算エンジンを止め、データ抽出後に戻す。これは鉄則だ。
- Late Bindingの回避: `Project`のタイプライブラリを確実に参照し、`Early Binding`でコンパイル時の最適化を享受せよ。
- メモリの解放: オブジェクト変数は必ず`Nothing`で明示的に破棄する。VBAのガベージコレクションを信用してはならない。
—
2. 実装:期間別稼働率抽出のアーキテクチャ
以下のコードは、期間ごとに`Assignment`から作業時間を吸い上げるコアロジックだ。
‘ 伝説のアーキテクトによるリソース負荷抽出ロジック
Public Sub ExtractResourceWorkload()
Dim proj As Project
Dim res As Resource
Dim asn As Assignment
Dim ts As TimeScaleValues
Dim tsv As TimeScaleValue
‘ パフォーマンス最適化:計算停止
Application.Calculation = pjManual
Set proj = ActiveProject
‘ Excelへの出力準備(ここでは簡易的なDebug出力だが、実際は配列に格納し一括転送せよ)
For Each res In proj.Resources
If Not res Is Nothing Then
If res.Type = pjResourceTypeWork Then
‘ 割り当てられたタスクごとの期間別稼働を取得
For Each asn In res.Assignments
‘ 期間を週単位(pjTimescaleWeeks)で取得
Set ts = asn.TimeScaleData(StartDate:=proj.ProjectStart, _
EndDate:=proj.ProjectFinish, _
Type:=pjTimescaleWeeks)
For Each tsv In ts
‘ ここで配列へ格納し、Excelへ一括出力する設計にすること
‘ Debug.Print res.Name & ” | ” & tsv.StartDate & ” | ” & tsv.Value
Next tsv
‘ メモリ解放:コレクションのループ後は明示的に
Set ts = Nothing
Next asn
End If
End If
Next res
‘ 計算エンジン再開
Application.Calculation = pjAutomatic
MsgBox “抽出完了。メモリを解放しました。”, vbInformation
End Sub
—
3. システム管理者への提言:レガシーとの共存
このスクリプトを運用する際、社内の古い環境では「メモリ不足」が必ず発生する。以下のチューニングを推奨する。
1. 配列処理の徹底: `Cells(i, j).Value = …`をループ内で繰り返すな。抽出したデータをバリアント型の配列に一度すべて格納し、`Range(“A1”).Resize(…) = Array`で一括転送せよ。I/Oコストが劇的に下がる。
2. Windows APIの活用: 大規模なプロジェクトでは、処理時間が長くなる。`GetTickCount`等のAPIで処理時間を計測し、ログに残せ。ボトルネックは常に「特定の複雑なサマリータスク」に集中している。
3. COMの強制開放: 大規模なデータセットを扱う場合は、`DoEvents`を適切に差し込みつつ、`Set = Nothing`のタイミングを厳格に管理すること。
—
最後に:なぜ「標準」ではダメなのか
標準レポートは「過去」しか語らない。しかし、我々エンジニアが求めるのは「来月のリソースの限界値」だ。
このコードで抽出したデータをExcelの「条件付き書式」や「Power BI」に流し込めば、稼働率が100%を超過する瞬間に赤く染まるヒートマップが完成する。それは単なるグラフではない。プロジェクトの崩壊を未然に防ぐ、「未来を視るための計器」だ。
VBAはレガシーと言われることもある。だが、このレベルまで突き詰めれば、それは最新のSaaSにも劣らない強力な意思決定支援ツールとなる。
諸君、コードを汚すな。そして、プロジェクトの真実を見抜く視点を忘れるな。健闘を祈る。
