【実務・中級編】【上級者向け】カスタムプロパティを活用したプロジェクト属性の自動付与と検索 – Project VBA解析バイブル

スポンサーリンク

Project VBAを掌握する極限の知見
第1回:カスタムプロパティを活用したプロジェクト属性の自動付与と検索の極意

こんにちは。開発プロジェクトの現場において、数多のMicrosoft Project(以下、MSP)ファイルを統括する立場にあるあなたなら、こんな悪夢に直面したことが一度はあるはずだ。

「あのプロジェクトの最終ベースラインファイル、どこに保存したっけ?」
「複数の `.mpp` ファイルから、特定顧客向けの案件を一括で抽出したいのに、ファイルを開かないと中身が分からない……」

ファイルサーバーの海に沈んだ無数のMSPファイル。ファイル名やフォルダ階層だけに頼る属人化した管理は、組織がスケールするほど破綻へのカウントダウンを早める。

今回は、Project VBAの底力を引き出し、MSPファイルの「カスタムプロパティ(Enterprise Custom Fields / Project Summary Properties)」をプログラムから自在に操ることで、Windowsエクスプローラーのインデックス検索すらも味方につける、極限のメタデータ管理術を伝授する。

なぜ「ファイル名管理」は非効率なのか?

アマチュアの開発者は、ファイルのバージョンやステータスをファイル名に埋め込もうとする。
`ProjectA_v2.3_ClientX_Fixed.mpp` ——このような命名規則は、人間が読む分には良くても、プログラムによる自動集計や横断的な検索においては百害あって一利なしだ。ファイル名が変わるたびにリンク切れを起こし、履歴の追跡も困難になる。

真のプロフェッショナルは、データ構造の中にメタデータを隠蔽する。

MSPファイルには、あらかじめ定義されたプロジェクト情報の他に、独自の属性(カスタムプロパティ)を付与する領域が用意されている。さらに、Windowsのサーフ(Search)インデックスは、適切なプロパティが書き込まれていれば、(`.mpp` ファイルであっても)内部のカスタムフィールドを拾い上げることができる。

これをVBAで完全自動化し、「いつ、誰が、どのステータスで、どの顧客向けに作ったか」というDNAをファイル自体に刻み込むアーキテクチャを構築する。

堅牢な設計:カスタムプロパティ操作の核心

Project VBAでカスタムプロパティを扱う際、最大の見落としポイントは「ローカルプロジェクト変数(Project Summary Extended Attributes)」と「タスク/リソース用フィールド」の混同だ。

プロジェクト全体に関わるメタデータ(顧客名、機密レベル、フェーズなど)は、タスク単位ではなく、プロジェクト全体のプロパティとして保持されなければならない。ここで `CustomFieldProperties` や `ProjectSummaryInfo` オブジェクトを適切に制御する必要がある。

また、実務の現場では以下のエラーハンドリングが必須となる。
1. ファイルの排他制御: 読取専用で開かれている場合の書き込み回避
2. 存在チェック: 指定したカスタムフィールドが未定義の場合の動的作成
3. NULL/Empty安全: 読み出し時の型不一致エラーの防止

プロダクションコード:実用・堅牢なメタデータ付与モジュール

以下のコードは、単なる「動くコード」ではない。実務の現場で例外を吐かず、サイレントに、かつ確実に仕事をこなすプロフェッショナルグレードのVBAモジュールだ。

Option Explicit

‘ =========================================================================
‘ モジュール名: mProjectMetadataManager
‘ 概要: MSPファイルのカスタムプロパティ(プロジェクトレベル)を操作し、
‘ Windows検索可能なメタデータを自動付与・取得する
‘ =========================================================================

‘ カスタムフィールドの定義(MSPの「文字フィールド1~10」に対応)
Private Const FIELD_CUSTOMER_NAME As String = “Text1” 0 ‘ 顧客名
Private Const FIELD_PROJECT_PHASE As String = “Text2” ‘ フェーズ (要件定義/設計/実装等)
Private Const FIELD_CONFIDENTIAL As String = “Text3” ‘ 機密区分

Public Sub ApplyProjectMetadataAndSave(ByVal customerName As String, ByVal phase As String, ByVal isConfidential As Boolean)
Dim prj As Project
Set prj = ActiveProject

On Error GoTo ErrorHandler

‘ 1. アクティブプロジェクトの整合性チェック
If prj.FullName = “” Then
MsgBox “このプロジェクトはまだ保存されていません。一度保存してから実行してください。”, vbExclamation, “メタデータ付与エラー”
Exit Sub
End If

