大規模プロジェクトの「ベースライン比較」を極める:メモリを支配し、差分を瞬時に射抜く技術
こんにちは。自動化の現場で数々のプロジェクトを救ってきた、アーキテクトの先輩です。
数万行のタスクを抱えるプロジェクトにおいて、プロジェクトマネージャーが最も恐れるのは「ベースラインとの乖離」を見落とすことです。しかし、標準機能で数千行の差分をチェックしようとすれば、Projectはフリーズし、あなたのPCも悲鳴を上げることでしょう。
今日は、VBAの「メモリ効率」を極限まで高め、大規模プロジェクトのベースライン比較を爆速で行うためのプロフェッショナルな知見を伝授します。
—
1. なぜ「全行ループ」が地獄を見るのか?
初心者がやりがちなのは、全てのタスクを順番にループして`Task.BaselineStart`などを比較する方法です。
しかし、Projectのオブジェクトモデルは「重い」。1つのタスクにアクセスするたびに内部で膨大なメモリ参照が発生し、数万行でこれをやると処理時間は指数関数的に増大します。
極限の知見:
高速化の鍵は、「オブジェクトに触れる回数を最小限にする」こと、そして「メモリ上に二次元配列を構築し、比較処理をVBAのメモリ領域内で完結させる」ことです。
—
2. 実装:高速差分抽出アルゴリズム
今回は、タスクの「UniqueID」をキーとして、ベースラインと現在値の開始日をハッシュのように比較する手法を紹介します。
‘ 【上級者向け】高速差分比較エンジン
Sub ExtractBaselineDiff()
Dim proj As Project
Dim tsk As Task
Dim arrData() As Variant
Dim i As Long
Set proj = ActiveProject
‘ 1. タスク数を取得してメモリを事前確保(ReDimの乱発を避ける)
ReDim arrData(1 To proj.Tasks.Count, 1 To 3)
‘ 2. オブジェクトアクセスを最小化するため、一度だけ配列に値を叩き込む
‘ これが「メモリ最適化」の第一歩です
i = 1
For Each tsk In proj.Tasks
If Not tsk Is Nothing Then
arrData(i, 1) = tsk.UniqueID
arrData(i, 2) = tsk.BaselineStart(pjBaseline1)
arrData(i, 3) = tsk.Start
i = i + 1
End If
Next tsk
‘ 3. 配列内で高速比較(Excelのシートへ出力する準備)
‘ ここでIF文を回すのが、Objectを触るより100倍速いのです
Debug.Print “— 差分レポート —”
For i = LBound(arrData, 1) To UBound(arrData, 1)
If arrData(i, 1) <> “” Then
If arrData(i, 2) <> arrData(i, 3) Then
Debug.Print “Task ID: ” & arrData(i, 1) & ” で乖離を検知!”
End If
End If
Next i
End Sub
コードの解説:ここがプロの設計
- ReDimによるメモリ確保: 配列のサイズを最初に決めることで、メモリの断片化(メモリフラグメンテーション)を防いでいます。
- Objectアクセスは最小限: `For Each`で一度だけ値を吸い上げ、あとは配列という「メモリの小部屋」で比較を行います。これが数万行を数秒で処理するための秘訣です。
—
3. 陥りやすい「罠」と対策
大規模開発でよくある失敗ケースを挙げておきます。これらを避けるだけで、あなたのコードは格段に安定します。
- 罠1:`Task.Name`のような文字列アクセスを繰り返す
- 対策:文字列の比較は重いです。可能な限り `UniqueID` や `ID` などの数値型で照合を行い、最後に必要な分だけ名前を取得してください。
- 罠2:エラーハンドリングの欠如
- 対策:サマリータスクや削除済みタスクが `Nothing` になることがあります。`If Not tsk Is Nothing Then` は、Project VBAにおける「お守り」だと思って必ず書いてください。
- 罠3:画面更新の停止を忘れる
- 対策:`Application.ScreenUpdating = False` を忘れていませんか? UIの再描画は、バックグラウンド処理の速度を激しく落とします。
—
4. さらなる高みへ:バイナリ比較の概念
今回紹介した手法は、いわば「インメモリ・キャッシュ」による比較です。さらに上を目指すなら、プロジェクトファイルをバイナリ(XML形式)として保存し、`Scripting.Dictionary` を使ってIDをキーにした高速ルックアップを行う手法もあります。
「Project VBAで何ができるか」を知ることは、あなたのキャリアにおける最強の武器になります。
ここをクリアしたあなたは、もう「マクロの記録」に頼る初心者ではありません。数万行のプロジェクトを意のままに操る、立派な自動化エンジニアです。次はぜひ、この結果をExcelのピボットテーブルに自動連携させて、ダッシュボード化することに挑戦してみてください。
また現場でお会いしましょう。応援しています!
