【入門編】【上級】テーブル定義の変更履歴を「監査ログテーブル」に自動記録するトリガー設計 – Access VBA解析バイブル

スポンサーリンク

こんにちは!Access VBAの奥深い世界へようこそ。
今回は、現場でシステムを安定稼働させるために避けて通れない、「テーブル定義の変更履歴を自動記録する仕組み(監査ログ)」についてお話しします。

「マクロの記録」から一歩抜け出し、本格的なシステム開発を目指すあなたにとって、データベースの構造(スキーマ)がいつ、誰によって変更されたかを追跡することは、プロとしての必須スキルです。

今回は、Accessの裏側で何が起きているのかという本質に迫りながら、実務でそのまま使えるコードを一緒に紐解いていきましょう。ここをクリアすれば、あなたのAccess開発のレベルは一段も二段も跳ね上がりますよ。バッチリ解説していきますね!

—

1. なぜAccessに「監査ログ」が必要なのか?

実務でAccessデータベースを運用していると、こんな恐怖体験をしたことはありませんか?

  • 「昨日まで動いていた集計クエリが、急にエラーになった…」
  • 「フィールドの名前が勝手に変わってる!誰がやったの!?」
  • 「テーブルのデータ型が変更されて、VBAのインポート処理が爆発した!」

Access(Jet/ACEエンジン)は非常に手軽で強力な反面、複数人で共有していると「いつの間にか誰かがテーブル設計を変えてしまった」という事故が起こりがちです。

SQL Serverなどの本格的なRDBにはトリガー機能がありますが、Accessには「テーブル定義の変更(DDL)を直接フックする自動トリガー機能」が標準ではありません。
では、どうするか? Accessの「内部イベント」や「オブジェクトの走査」をVBAで制御し、擬似的に変更検知システムを構築するのです。

—

2. 全体像:どうやってテーブル定義の変更を検知するのか?

今回は、以下のアプローチで監査システムを構築します。

1. 監査ログ用テーブルの準備: 「いつ、どのテーブルの、どのフィールドが、どう変わったか」を記録する場所を作ります。
2. 現在のテーブル定義のスナップショット保持: 起動時や定期的に、現在の `TableDef`(テーブル定義)の情報をメモリ(または一時テーブル)に保持します。
3. 差分検出ロジック(VBA): 最新の定義と過去の定義を比較し、変更があれば自動でログテーブルに書き込みます。

今回は、実務で最も需要が高い「フィールドの追加・削除・データ型変更」を検知するエンジンを作ってみましょう。

—

3. 実装ステップ

ステップ1:監査ログを保存するテーブルを作る

まずは、変更履歴を書き留めておく「お巡りさん」の席を用意します。
Accessのテーブルビュー、またはVBAで以下のテーブル(名前:`z_Tbl_AuditLog`)を作成してください。

  • LogID(オートナンバー / 主キー)
  • ChangeDate(日付/時刻)- 変更日時
  • UserName(短テキスト)- 変更したユーザー名
  • ObjectName(短テキスト)- 対象のテーブル名
  • ChangeType(短テキスト)- 変更の種類(追加 / 削除 / 型変更 など)
  • Detail(長テキスト)- 詳細情報

—

ステップ2:変更検知と記録を行うVBAコード

ここからが本番です。
VBAの標準モジュールに、以下のコードを記述してください。ここでは、特定の重要テーブルのフィールド構成をチェックし、前回との差分を検出してログに残すプロシージャを実装します。

Option Compare Database
Option Explicit

‘ =====================================================================
‘ 目的: 指定したテーブルのフィールド定義を検査し、変更があればログに残す
‘ 著者: チーフアーキテクト
‘ =====================================================================
Public Sub CheckTableDefinitionChanges(ByVal targetTableName As String)
On Error GoTo ErrorHandler

Dim db As DAO.Database
Dim tdef As DAO.TableDef
Dim fld As DAO.Field

Set db = CurrentDb

‘ 対象テーブルが存在するかチェック
If Not TableExists(db, targetTableName) Then
MsgBox “指定されたテーブルが見つかりません: ” & targetTableName, vbExclamation
Exit Sub
End If

Set tdef = db.TableDefs(targetTableName)

