Accessの「神殿」を守れ:TableDefメタデータ監視によるガバナンスの極致
Accessというシステムは、その柔軟性ゆえに「誰でも触れる」という致命的な脆弱性を抱えている。現場の担当者が意図せずフィールドを追加し、データ型を壊し、それが連鎖的にクエリやVBAの破綻を招く……。これを防ぐのは規約ではなく、システムによる「不可侵の監視」である。
本稿では、Accessの心臓部である `DAO.TableDef` を監視し、構造変更を検知して即座に管理者へ通知する、ガバナンスの要となるアーキテクチャを解説する。
—
1. 監視の核心:メタデータハッシュによる変更検知
構造変更を検知する際、テーブルのレコードをループして比較するのは愚策だ。それはパフォーマンスを著しく低下させ、ロックの競合を招く。
我々が取るべき手法は、「DAOメタデータのハッシュ化」である。`TableDef` の `Fields` および `Properties` をシリアライズし、SHA-256でフィンガープリントを生成。これを「管理用テーブル」に永続化し、起動時に照合する。
実装の戦略
1. 初期化時(または起動時): 現在の全テーブルのフィールド構成をシリアライズしてハッシュ値を生成。
2. 比較アルゴリズム: 既存のハッシュ値と現在のハッシュ値を照合。差異があれば「変更あり」と判定。
3. 通知: CDO (Collaboration Data Objects) を使用し、Outlookを介さずにSMTP経由で直接ゲートウェイへ投げる。
—
2. 実践:DAOメタデータ監視の実装
以下に、システムが起動するたびに構造の「聖域」をチェックする中核ロジックを示す。
‘ 必要なライブラリ: Microsoft DAO 3.6 Object Library / Microsoft CDO for Windows 2000
Option Explicit
Public Sub VerifySchemaIntegrity()
Dim db As DAO.Database
Dim td As DAO.TableDef
Dim fld As DAO.Field
Dim schemaInfo As String
Set db = CurrentDb
‘ システムテーブルを除外して監視
For Each td In db.TableDefs
If Left(td.Name, 4) <> “MSys” Then
schemaInfo = GenerateTableSignature(td)
‘ ここでテーブル「tbl_SchemaLog」のハッシュ値と比較する
‘ 一致しなければ NotifyAdmin(td.Name) を呼び出す
If IsModified(td.Name, schemaInfo) Then
Call SendViolationAlert(td.Name)
End If
End If
Next td
‘ オブジェクトの明示的解放(メモリ管理の鉄則)
Set td = Nothing
Set db = Nothing
End Sub
Private Function GenerateTableSignature(td As DAO.TableDef) As String
Dim fld As DAO.Field
Dim sig As String
‘ フィールド名と型を連結してユニークなシグネチャを作る
For Each fld In td.Fields
sig = sig & fld.Name & “:” & fld.Type & “|”
Next fld
GenerateTableSignature = sig
End Function
—
3. レガシーの制約を突破する通知技術
Outlookのオブジェクトモデル(`Outlook.Application`)を呼び出すのは、セキュリティ警告やプロセスの残留といったリスクを伴うため、プロフェッショナルな環境では推奨しない。
代わりに、Windows標準の CDO (Collaboration Data Objects) を使用せよ。これはプロセス外部で完結するため、Accessの実行コンテキストに影響を与えず、極めて軽量かつ安定している。
CDOによるSMTP直接送出コード
Public Sub SendViolationAlert(tableName As String)
Dim cdoMsg As Object
Set cdoMsg = CreateObject(“CDO.Message”)
With cdoMsg
.Subject = “【警告】テーブル構造の変更が検知されました: ” & tableName
.From = “monitor@internal.system”
.To = “admin@company.com”
.TextBody = “テーブル [” & tableName & “] のメタデータに変更が検知されました。” & vbCrLf & _
“直ちにアクセス権限とログを確認してください。”
‘ SMTP設定(社内サーバーに合わせて構成)
.Configuration.Fields.Item(“http://schemas.microsoft.com/cdo/configuration/sendusing”) = 2
.Configuration.Fields.Item(“http://schemas.microsoft.com/cdo/configuration/smtpserver”) = “smtp.your-server.com”
.Configuration.Fields.Update
.Send
End With
Set cdoMsg = Nothing
End Sub
—
4. アーキテクトからの忠告
このツールを実装するにあたり、以下の二点を肝に銘じてほしい。
1. メモリリークの排除: `DAO.TableDef` や `Recordset` をループで回す際は、必ずループ内で個別に `Set obj = Nothing` を実行すること。Accessのガベージコレクションは信用するな。
2. ホワイトリスト運用: 開発中には自身で構造変更を行うはずだ。その際、監視をオフにするための「管理者用メンテナンスモード」をフラグ管理で実装せよ。これを忘れると、深夜に管理者のメールボックスがアラートで埋まることになる。
Accessは単なるデスクトップアプリではない。適切に監視された環境下では、極めて堅牢な業務基盤となり得る。システムを守るためのこの「境界線」を構築し、レガシーを、遺産ではなく「資産」へと昇華させよ。
