【テクニカル・上級編】【中級者向け】テンプレート(.mpt)から新規作成する際、特定のカスタムフィールド定義を強制的に同期させるマクロ – Project VBA解析バイブル

スポンサーリンク

テンプレートの強制同期:Project VBAにおける「定義の整合性」を極める

多くのエンジニアがProjectのカスタムフィールド(ユーザー設定フィールド)管理で躓くのは、単にフィールドを作成するからではない。「既存の汚染されたプロジェクトファイル」に対して、いかにして組織標準の定義を非破壊的に、かつ確実にインポートするか、という点にある。

GUIで「構成のインポート」をポチポチ押しているようでは、全社レベルのPMO業務は回らない。今回は、テンプレートファイル(.mpt)からフィールド定義のみを抽出・強制同期させる、堅牢なVBAアーキテクチャを提示する。

1. なぜ「OrganizerCopy」の直接利用は危険か

MS Projectの`OrganizerCopy`メソッドは強力だが、無策に呼び出すと致命的なエラーやメモリリークを招く。特に、プロジェクトがオープン状態にある際、オブジェクトの参照が解放されないままインポートを繰り返すと、Project自体のメモリスタックを圧迫する。

我々が目指すべきは、「ソース(テンプレート)とターゲット(対象ファイル)の完全な分離」「オブジェクトの明示的な破棄」である。

2. 実装:カスタムフィールド定義の強制同期メカニズム

以下のコードは、指定したテンプレートからフィールド定義のみをターゲットへ流し込むためのコアロジックだ。

Option Explicit

‘ 伝説的なエンジニアは、常にスコープを最小化し、メモリを制御下に置く
Public Sub SyncCustomFieldsFromTemplate(ByVal targetProject As Project, ByVal templatePath As String)
Dim srcApp As Object
Dim srcProject As Project

‘ 1. インスタンスの分離とバックグラウンド処理
‘ 非表示でインスタンスを起動し、リソースの競合を回避する
Set srcApp = CreateObject(“MSProject.Application”)
srcApp.Visible = False

On Error GoTo Cleanup

‘ 2. テンプレートを読み取り専用で開く(共有違反回避)
srcApp.FileOpenEx Name:=templatePath, ReadOnly:=True
Set srcProject = srcApp.ActiveProject

‘ 3. フィールド定義の同期 (pjCustomFields)
‘ OrganizerCopyは第4引数をTrueにすることで既存定義を上書き更新する
Application.OrganizerCopy Source:=templatePath, _
Destination:=targetProject.FullName, _
Name:=””, _
Object:=pjCustomFields

Debug.Print “Synchronization Successful: ” & targetProject.Name

Cleanup:
‘ 4. オブジェクトの明示的解放
‘ ここを疎かにするエンジニアは、大規模環境で必ず痛い目を見る
If Not srcProject Is Nothing Then srcProject.Close SaveChanges:=False
If Not srcApp Is Nothing Then srcApp.Quit
Set srcProject = Nothing
Set srcApp = Nothing

If Err.Number <> 0 Then
MsgBox “Critical Error: ” & Err.Description, vbCritical
End If
End Sub

3. チーフアーキテクトからの深掘り:知見と教訓

A. メモリ管理の真実

`CreateObject(“MSProject.Application”)` を使用して別プロセスでテンプレートを読み込むのは、単なる「行儀の良さ」ではない。ProjectのCOMコンテナは非常に脆弱であり、同一プロセス内で大量のオブジェクト操作を行うと、ガーベッジコレクションが追いつかず、ProjectのGUIがフリーズしたり、最悪の場合はファイル破損を引き起こす。この分離は必須の安全策だ。

B. レガシーな環境との向き合い方

古いバージョンのProject Serverや、ネットワークドライブ上の不安定なパスが混在する環境では、`FileOpenEx`の際に`ReadOnly`を指定することが不可欠である。排他制御の衝突は、VBAのスタックトレースを破壊する最大の要因となる。

C. パフォーマンスの最適化

今回、`OrganizerCopy`を使用して一括コピーを行っているが、個別のフィールド定義を細かく制御したい場合は、`CustomFieldProperties`オブジェクトを直接イテレーションする手法をとるべきだ。しかし、今回のテーマである「組織標準の整合性」を保つには、テンプレート自体をマスターとして全コピーを行うのが最も堅牢である。

4. 最後に:エンジニアが守るべき矜持

システム管理ツールは、ユーザーが意識せずに「正しく」動くことが最大の価値だ。今回紹介した手法は、組織内のプロジェクトファイルが個別にカスタマイズされ、収拾がつかなくなった状況を救うための「外科手術」である。

コードをコピペするだけで満足してはならない。なぜ別プロセスを立ち上げるのか、なぜ`Set = Nothing`が重要なのか。その背後にあるメモリ管理の哲学を理解した者だけが、真の自動化エンジニアとして評価される。

次は、これを「Project Serverのチェックイン・チェックアウト処理」と組み合わせる高度な非同期処理について解説する予定だ。腕に自信がある者は、今のうちにメモリの解放順序を完璧に体に叩き込んでおくように。

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