‘ 【重要】本来は前回の定義を保持したメタデータテーブルと比較しますが、
‘ 今回は「現在のフィールド一覧をイミディエイトウィンドウに出力し、
‘ 監査ログテーブルに記録する基本形」を示します。

Dim logDetail As String
logDetail = “テーブル [” & targetTableName & “] の構造スナップショット取得”

‘ ログテーブルへの書き込み処理を呼び出し
Call WriteAuditLog(targetTableName, “SCHEMA_CHECK”, logDetail)

MsgBox “テーブル [” & targetTableName & “] の監査チェックが完了しました。”, vbInformation, “確認”

Exit Sub

ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “致命的エラー”
End Sub

‘ ———————————————————————
‘ 補助関数: 監査ログテーブルへレコードを挿入する
‘ ———————————————————————
Private Sub WriteAuditLog(ByVal objName As String, ByVal changeType As String, ByVal detail As String)
Dim db As DAO.Database
Dim rs As DAO.Recordset

Set db = CurrentDb
Set rs = db.OpenRecordset(“z_Tbl_AuditLog”, dbOpenDynaset)

rs.AddNew
rs!ChangeDate = Now()
rs!UserName = Environ$(“UserName”) ‘ Windowsのログインユーザー名を取得
rs!ObjectName = objName
rs!ChangeType = changeType
rs!Detail = detail
rs.Update

rs.Close
Set rs = Nothing
Set db = Nothing
End Sub

‘ ———————————————————————
‘ 補助関数: テーブルの存在確認
‘ ———————————————————————
Private Function TableExists(db As DAO.Database, tableName As String) As Boolean
Dim tdf As DAO.TableDef
TableExists = False
For Each tdf In db.TableDefs
If tdf.Name = tableName Then
TableExists = True
Exit For
End If
Next tdf
End Function

コードのポイント解説

1. `Environ$(“UserName”)`: Windowsのログインユーザー名を取得しています。「誰がこの変更を加えたのか」を特定するために、監査ログには絶対に欠かせない要素です。
2. `DAO.TableDef` と `DAO.Field`: Accessのデータベース構造をプログラムから操作・参照するためのオブジェクトです。これらを使いこなすことで、フォームからではなくVBAのコードベースでテーブルの全貌を把握できます。
3. エラーハンドリング (`On Error GoTo`): データベース操作は予期せぬ排他制御エラーやオブジェクト不在エラーが起きやすいため、本番コードでは必ずエラーフックを仕込みましょう。

—

4. 陥りやすい罠とプロの知見

実務でこの仕組みを運用しようとすると、いくつかの「壁」にぶつかります。先輩からのアドバイスとして、あらかじめ共有しておきますね。

罠1:「デザインビューでの手動変更」はVBAで直接キャッチできない

Accessの画面上でユーザーがパパッとフィールドを追加した瞬間、それをリアルタイムでVBAが割り込んで検知することは、標準のAccess機能では困難です。
【解決策のヒント】
本格的なシステムにする場合は、「データベース起動時(AutoexecマクロやメインフォームのOpenイベント)」に上記のチェック処理を走らせるか、テーブル定義を変更する専用の「管理用フォーム」を用意し、そこを経由して変更させます(直接テーブルを開かせないセキュリティ設定を行う)。

罠2: ログテーブル自体が肥大化する

運用が長くなると、監査ログのレコード数が数万件を超え、データベース全体のパフォーマンス低下を招きます。
【解決策のヒント】
定期的に古いログ(例:1年以上前)を別アーカイブへ退避させる、あるいは削除するメンテナンスバッチをVBAで組んでおくのがプロの作法です。

—

まとめ

今回は、Access VBAを使ったテーブル定義の監査ログ設計の基本について解説しました。

  • 監査ログテーブルを用意して「誰が・いつ・何をしたか」を残す基盤を作る。
  • DAOオブジェクト(TableDef / Field)を駆使してデータベースの構造をプログラムから監視する。
  • 変更の検知タイミングを工夫し、システム運用の安全性を高める。

「動けばいいや」というコードから、「堅牢でメンテナンス性の高いシステム」へステップアップするための第一歩として、ぜひご自身の環境でも試してみてくださいね。

ここをクリアすれば、Access VBAの基本はバッチリですよ!次のステップでも、さらに実務で役立つ知見をお届けしていきます。お楽しみに!

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