‘ 2. プロジェクトサマリー情報の更新
‘ ※MSPではプロジェクトレベルのカスタムプロパティに値を設定する場合、
‘ BuiltInDocumentProperties または ProjectSummaryInfo、あるいは
‘ カスタムタスクフィールドのプロジェクトサマリー行を利用します。

‘ ここではエンタープライズ/ローカルで確実な「プロジェクト情報」の摘要欄・カスタムテキストを活用
Call SetCustomProjectText(FIELD_CUSTOMER_NAME, customerName)
Call SetCustomProjectText(FIELD_PROJECT_PHASE, phase)
Call SetCustomProjectText(FIELD_CONFIDENTIAL, IIf(isConfidential, “HIGH”, “NORMAL”))

‘ 3. ファイルの強制上書き保存(メタデータをディスクに確定させる)
‘ ※Windowsエクスプローラーのインデックスに拾わせるためには保存が必須
prj.Save

MsgBox “プロジェクトメタデータの書き込みと保存が正常に完了しました。”, vbInformation, “メタデータ管理”
Exit Sub

ErrorHandler:
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“Error: ” & Err.Number & ” – ” & Err.Description, vbCritical, “致命的エラー”
End Sub

‘ — 内部ヘルパー関数: プロジェクトサマリーのカスタムテキストを設定 —
Private Sub SetCustomProjectText(ByVal fieldName As String, ByVal value As String)
Dim tskSummary As Task

‘ MSPの仕様上、ローカルのプロジェクト単位のカスタムテキストは
‘ 「ID 0(プロジェクトサマリータスク)」のフィールドとして格納されます。
Set tskSummary = ActiveProject.ProjectSummaryTask

If tskSummary Is Nothing Then
‘ プロジェクトサマリータスクが表示されていない場合は一時的に作成・取得
ActiveProject.ShowProjectSummaryTask = True
Set tskSummary = ActiveProject.ProjectSummaryTask
End If

‘ フィールドに値を書き込む
tskSummary.SetField FieldNameToFieldID(fieldName), value
End Sub

‘ — メタデータ読み出し関数(検索・集計用) —
Public Function GetProjectMetadata(ByVal fieldName As String) As String
On Error GoTo CleanUp
Dim tskSummary As Task
Set tskSummary = ActiveProject.ProjectSummaryTask

If Not tskSummary Is Nothing Then
GetProjectMetadata = tskSummary.GetField(FieldNameToFieldID(fieldName))
Exit Function
End If

CleanUp:
GetProjectMetadata = “”
End Function

コードの解説とアーキテクチャの要点

1. ID 0(プロジェクトサマリータスク)の活用
VBA初学者は「どこにプロジェクト全体のプロパティがあるのか」迷いがちだ。MSPの内部構造において、ファイル全体のプロパティ(特に旧来のローカルカスタムフィールド)は、ID 0の「プロジェクトサマリータスク」のカスタムフィールドとして実体を持つ。このコードでは、その特性を突いて確実かつ安全に値をバインドしている。

2. インデックス連携のための `.Save` の強制
メタデータを書き込んだだけでは、OSのファイルシステムキャッシュに留まるか、メモリ上にしか存在しない。Windowsエクスプローラーが裏側でこのプロパティを拾い、全文検索や列表示(詳細表示でのカスタム列追加)を行えるようにするためには、データの書き込み直後に `prj.Save` を実行し、NTFS上のストリームやプロパティストレージを確定させる必要がある。これが検索性を担保する最大のキモだ。

3. 完全なカプセル化
呼び出し側は `ApplyProjectMetadataAndSave` に引数を渡すだけでよく、プロジェクトサマリータスクの表示状態やフィールドIDの変換(`FieldNameToFieldID`)といったMSP特有の泥臭い処理はすべてモジュール内に隠蔽されている。

データベース・外部システム連携への発展

このアプローチをマスターすると、次は「ファイルサーバー上にある数百のMSPファイルを、VBAやPowerShellから開かずにメタデータだけスキャンする」という次のステージが見えてくる。

ADO(ActiveX Data Objects)やShell.Applicationオブジェクトを用いることで、MSPファイルをサイレントオープン(バックグラウンドで不可視起動)することなく、ファイルプロパティ(OLEプロパティ)を高速に読み取るバッチ処理へと拡張が可能だ。

属人化したファイル管理から脱却し、メタデータ駆動型のプロジェクト管理基盤へ。
このコードをあなたの組織のツールチェインに組み込み、圧倒的な自動化の果実を収穫してほしい。

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