プロジェクトの「魂」をGitと同期せよ:VBAカスタムプロパティへのコミットハッシュ自動埋め込み術
業務自動化の現場で最も恐ろしいのは、「今動いているこのファイルが、どのリポジトリのどのバージョンから生成されたのか不明」という事態だ。
Project VBAを扱うエンジニアにとって、ファイルは単なる成果物ではなく、コードとロジックが凝縮された「実行可能なドキュメント」であるべきだ。Git管理下のプロジェクトで、「保存のたびにコミットハッシュをファイル内部のカスタムプロパティに刻み込む」という設計は、単なる管理術を超えた「トレーサビリティの極致」である。
今回は、この実装を堅牢に行うためのアーキテクチャを伝授する。
—
1. なぜ「手動管理」は敗北するのか
多くの現場では、バージョン番号をセルにハードコーディングしたり、ファイル名に日付を入れたりして管理している。だが、これは以下の理由でいずれ破綻する。
- ヒューマンエラー: 修正後にコミットを忘れる、あるいは別ブランチで作業して混同する。
- 非同期性: コードの実体(Git)とファイルの状態が乖離する。
- 不透明性: 自動化ツールが「今、正しいコードで動いているか」を判定できない。
我々が目指すべきは、VBAプロジェクトの保存イベント(BeforeSave)をトリガーに、GitのHEADハッシュを取得し、文書情報(CustomDocumentProperties)へ強制的に同期させる設計だ。
—
2. 堅牢な設計:実装の要所
この実装には、以下の3つの制約を設ける。
1. Git環境の疎結合: `git.exe`のパスが環境依存であることを考慮し、呼び出しは動的に行う。
2. エラーハンドリング: Gitが初期化されていないフォルダでもクラッシュさせない。
3. プロパティの冪等性: 存在しないプロパティは生成し、存在すれば更新する。
—
3. プロダクションコード:`ThisWorkbook`への実装
以下のコードを、Excelの`ThisWorkbook`モジュールに貼り付ける。
‘ ———————————————————————-
‘ プロジェクト名: Git-VBA Integration Engine
‘ 概要: 保存時に現在のGitコミットハッシュをカスタムプロパティに埋め込む
‘ ———————————————————————-
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
On Error Resume Next
Dim commitHash As String
commitHash = GetCurrentGitHash(ThisWorkbook.Path)
If commitHash <> “” Then
UpdateCustomProperty “LastCommitHash”, commitHash
End If
On Error GoTo 0
End Sub
‘ Gitの最新コミットハッシュを取得する(シェル経由)
Private Function GetCurrentGitHash(ByVal projectPath As String) As String
Dim shell As Object
Dim exec As Object
Dim cmd As String
‘ git rev-parse HEAD でハッシュを取得
cmd = “cmd /c cd /d “”” & projectPath & “”” && git rev-parse –short HEAD”
Set shell = CreateObject(“WScript.Shell”)
Set exec = shell.Exec(cmd)
‘ エラー時は空文字を返す
If exec.StdErr.ReadAll <> “” Then
GetCurrentGitHash = “”
Else
GetCurrentGitHash = Trim(exec.StdOut.ReadAll)
End If
End Function
‘ カスタムプロパティを更新する(存在しなければ作成)
Private Sub UpdateCustomProperty(ByVal propName As String, ByVal propValue As String)
Dim cp As DocumentProperty
Dim exists As Boolean
On Error Resume Next
Set cp = ThisWorkbook.CustomDocumentProperties(propName)
exists = (Err.Number = 0)
On Error GoTo 0
If Not exists Then
ThisWorkbook.CustomDocumentProperties.Add _
Name:=propName, LinkToContent:=False, Type:=msoPropertyTypeString, Value:=propValue
Else
cp.Value = propValue
End If
End Sub
—
4. 運用の極意とパフォーマンスへの配慮
なぜ`WScript.Shell`の`Exec`を使うのか
`Run`メソッドではなく`Exec`を使う理由は、標準出力をストリームとして取得できるからだ。`Run`によるファイル書き出しを経由する手法は、I/O負荷が高く、アンチパターンである。
セキュリティと権限
`cmd /c` を実行するため、組織のポリシーによってはマクロ制限に引っかかる場合がある。その際は、Gitのハッシュを保存する専用の環境変数を用意し、VBAから`Environ`で取得する運用に切り替えることも検討してほしい。
データベース連携のヒント
この実装により、Excelファイル自体が「自分自身のバージョン情報」を保持することになる。
今後、このファイルをマスターとしてデータベースにインポートする際、このプロパティを読み取ることで、「どのコミット時点のロジックで処理されたデータか」をDB側で管理できるようになる。これはデータ分析の整合性を担保する上で最強の武器になる。
—
最後に:エンジニアとしての矜持
コードを自動化するだけなら誰にでもできる。だが、「その自動化が、どのように管理され、どのように検証されるべきか」まで設計してこそ、真の業務自動化エンジニアだ。
この「コミットハッシュの埋め込み」を実装すれば、チームメンバーはファイルを開いた瞬間に、それが最新の正当なコードベースであるかをプロパティから確認できる。
「動けばいい」という甘えを捨て、追跡可能な堅牢なシステムを構築せよ。それが、君の作成する自動化ツールが「社内の資産」として生き残るための唯一の道だ。
