【上級プロ】Project VBAで「カスタムビュー」をXML定義から動的に生成・適用する方法
開発プロジェクトの現場において、メンバー全員が「同じ視点」でスケジュールを捉えられているか——これはプロジェクトの成否を分ける極めて重要なファクターだ。
MS Project標準のビューをそのまま使わせている現場をよく見かけるが、正直に言ってあれは非効率の極みである。担当者ごとに列の並び順がバラバラであったり、必要なカスタムフィールドが表示されていなかったり、不要なガントバーで画面が埋め尽くされていたり。これではプロジェクトマネージャーが意図したデータ分析や進捗管理などできるはずがない。
「チーム全員のビュー定義を統一する」
これを手動で行うのは、組織のスケールを考えればナンセンスだ。今回は、MS Projectの `ViewEditEx` メソッド(または `ViewEdit`)を駆使し、外部のXML定義からカスタムビューを動的に生成・適用する高度な運用術を伝授する。
—
なぜGUIでのビュー作成・配布は破綻するのか?
多くの現場では、マスターとなるプロジェクトファイル(.mpp)にあらかじめカスタムビューを作り込み、それを「グローバルテンプレート(Global.mpt)」に保存させたり、ファイル間でビューをコピーさせたりするアプローチをとる。
しかし、このアプローチには致命的な欠陥がある。
1. Global.mptの破損リスク: 組織共通のGlobal.mptが破損・肥大化した場合、全ユーザーの環境に悪影響を及ぼす。
2. バージョンのブラックボックス化: 「どのバージョンのビューが最新なのか」がファイル内に隠蔽され、差分管理が不可能になる。
3. 動的なカスタマイズの限界: ログインユーザーやプロジェクトの種別に応じて、動的に表示項目を変えるような柔軟性がない。
解決策:ビューを「コード(XML)」としてコード管理する
MS Projectのビュー構造は、内部的にXMLで表現されている。このXML構造をVBAから動的に流し込み、ビューとして実体化させればよい。これにより、Git等のバージョン管理システムでビュー定義をコード管理し、起動時に自動適用するクリーンな仕組みが構築できる。
—
アーキテクチャの全体像
今回構築する仕組みのフローは以下の通りだ。
1. XML定義の読み込み: サーバ上の共有フォルダやリポジトリから、最新のビュー定義XML文字列を取得する。
2. 既存ビューのクリーンアップ: 競合を防ぐため、同名の既存カスタムビューを安全に削除(または上書き)する。
3. XMLからの動的生成: `ViewEditEx` メソッドを用いて、XMLからダイレクトにビューを生成する。
4. アクティブビューへの適用: 生成したビューを即座に適用し、画面をリフレッシュする。
—
プロダクションコード:XML定義からのビュー動的生成モジュール
以下のコードは、エラーハンドリングを徹底し、実務の現場でそのまま組み込める堅牢性を持たせた実装だ。
Option Explicit
‘ ==============================================================================
‘ モジュール名: MdlViewManager
‘ 概要: XML定義からMS Projectのカスタムビューを動的生成・適用するモジュール
‘ ==============================================================================
Public Sub ApplyCustomViewFromXml()
On Error GoTo ErrorHandler
Dim targetViewName As String
targetViewName = “【PMO標準】クリティカルパス分析ビュー”
‘ 1. 既存ビューの存在確認とクリーンアップ
Call RemoveExistingView(targetViewName)
‘ 2. XML定義の取得(今回はハードコーディングだが、実際はファイルやDBから読み込む)
Dim xmlDefinition As String
xmlDefinition = GetViewXmlDefinition()
‘ 3. XMLからビューを生成する(ViewEditExを使用)
‘ ※引数の仕様:ViewEditEx(Name, [Table], [TaskForm], [TaskSheet], [ResourceSheet], [ResourceForm], [Filter], [Group], [ShowInMenu], [AutoColumnBestFit], [Screen], [Custom], [Xml])
‘ XMLを直接渡す場合は、専用の構文とパラメータ構造が必要になります。
Dim isSuccess As Boolean
‘ ProjectのバージョンやXMLスキーマに依存するため、エラーキャッチを厳重に行う
Application.ViewEditEx _
Name:=targetViewName, _
Create:=True, _
Screen:=pjScreenGantt, _
Custom:=True, _
Xml:=xmlDefinition
‘ 4. 生成したビューを適用
ViewApply Name:=targetViewName
MsgBox “カスタムビュー「” & targetViewName & “」の適用が完了しました。”, vbInformation, “ビュー自動化システム”
Exit Sub
ErrorHandler:
MsgBox “ビューの生成・適用中に致命的なエラーが発生しました。” & vbCrLf & _
“Error 0x” & Hex(Err.Number) & “: ” & Err.Description, vbCritical, “システムエラー”
End Sub
‘ ——————————————————————————
‘ 既存の同名ビューを安全に削除するプロシージャ
‘ ——————————————————————————
Private Sub RemoveExistingView(ByVal viewName As String)
Dim v As View
On Error Resume Next
Set v = ActiveProject.Views(viewName)
On Error GoTo 0
If Not v Is Nothing Then
‘ ビューが現在アクティブな場合は、一旦別の標準ビューに逃がす
If ActiveProject.ActiveView.Name = viewName Then
ViewApply Name:=”ガント チャート”
End If
v.Delete
End If
End Sub
‘ ——————————————————————————
‘ ビュー定義XMLを返すスタブ関数(実務ではテキストファイルやAPIから取得)
‘ ——————————————————————————
Private Function GetViewXmlDefinition() As String
Dim xml As String
‘ 【重要】ここにはMS Projectが解釈可能なビュー定義XMLスキーマを記述します。
‘ 実際のプロジェクトでは、あらかじめGUIで作成したビューをXML形式でエクスポートし、
‘ テンプレートとして外部ファイル(.xml)から読み込む形をとるのが定石です。
xml = “
“
“
“Cost
” & _
“
“
“
GetViewXmlDefinition = xml
End Function
—
長の経験から、この手法を導入する上で絶対に押さえておくべき実務上の注意点をいくつか共有しておこう。
1. XMLスキーマのバージョン依存性
MS Projectのバージョン(2016, 2019, 2021, 365)によって、`ViewEditEx` が要求するXMLのスキーマやサポートされるプロパティが微妙に異なる。
開発環境とエンドユーザーの環境のバージョンが混在する組織では、事前に動作検証を徹底してほしい。最も手堅いのは、「対象のバージョンで手動作成したビューをいったんXMLエクスポートし、それをテンプレートとしてVBAから流し込む」というアプローチだ。
2. アクティブビュー競合の罠
VBAでビューを操作している最中に、ユーザーがマウスやキーボードで別のビューに切り替えようとすると、オブジェクトモデルがロックされ、実行時エラー(エラー番号:1100など)を引き起こす。
これを防ぐため、ビューの自動生成スクリプトを実行する際は、あらかじめ `Application.ScreenUpdating = False` を活用し、処理中はユーザーのUI操作をブロックする配慮(あるいは非同期処理の検討)がプロとしての要件となる。
—
終わりに:自動化の先にある「真のガバナンス」
VBAによるビューの動的生成は、単なる「手間の削減」ではない。
「プロジェクトのデータをどう見るべきか」という組織の意思決定の基準を、コードによって一元管理・強制するという、極めて高度なガバナンスの仕組みなのだ。
コピペで動かすことは容易い。だが、なぜその設計が必要なのかという文脈を理解し、組織のワークフローに組み込んでこそ、真の業務自動化エンジニアと言える。
あなたの現場のプロジェクト管理を、次のステージへと引き上げてほしい。
