MS Project VBAの深淵:ベースライン自動管理による「計画の死」を防ぐアーキテクチャ
MS Projectのプロジェクト管理において、「ベースライン」はただの記録ではない。それはプロジェクトという生命体が、ある瞬間に何を「正解」としていたかを示す唯一の死体解剖図である。
多くの現場では、GUIから手動でベースラインを保存しているが、それはエンジニアとしてあまりに脆弱だ。特に大規模なエンタープライズ環境において、計画変更のたびにバージョン管理がブラックボックス化することは、数年後のガバナンス崩壊を約束しているに等しい。
本稿では、VBAを用いてベースラインをプログラムで制圧し、履歴を永続化する「真の管理手法」を授ける。
—
1. ベースライン管理の勘所:オブジェクトモデルの罠
MS Projectのオブジェクトモデルは、一見素直に見えて、メモリ管理と参照整合性の面で極めて気難しい。`Application.BaselineSave` メソッドを単に叩くのは素人の所業だ。
シニアエンジニアが意識すべきは、以下の3点である。
- メモリ解放の徹底: ProjectオブジェクトはCOMベースであり、内部でCOMポインタが循環参照を引き起こしやすい。明示的な `Nothing` の代入は必須。
- エラーハンドリング: ベースラインの保存は失敗する前提で設計せよ。特にリソースの整合性が取れていない場合、メソッドは例外を投げずに静かに失敗するか、予期せぬ挙動を示す。
- ログの分離: 計画の履歴はProjectファイル内だけでなく、外部のSQL ServerやXML/JSONに書き出すべきだ。ファイルが破損した際、ベースラインデータまで失うリスクを排除せよ。
—
2. 実装:ベースライン自動化エンジン
以下は、現在のアクティブプロジェクトをベースライン(0〜10)へ保存し、その実行ログを外部ファイルに出力する堅牢な実装サンプルである。
Option Explicit
‘ メモリ最適化のためのAPI定義(必要に応じてWindowハンドリング等を拡張)
Private Declare PtrSafe Sub Sleep Lib “kernel32″ (ByVal dwMilliseconds As Long)
”’
”’
Public Sub ExecuteBaselineSnapshot(ByVal baselineNum As PjBaselines)
Dim proj As Project
Set proj = Application.ActiveProject
On Error GoTo ErrorHandler
‘ 1. ベースラインの保存 (全タスク対象)
‘ 0 はベースラインそのもの、1-10は各スナップショット
proj.BaselineSave AllProjects:=False, _
CopyBaselineToBaseline:=pjBaselineCopyNone, _
FromBaseline:=pjBaselineDefault, _
ToBaseline:=baselineNum
‘ 2. 外部ログへの書き出し(システム監査用)
WriteBaselineLog proj.Name, baselineNum
MsgBox “ベースライン [” & baselineNum & “] の保存とログ記録が完了しました。”, vbInformation
CleanExit:
Set proj = Nothing
Exit Sub
ErrorHandler:
Debug.Print “Error: ” & Err.Description
Resume CleanExit
End Sub
”’
”’
Private Sub WriteBaselineLog(projName As String, bNum As Integer)
Dim fso As Object
Dim logFile As Object
Dim logPath As String
logPath = “C:\ProjectLogs\BaselineHistory.log”
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set logFile = fso.OpenTextFile(logPath, 8, True) ‘ 8: ForAppending
logFile.WriteLine Now & ” | Project: ” & projName & ” | Baseline: ” & bNum & ” | User: ” & Environ(“USERNAME”)
logFile.Close
Set logFile = Nothing
Set fso = Nothing
End Sub
—
3. シニアエンジニアが守るべき「極限の知見」
オブジェクトの明示的解放とメモリ管理
VBAはガベージコレクションを待っていてはいけない。特に `ActiveProject` や `Tasks` コレクションをループ処理する際は、必ずループ終了時にオブジェクト変数を `Nothing` にリセットせよ。これを怠ると、Projectのプロセスがゾンビ化し、バックグラウンドでメモリリークを誘発する。
Windows APIによる「強制的な同期」
MS Projectが重い計算処理(再スケジュールやリソースの平準化)を行っている最中にVBAを走らせると、COMオブジェクトがロックされることがある。そんな時は `Sleep` APIを使い、CPUリソースに空きを作ってから処理を再開するような「非同期的な配慮」が、システムの寿命を延ばす。
計画変更の「差分」を可視化せよ
ベースラインを保存するだけでは不十分だ。真の管理者は、`BaselineStart` と `Start` の差分を計算し、KPIとして外部DBに飛ばす。「計画から何日乖離したか」を定量的かつ自動的に追跡し続けること。それがProjectにおける「自動化」の真の目的である。
—
結論:自動化は「責任」である
我々アーキテクトにとって、ツールを作ることは単なる工数削減ではない。それはプロジェクトという複雑なシステムを「計測可能」にすることである。
ベースラインの自動化は、プロジェクトの「過去」と「未来」を繋ぐバックボーンだ。このコードをベースに、各社の環境に合わせたログフォーマットやDB連携を実装してほしい。VBAは決してレガシーではない。使い手次第で、エンタープライズの深淵を支える最強の武器となる。
次のステップでは、このVBAからJSONを生成し、BIツール(Power BI等)へ自動プッシュする方法を解説する。準備はいいか。
