プロジェクト管理の深淵:MS Project VBAによるマスタープロジェクト動的生成の最適解
多くのエンジニアが、MS Projectの「マスタープロジェクト」という概念を、ただのUI操作の延長線上で捉えている。しかし、大規模プロジェクトのPMOやシステム管理を担う諸君にとって、それは「メモリとリソースの動的結合」という高度なアーキテクチャの課題に他ならない。
今回は、指定フォルダ内のサブプロジェクトを走査し、リンクされたマスタープロジェクトを生成・管理する、堅牢かつ極限まで最適化されたVBAコードを提示する。
—
1. ライフサイクルを掌握せよ:メモリリークの排除
VBAにおいて、`Project`オブジェクトや`Application`オブジェクトのハンドリングは、単に変数に代入して終わりではない。特にMS ProjectのCOMインターフェースは、オブジェクトの解放タイミングが極めてシビアだ。
ループ内で生成されるオブジェクトは、必ず明示的に解放しなければならない。これを怠れば、数千行のプロジェクト操作において、VBAのメモリ管理は破綻し、不可解な「予期せぬエラー」を招くことになる。
2. 実装:マスタープロジェクト自動生成エンジン
以下のコードは、指定ディレクトリ内の`.mpp`ファイルを抽出し、リンクを構築するエンジンの核心部分だ。
‘ 必要な参照設定: Microsoft Project 16.0 Object Library
Option Explicit
Public Sub GenerateMasterProject()
Dim mppFolder As String
Dim fileName As String
Dim masterProj As Project
Dim subProj As Object
Dim fso As Object
‘ メモリ管理の最適化: ファイルシステムオブジェクトの生成
Set fso = CreateObject(“Scripting.FileSystemObject”)
mppFolder = “C:\Projects\SubProjects\” ‘ 対象ディレクトリ
‘ 新規マスタープロジェクト作成
Application.FileNew
Set masterProj = ActiveProject
fileName = Dir(mppFolder & “.mpp”)
On Error GoTo Cleanup
Do While fileName <> “”
‘ リンク付き挿入: リンクを維持した状態でサブプロジェクトとして挿入
masterProj.Subprojects.Add Name:=mppFolder & fileName, Link:=True
fileName = Dir()
Loop
MsgBox “マスタープロジェクトの生成が完了しました。”, vbInformation
Cleanup:
‘ 明示的なオブジェクト解放
If Not fso Is Nothing Then Set fso = Nothing
If Err.Number <> 0 Then
MsgBox “エラー発生: ” & Err.Description, vbCritical
End If
End Sub
3. シニアエンジニアが意識すべき「隠れたボトルネック」
A. COMインターフェースのオーバーヘッド
`Subprojects.Add`メソッドは、実行のたびに裏側でCOMサーバーを呼び出し、ファイルヘッダーを読み込む。数が多い場合、この処理は指数関数的に遅延する。パフォーマンスを改善するには、`Application.ScreenUpdating = False`を冒頭に配置し、再描画を極限まで抑制することが必須である。
B. リンクの完全性維持
リンクされたマスタープロジェクトは、サブプロジェクトのパスが物理的に移動すると容易に破壊される。本番環境では、UNCパスでの指定を徹底し、さらに`FileExists`チェックを実装して、リンクの整合性を動的に検証するロジックを挟むのがプロの仕事だ。
C. レガシー環境との共存
もし社内システムが古いProject Serverと連携している場合、マスタープロジェクトの保存時に「サーバーとの接続タイムアウト」が発生することがある。この場合、Win32 APIの`Sleep`関数を用いて、ファイル間の読み込みインターバルを強制的に設けるという、泥臭いが必要不可欠なハックが必要になる場合がある。
—
最後に:自動化の真髄
「コードを書く」ことは誰にでもできる。しかし、そのコードがシステムリソースにどのような負荷をかけ、数年後の保守担当者がどれだけ頭を抱えるかを想像するのが、アーキテクトの仕事だ。
今回紹介したコードは、あくまで「骨子」である。実際の運用環境では、これに例外処理のスタックトレース出力、ログ出力、そしてファイルロックの排他制御などを加えるべきだ。
技術は常に進化するが、メモリを大切に扱い、オブジェクトの寿命を正確に管理するという原則は、VBAであろうと最新の言語であろうと変わることはない。諸君のプロジェクトが、この自動化によって少しでも本質的な改善に時間を使えるようになることを期待している。
