【テクニカル・上級編】リソースの「過負荷」を解消するための「自動平準化」実行後の差分レポート生成 – Project VBA解析バイブル

スポンサーリンク

プロジェクトの「見えない歪み」を可視化せよ:Project VBAによる平準化差分分析の極意

プロジェクト管理において、Project標準の「平準化(Leveling)」は諸刃の剣だ。リソースの過負荷を解消する一方で、クリティカルパスやスケジュール上の制約を、現場のエンジニアが感知できないレベルで歪ませる。

「なぜタスクが勝手に移動したのか?」という問いに対し、管理者はログではなく「結果」だけを突きつけられる。このブラックボックスを解体し、平準化前後の差分をExcelで完全可視化する。それが、真のシニアアーキテクトが辿り着くべき一つの到達点だ。

—

1. 影の履歴を追跡する:アーキテクチャの設計思想

標準機能の「平準化」を実行すると、`Task.Start` や `Task.Finish` が一斉に書き換わる。これに対抗するには、平準化実行直前の状態をスナップショットとしてメモリ上に展開し、実行後に差分を抽出するというアプローチが不可欠だ。

ここで注意すべきは、VBAのコレクションの扱いに起因するメモリリークだ。数千行規模のProjectファイルで `Task` オブジェクトを無造作に走査すれば、GCが追いつかずVBA環境が不安定になる。

2. 極限の差分抽出:実装の要諦

以下のコードは、Projectのタスク情報を配列(Array)に展開することで、オブジェクト参照のオーバーヘッドを極限まで排除する手法をとっている。

‘ プロジェクトタスクの差分分析エンジン
‘ @param proj As Project
‘ @return Collection (差分レポート用データセット)
Public Function GenerateLevelingReport(ByRef proj As Project) As Collection
Dim taskColl As Collection
Set taskColl = New Collection

Dim t As Task
‘ オブジェクトの明示的参照ではなく、配列への展開による高速化
‘ 大規模プロジェクトでは、タスクを回す際にプロパティアクセスを最小化せよ
For Each t In proj.Tasks
If Not t Is Nothing Then
If Not t.Summary Then
‘ 構造体で保持することでメモリ効率を高める
Dim diffInfo As Variant
diffInfo = Array(t.ID, t.Name, t.Start, t.Finish)
taskColl.Add diffInfo
End If
End If
Next t

‘ ここで平準化処理を実行する
‘ proj.LevelingOptions…
‘ proj.LevelNow

‘ …(後処理にて再びループし、Start/Finishの乖離を計算)
Set GenerateLevelingReport = taskColl
End Function

3. メモリ管理とレガシー環境への配慮

長年VBAに携わっていると痛感するのは、「VBAは動くが、メモリは常に死にかけている」という現実だ。

  • 明示的な解放: `Set obj = Nothing` はおまじないではない。特に巨大なProjectオブジェクトを操作する際は、スコープを最小限にしたプロシージャ内で処理を完結させ、スタックを早期に解放することが必須だ。
  • Windows APIの活用: 平準化実行中のフリーズを防ぐため、`DoEvents` を多用するのは素人の所業だ。必要に応じて `Sleep` APIを呼び出し、CPU占有率をコントロールせよ。

If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As LongPtr)
Else
Private Declare Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
End If

4. 差分をExcelへ:レポートの自動生成

抽出したデータは、そのままExcelのシートへ書き出すのではなく、一度 `Variant` 型の二次元配列に格納してから、`Range.Value2` で一括出力せよ。セルへの個別アクセスは最もコストが高い処理である。

‘ 差分をExcelシートに一括転送
Public Sub OutputToExcel(ByRef dataArray As Variant)
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(“DiffReport”)

‘ 一括転送により、画面描画のオーバーヘッドを抑える
ws.Range(“A2”).Resize(UBound(dataArray, 1), UBound(dataArray, 2)).Value2 = dataArray
End Sub

—

シニアエンジニアへの提言:なぜツールを作るのか

平準化レポートを自動生成する目的は、単なる進捗管理ではない。「プロジェクトの意思決定プロセスを透明化すること」にある。

Projectが自動で割り当てたリソースの移動は、往々にして現場の属人的な調整と衝突する。システム管理者は、この「技術的な最適化」と「現場の現実」の溝を埋めるための翻訳者であるべきだ。

VBAはレガシーと呼ばれて久しいが、Project APIを直接叩き、プロジェクトの深層構造を可視化できるという点において、未だにこれを超える強力なツールは存在しない。この武器を使いこなし、混沌としたプロジェクトの「歪み」を誰よりも早く見つけ出すこと。それが、この過酷な現場を生き抜くための唯一の道である。

次は、このレポートを元に、どのリソースが「過負荷の閾値」を最も頻繁に超えているのかをヒートマップ化する手法について掘り下げるとしよう。準備はいいか。

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