【上級者向け】MS Projectのバージョン管理:VBAとGitを融合させる構成管理の極意
プロジェクトマネジャー諸君、日々増え続ける「Schedule_v2_final_rev3.mpp」といった無秩序なファイル名に絶望していないか?
MS Project(以下、MSP)の標準ファイル形式(`.mpp`)は、バイナリのブラックボックスである。そのため、誰がどこを変更したのか、タスクの依存関係がどうズレたのかを、通常のGitやSVNなどのバージョン管理システム(VCS)で差分(Diff)を取ることは不可能に近い。結果として、共有サーバーの肥大化と「誰のスケジュールが最新か分からない」というカオスな状況を生み出している。
この構造的な敗北を打ち破る鍵が、「保存時のXMLエクスポート」と「Gitの自動連携」の融合だ。
今回は、VBAのイベントフックを極限までチューニングし、ファイル保存の瞬間にMSPを可読性の高いXMLに変換した上で、バックグラウンドでGitコミットまでを完全に自動化する「エンタープライズ・コンフィグレーション・マネジメント(構成管理)スクリプト」を伝授する。
—
なぜ「ただのVBAコード」では実務で破綻するのか?
多くのエンジニアが「保存時にGitコマンドを叩くVBA」を作ろうとして挫折する。その理由は以下の3点に集約される。
1. 同期処理によるフリーズ地獄
Gitの外部プロセス(`git.exe`)の実行を同期的(同期シェルの起動)に待たせると、大規模プロジェクトのXML出力(数万行)とコミット処理が重なった際、MSPのUIが数秒間フリーズし、ユーザーにストレスを与える。
2. ワーキングディレクトリのコンテキスト喪失
VBAから外部コマンドを叩く際、カレントディレクトリの制御を誤ると、Gitリポジトリの外でコマンドが実行され、エラーでマクロが沈黙する。
3. 排他制御とゴーストプロセスの放置
多重保存や例外発生時に、`.git` ロックファイルが残存したり、WScript.Shellのゾンビプロセスがメモリリークを引き起こす。
これらをクリアし、「プロフェッショナルな現場に耐えうる堅牢性」を持たせたプロダクションコードを以下に公開する。
—
アーキテクチャの全体像
1. イベントフック: `ThisProject` モジュールの `ProjectBeforeSave` イベントをキャプチャ。
2. XMLシリアライズ: MSP標準の `FileSaveAs` メソッドを用いて、ワークスペース直下に決まった名前(例: `project_source.xml`)で出力。
3. 非同期バッチ処理: VBAから直接 `git.exe` を叩くのではなく、安全かつ確実に環境変数を継承したバッチファイル、あるいはWScript.Shellの非同期実行(`Run`メソッドの第2引数・第3引数の制御)を利用してコミットを流し込む。
—
実装コード:ThisProject モジュール
以下のコードを、対象となるMSPファイルの `ThisProject` クラスモジュールにそのまま貼り付けてほしい。
‘ Option Explicitの強制による型安全性の確保
Option Explicit
Private Sub ProjectBeforeSave(ByVal AS_SaveAs As Boolean, ByRef Cancel As Boolean)
On Error GoTo ErrorHandler
‘ —————————————————————-
‘ 定数定義(環境に合わせてパスやファイル名を調整すること)
‘ —————————————————————-
Const XML_FILE_NAME As String = “project_source.xml”
Dim repoPath As String
Dim xmlPath As String
Dim commitMessage As String
Dim fso As Object
Dim shell As Object
Dim cmd As String
‘ 1. GitリポジトリのルートパスをMSPファイルの保存先から動的に取得
If ActiveProject.Path = “” Then
‘ 未保存の新規ファイルの場合は処理をスキップ(または初回保存を促す)
MsgBox “プロジェクトファイルが未保存です。一度保存してからGit連携を行ってください。”, vbExclamation, “Git自動連携”
Exit Sub
End If
repoPath = ActiveProject.Path
xmlPath = repoPath & “\” & XML_FILE_NAME
‘ 2. FileSystemObjectによるパス検証
Set fso = CreateObject(“Scripting.FileSystemObject”)
If Not fso.FolderExists(repoPath) Then
Err.Raise 9999, “GitIntegration”, “指定された保存先ディレクトリが存在しません: ” & repoPath
End If
‘ 3. 【最重要】MSPデータをXML形式でエクスポート
‘ pjXML は Projectの標準定数 (通常は 32)。安全のため数値で指定することもある。
‘ ※保存処理自体の邪魔をしないよう、バックグラウンドでのサイレントエクスポートを模倣
Application.FileSaveAs Name:=xmlPath, FormatID:=”MSProject.XML”
‘ 4. コミットメッセージの動的生成(プロジェクト名+タイムスタンプ)
commitMessage = “Auto-commit: ” & ActiveProject.Name & ” (” & Format(Now, “YYYY-MM-DD HH:MM:SS”) & “)”
‘ 5. Gitコマンドの構築
‘ cd /d で確実にドライブを移動し、add -> commit を一連のトランザクションとして実行
‘ ※環境変数PATHにgitが含まれている前提
cmd = “cmd.exe /c cd /d “”” & repoPath & “”” && ” & _
“git add “”” & XML_FILE_NAME & “”” && ” & _
“git commit -m “”” & commitMessage & “”””
‘ 6. 外部プロセスの実行(非同期・ウィンドウ非表示)
Set shell = CreateObject(“WScript.Shell”)
‘ 第2引数: 0 (ウィンドウ非表示), 第3引数: False (非同期実行でMSPのフリーズを防ぐ)
shell.Run cmd, 0, False
‘ 正常終了ログ(イミディエイトウインドウへ出力)
Debug.Print “[Git Auto-Sync] Success: ” & commitMessage
Set fso = Nothing
Set shell = Nothing
Exit Sub
ErrorHandler:
‘ 異常系:自動化の失敗が本番のファイル保存フロー自体をブロックしない設計にする
MsgBox “Git自動連携中にエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“詳細: ” & Err.Description, vbCritical, “Git Integration Error”
‘ 必要に応じてエラーログをファイルに出力する処理をここに挟むと完璧
Set fso = Nothing
Set shell = Nothing
End Sub
—
現場で絶対に押さえておきたいアーキテクチャ上の注意点
1. メイン保存フローをブロックしない「非同期設計」
コード内の `shell.Run cmd, 0, False` に注目してほしい。
最後の引数を `False`(非同期)にすることで、VBAは `git commit` の完了を待たずに処理を抜ける。これにより、数メガバイトある巨大なXMLのコミット処理中であっても、ユーザーはストレスなくMSPの操作を継続できる。
2. 「.mpp」ではなく「.xml」をバージョン管理する理由
前述した通り、`.mpp` はバイナリであるためGitで差分(Diff)が見えない。しかし、MSPが吐き出すXMLは構造化されたテキストである。
これにより、以下のような圧倒的なメリットが生まれる。
- Pull Requestでのコードレビュー: 「どのリソースに、どのタスクの工数が追加されたか」をテキストのDiffとしてレビュー可能になる。
- コンフリクトの解決: 複数人で同時にスケジュールをいじった場合でも、テキストベースであればGitの三方マージ(Three-way merge)のアルゴリズムが効きやすくなる(※XMLの構造特性を理解した上での運用が必要だが、バイナリより遥かにマシである)。
3. 無限ループの防止とセキュリティ
プロジェクトファイル自体(`.mpp`)をGit管理対象に含める場合、`.gitignore` に `project_source.xml` を登録するかどうかはチームのポリシーによる。
あえてXMLをリポジトリに残すことで、Web上のGitクライアント(GitHubやGitLabなど)から直接ガントチャートの進捗状況をテキストでパース・可視化するCI/CDパイプラインを組むことも容易になる。
—
チーフアーキテクトからの提言
VBAを単なる「手作業の代替おもちゃ」として扱う時代は終わった。
VBAは、Windows環境における最強のローカル・オーケストレーション・ツールである。
この自動化スクリプトをチームに導入した瞬間から、あなたのプロジェクト管理は「個人の記憶と属人化されたファイルサーバー」から、「履歴が担保されたエンジニアリング・プロセス」へと昇華する。
今すぐこのコードをあなたのプロジェクトに組み込み、バージョン管理の闇に光を射してほしい。
