【テクニカル・上級編】【中級】テーブル定義の変更を検知し、変更箇所をメールで通知する監視ツールの開発 – Access VBA解析バイブル

スポンサーリンク

誰も語らない「Accessの深淵」:TableDef監視がもたらすシステム防衛の真実

いいか、Accessは「誰でも使える」という甘い言葉で語られがちだが、大規模な業務システムにおいて、それは地雷原を裸足で歩くのと同じだ。特に、複数人が触れる共有フロントエンドや、バックエンドのテーブル定義が「神の手」によって修正された時、システムは静かに崩壊へのカウントダウンを始める。

今日は、DAOの`TableDef`を監視し、変更を検知して管理者へ自動通知する「境界防衛ツール」のアーキテクチャについて語る。これは単なるユーティリティではない。システムの整合性を守るための最後の砦だ。

—

1. 監視のパラダイム:LastUpdatedの罠を越えて

多くのジュニアエンジニアは`TableDef.LastUpdated`プロパティを見て「これで完璧だ」と錯覚する。だが、甘い。このプロパティは「オブジェクト自体の変更」に反応するが、レコードの内容や、インデックス、さらにはリレーションシップの微細な変更を網羅しているとは限らない。

真の監視者は、`TableDef`のプロパティだけでなく、`Fields`コレクションと`Indexes`コレクションのハッシュ値を保持し、前回値との差分を突き合わせる。「何が変更されたか」ではなく「どこが食い違っているか」を特定するのだ。

2. 実装の要諦:メモリ管理と安全なAPI呼び出し

Access VBAで大規模なスキャンを行う際、最も恐れるべきはメモリリークだ。DAOオブジェクトの解放を怠れば、Accessは瞬く間に肥大化する。

以下のコードは、単に比較するだけでなく、オブジェクトの参照を確実に殺し、メモリをクリーンに保つ設計にしている。

‘ 【極限の監視ロジック】
‘ DAO.DatabaseとTableDefの参照を適切に管理し、メモリリークを排除する
Public Sub AuditTableStructure()
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim fld As DAO.Field

‘ DB参照はカレントを明示的に取得
Set db = CurrentDb

On Error GoTo Cleanup

For Each tdf In db.TableDefs
‘ システムテーブル(MSys)は除外する。これが基本中の基本だ。
If Left(tdf.Name, 4) <> “MSys” Then
‘ ここでLastUpdatedと、内部構成のシグネチャを比較する
‘ 変更があればEmailNotifyルーチンを呼び出す
If IsStructureChanged(tdf) Then
Call SendAlertEmail(tdf.Name, “構造変更を検知”)
End If
End If
Next tdf

Cleanup:
‘ 明示的なオブジェクト解放。VBAにおいてこれを疎かにすることは「罪」である
Set fld = Nothing
Set tdf = Nothing
Set db = Nothing
End Sub

3. 通知の先:CDOによるSMTP直撃の実装

Outlookを起動してメールを送る? 時代遅れも甚だしい。そんなことをすれば、ユーザーの画面にOutlookが顔を出し、処理が中断される。

シニアエンジニアはCDO (Collaboration Data Objects) を使う。OSレベルでSMTPセッションを確立し、AccessのUIを汚さずにパケットを飛ばすのだ。

‘ CDOを利用したサイレントメール通知
Private Sub SendAlertEmail(tableName As String, msg As String)
Dim iMsg As Object
Dim iConf As Object

Set iMsg = CreateObject(“CDO.Message”)
Set iConf = CreateObject(“CDO.Configuration”)

‘ サーバー設定を構成
With iConf.Fields
.Item(“http://schemas.microsoft.com/cdo/configuration/sendusing”) = 2
.Item(“http://schemas.microsoft.com/cdo/configuration/smtpserver”) = “smtp.your-server.com”
.Item(“http://schemas.microsoft.com/cdo/configuration/smtpserverport”) = 587
.Update
End With

With iMsg
Set .Configuration = iConf
.To = “admin@company.com”
.From = “access-monitor@company.com”
.Subject = “【警告】テーブル構造変更検知: ” & tableName
.TextBody = “テーブル [” & tableName & “] に変更が検知されました。” & vbCrLf & msg
.Send
End With

‘ ここでもオブジェクトを確実に破棄
Set iMsg = Nothing
Set iConf = Nothing
End Sub

—

4. 伝説のエンジニアからの忠告

このツールを実装する際、以下の3点を忘れないでほしい。

1. システムテーブルの不可侵性: `MSys`系テーブルをいじろうとするな。それはAccessというブラックボックスの心臓に触れる行為だ。監視対象外とすることを徹底せよ。
2. 実行タイミングの設計: この処理は重い。起動時に毎回走らせるのではなく、特定の管理者ログイン時、あるいは深夜のバッチ処理として実行させるのが、パフォーマンスを維持するアーキテクトの思考だ。
3. ログの永続化: メール通知が失敗した時のために、必ずローカルのテキストファイルか、専用の監査テーブルに「いつ、何が変更されたか」を書き出せ。メールは所詮「プッシュ通知」に過ぎない。

技術とは、単にコードを書くことではない。「何が起こりうるか」を予測し、そのリスクを完全に制御下に置くことだ。

さあ、あなたのAccessを、誰にも壊させない強固なシステムへと昇華させろ。健闘を祈る。

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