【実務・中級編】Project VBA開発におけるバージョン管理とチーム共有のベストプラクティス – Project VBA解析バイブル

スポンサーリンク

Project VBAを掌握せよ:複数人開発と配布・保守の「黄金律」

Microsoft Project(以下、Project)のVBA開発は、ExcelやAccessのそれとは一線を画す。単なる自動化ツールではない。それは「動的に変化するWBS(作業分解構造)」という巨大なステート(状態)を管理するエンジンの開発に他ならない。

多くの現場では、場当たり的なマクロが`Global.mpt`(グローバルテンプレート)を汚染し、バージョン管理が破綻し、誰が書いたか分からないコードがスケジュールを破壊している。

本記事では、世界最高峰のアーキテクトの視点から、Project VBAにおけるバージョン管理、チーム共有、そしてタスク階層と依存関係を堅牢に制御するための「プロダクト級」の実装戦略を伝授する。

1. 共有の罠:なぜGlobal.mptにコードを書いてはならないのか

初心者や凡庸なエンジニアは、マクロを`Global.mpt`に保存して満足する。しかし、これはプロフェッショナルの現場では「禁じ手」だ。

  • 衝突のリスク: 複数人で同じ名前のマクロを書き換えた瞬間、環境は壊れる。
  • 配布の地獄: 修正のたびに各ユーザーの`Global.mpt`を置き換えるのか? それは保守ではない、ただの苦行だ。
  • 依存関係の不透明さ: どのプロジェクトファイルがどのバージョンのマクロに依存しているかが全く見えなくなる。

ベストプラクティス:アドイン形式(.mpp)によるコード分離

ロジックは特定の「ツール用MPPファイル」または「アドイン」として切り出し、必要な時だけ参照(リファレンス)させるか、あるいはプロジェクト起動時に動的にインポートする仕組みを構築せよ。

2. 実装:タスク階層と依存関係の「破壊」を防ぐ堅牢なコード

タスクの階層構造(WBS)やリンク(依存関係)を自動設定する際、最も多いバグは「ID(連番)」を直接指定することだ。タスクが挿入・削除された瞬間に、そのIDは意味を失う。

プロフェッショナルは常に`UniqueID`を基準にし、さらに再帰的な構造を用いて階層を制御する。

プロダクション・コード例:WBS構造の自動再構築エンジン

以下のコードは、外部設定(例えばJSONやExcel)から取り込んだ構造を再現することを想定した、堅牢なタスク生成・階層化のテンプレートである。

‘—————————————————————————————
‘ Procedure : SynchronizeWBSStructure
‘ Purpose : 外部定義に基づきWBS構造と依存関係を安全に構築する
‘ Note : Task.IDではなくTask.UniqueIDを使用し、計算エンジンの負荷を考慮する
‘—————————————————————————————
Public Sub SynchronizeWBSStructure()
Dim prj As Project
Set prj = ActiveProject

‘ パフォーマンス最適化:再計算と画面更新を一時停止
CalculationState_Set False

On Error GoTo ErrorHandler

Dim currentTask As Task
Dim parentTask As Task

‘ 例:タスクの生成と階層化(本来はループ内で外部データから読み込む)
‘ 1. サマリータスクの作成
Set parentTask = prj.Tasks.Add(“フェーズ1:システム設計”)
parentTask.OutlineLevel = 1

‘ 2. 子タスクの作成
Set currentTask = prj.Tasks.Add(“要件定義ワークショップ”)
currentTask.OutlineLevel = 2

‘ 3. 依存関係の設定 (Predecessors)
‘ IDではなく、オブジェクト参照でリンクを張ることで、IDの変動に耐えうる設計にする
‘ LinkTasksメソッドは内部的にUniqueIDを追跡するため安全である
Call LinkTwoTasks(parentTask, currentTask)

‘ 4. 特定のカスタムフィールドに基づいたフラグ管理
currentTask.Text1 = “CRITICAL_PATH” ‘ 管理用タグの埋め込み

CleanUp:
CalculationState_Set True
MsgBox “WBSの構築が完了しました。”, vbInformation
Exit Sub

ErrorHandler:
MsgBox “エラー発生: ” & Err.Description, vbCritical
Resume CleanUp
End Sub

‘—————————————————————————————
‘ 補助関数:タスク間のリンク設定(堅牢版)
‘—————————————————————————————
Private Sub LinkTwoTasks(ByRef predTask As Task, ByRef succTask As Task)
If Not predTask Is Nothing And Not succTask Is Nothing Then
‘ 既にリンクがある場合はスキップする等のロジックをここに挟む
succTask.LinkPredecessors Tasks:=predTask, LinkType:=pjFinishToStart
End If
End Sub

‘—————————————————————————————
‘ パフォーマンス制御:大規模プロジェクトでの生命線
‘—————————————————————————————
Private Sub CalculationState_Set(ByVal isEnabled As Boolean)
With Application
If isEnabled Then
.Calculation = pjAutomatic
.ScreenUpdating = True
Else
.Calculation = pjManual
.ScreenUpdating = False
End If
End With
End Sub

3. チーム共有とバージョン管理の戦略

Project VBAのソースコードをGit等で管理する場合、バイナリである`.mpp`ファイルだけをコミットしても意味がない。差分が追えないからだ。

ソースコードのテキスト化(Export/Import戦略)

チーム開発では、以下の運用を徹底せよ。

1. コードの外部化: VBAエディタの「ファイルのエクスポート」機能を使い、`.bas`や`.cls`としてGitで管理する。
2. ビルドプロセスの自動化: 起動時に最新のソースコードをファイルシステムから自動インポートする「ローダーマクロ」を`Global.mpt`に一つだけ置いておく。
3. データベース(SQL Server等)との連携:

  • タスクのメタ情報や依存関係の定義をProjectファイル内ではなく、外部DBで保持する。
  • VBAは「DBの定義をProjectに反映する」だけのステートレスなエンジンとして振る舞わせる。これにより、ファイルが壊れてもデータは死なない。

データベース連携時の注意点

Project VBAからADODB等を使ってDBに接続する際、「長時間コネクションを保持しない」こと。Projectの操作(ガントチャートの描画など)は非常に重いため、DBロックが長時間続くとチーム全体のパフォーマンスを著しく阻害する。

4. 結論:真の自動化エンジニアへの道

Project VBA開発において、「動けばいい」という考えは負債を産むだけだ。

  • タスク操作は ID ではなく Object/UniqueID で行う。
  • ロジックは Global.mpt から分離し、バージョン管理可能な形式で配布する。
  • 再計算エンジンを制御し、パフォーマンスの重みを感じながらコードを書く。

この3点を守るだけで、あなたのツールは「壊れやすいマクロ」から「信頼されるエンタープライズ・システム」へと昇華する。

Project VBAは、複雑な現実世界をモデル化するための強力な武器だ。その設計を疎かにせず、常に「保守性の高み」を目指してほしい。これこそが、WBSという迷宮を支配する唯一の鍵である。

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