【PowerPoint VBA】プレゼンに「記憶」を刻む:CustomDocumentPropertiesによる堅牢な監査ログ実装術
現場で乱立するPowerPointファイル。誰が、いつ、どのマクロを実行したのか? 共有サーバー上で「誰かが見知らぬうちに内容を書き換えた」という恐怖と戦うのはもう終わりにしよう。
外部データベースやテキストログに頼る手法は、ネットワーク障害やパス権限の問題で脆弱だ。「ファイル自体にログを埋め込む」。この設計こそ、配布・共有が前提のPowerPointにおいて最もポータブルで強力な解決策となる。
本稿では、`Presentation.CustomDocumentProperties`を駆使し、ファイル内に不可視の監査履歴を刻み込む「堅牢なアーキテクチャ」を伝授する。
—
1. なぜ「CustomDocumentProperties」なのか
多くのエンジニアがログ管理に外部ファイル(CSVやDB)を選択するが、これには致命的な欠陥がある。
- パス依存: サーバー移動や共有フォルダの同期でリンクが切れる。
- 権限エラー: ログファイルへの書き込み権限がないユーザーがマクロを実行すると即座にクラッシュする。
一方、`CustomDocumentProperties`は、ファイル形式(pptx)のメタデータ領域にキー・バリュー形式でデータを保存する。ファイルがメールで送られようが、コピーされようが、ログは「ファイルと共に移動」する。これこそが、配布型ツールにおける真の永続化だ。
—
2. 実装の要:堅牢なログ追記ロジック
まずは、泥臭いエラーハンドリングを排除した、実務でそのまま使えるクラスモジュールに近い関数を紹介する。
監査ログ記録のプロダクションコード
‘ 監査ログをファイルプロパティに追記する関数
‘ @param logMessage 記録する処理内容
Public Sub WriteAuditLog(ByVal logMessage As String)
Dim pptPres As Presentation: Set pptPres = ActivePresentation
Dim customProps As DocumentProperties
Dim logProp As DocumentProperty
Dim logKey As String: logKey = “AuditLog”
‘ 実行者情報の取得(環境変数から)
Dim userName As String: userName = Environ(“USERNAME”)
Dim logEntry As String
‘ ログフォーマット: [日時] [実行者] 処理内容
logEntry = Format(Now, “yyyy/mm/dd hh:nn:ss”) & ” | ” & userName & ” | ” & logMessage
On Error Resume Next
Set customProps = pptPres.CustomDocumentProperties
Set logProp = customProps(logKey)
If Err.Number <> 0 Then
‘ プロパティが未作成なら新規作成
customProps.Add Name:=logKey, LinkToContent:=False, _
Type:=msoPropertyString, Value:=logEntry
Else
‘ 既存ログに改行区切りで追記(追記しすぎると容量制限に注意)
logProp.Value = logProp.Value & vbCrLf & logEntry
End If
On Error GoTo 0
End Sub
—
3. 実務で「詰まない」ための設計思想
この実装には、アーキテクトとして守るべき3つの鉄則がある。
① 容量制限との戦い
`CustomDocumentProperties`には格納できる文字列の長さに限界がある(約255文字以上は可能だが、Officeの仕様上あまりに巨大なデータを詰め込むとファイル破損のトリガーになる)。
- 対策: ログが一定行数を超えたら古いものを削除する「ローリングロジック」を組み込むか、あくまで「重要な操作の要約」のみを記録するように設計すること。
② 実行者の識別
`Environ(“USERNAME”)`はOSから取得する簡易的な方法だが、セキュリティが厳しい環境では改ざんの余地がある。厳密な監査が必要な場合は、Active Directoryの情報を取得するAPIコールが必要だが、まずはこの実装で「誰が触ったかのログを意識させる」心理的バリアを張るだけでも抑止力は格段に向上する。
③ 不正利用防止の「見えない印」
このログは[ファイル] > [情報] > [プロパティ] > [詳細プロパティ] からユーザーが見ようと思えば見えてしまう。もし機密性が極めて高い場合は、値をBase64エンコードしたり、単純なXOR暗号化を施すことで、一般ユーザーの覗き見を防止せよ。
—
4. プロの現場での活用シナリオ
単にログを溜めるだけでなく、マクロの冒頭に以下のようなガード節を入れるのが「伝説的な」エンジニアのやり方だ。
Sub MainProcess()
‘ 処理開始時に監査ログを記録
Call WriteAuditLog(“MainProcess 開始”)
On Error GoTo ErrorHandler
‘ メインの業務ロジック
‘…
Call WriteAuditLog(“MainProcess 正常終了”)
Exit Sub
ErrorHandler:
Call WriteAuditLog(“ERROR: ” & Err.Description)
MsgBox “エラーが発生しました。ログを記録しました。”
End Sub
このように、「成功ログ」と「エラーログ」の双方をファイルに刻むことで、後日「あの時なぜ失敗したのか?」と問い合わせが来た際、ファイルを開くだけで状況が手に取るように分かるようになる。
結びに代えて
自動化とは、ただの手抜きではない。「後から振り返ったときに、すべてが可視化されている状態」を構築することこそが真の自動化だ。
あなたのコードが、現場で誰にも迷惑をかけず、管理者の手を煩わせることなく、静かに自律的に成長するドキュメントへと変わることを期待している。さあ、今すぐあなたのプレゼンファイルに「歴史」を刻み込んでほしい。
