Access VBAの深淵へ:テーブル構造の「改ざん」を許さない、監視システムの作り方
こんにちは。システム開発の現場で、長年「コードの美学」と「堅牢性」を追求してきたエンジニアです。
Accessを使っていると、ふと不安になることはありませんか?
「誰かが勝手にフィールドを追加したり、データ型を変えたりしていないか?」
「運用中に構造が変わると、バックエンドのクエリが全滅するのではないか?」
そう、「勝手な変更」はシステム開発における最大の癌です。今日は、Access VBAを駆使して、テーブルの構造変更を検知し、即座に管理者のメールへ警告を飛ばす「番犬」のようなプログラムを構築する方法を伝授します。
マクロの記録から卒業し、プロのエンジニアとしての第一歩を踏み出しましょう。
—
1. なぜ「TableDef」を知る必要があるのか?
Accessにおいてテーブルは単なるデータの箱ではありません。VBAの世界では、`TableDef`オブジェクトという「設計図そのもの」を操作できる強力なインターフェースが用意されています。
- TableDef: テーブルの構造(列名、データ型、サイズ、インデックス)を保持する心臓部。
- Fields: そのテーブルに存在するフィールドの集合。
これらを監視することで、「昨日と今日でテーブルの設計図が変わっていないか?」を判定するのです。
—
2. 監視システムのアーキテクチャ
今回の監視ツールは、以下の3ステップで動作します。
1. スナップショットの保存: 現在のテーブル定義を「設計図管理テーブル」として記録しておく。
2. 比較ロジック: システム起動時やタイマー監視で、現在の`TableDef`と保存した設計図を照合する。
3. アラート発報: 差異があれば、`CDO.Message`を使って管理者のメールへ通知を送る。
—
3. 実装コード:テーブルの構造を指紋のように保存する
まずは、現在の構造を比較するための「指紋(ハッシュのようなもの)」を作成する関数です。
‘ 【重要】DAOライブラリを参照設定に追加してください
‘ 参照設定: Microsoft Office 16.0 Access database engine Object Library
Public Function GetTableFingerprint(tableName As String) As String
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim fld As DAO.Field
Dim fingerprint As String
Set db = CurrentDb
Set tdf = db.TableDefs(tableName)
‘ フィールド名と型を連結してユニークな文字列を作る
For Each fld In tdf.Fields
fingerprint = fingerprint & fld.Name & “:” & fld.Type & “|”
Next fld
GetTableFingerprint = fingerprint
End Function
解説:
ここでは `fld.Type`(データ型)と `fld.Name`(フィールド名)を結合しています。もし誰かが「数値型」を「テキスト型」に変えたら、文字列が一致しなくなるため、即座に検知可能です。
—
4. 変更を検知し、メールを送信する
次に、あらかじめ保存しておいた値と現在の値を比較し、変更があればメールを送るプロシージャです。
Public Sub MonitorTableStructure(targetTable As String)
Dim savedFingerprint As String
Dim currentFingerprint As String
‘ 本来は「設計図管理テーブル」から保存値を読み込む
savedFingerprint = DLookup(“Fingerprint”, “tbl_Settings”, “TableName='” & targetTable & “‘”)
currentFingerprint = GetTableFingerprint(targetTable)
If savedFingerprint <> currentFingerprint Then
‘ 変更があった!メール送信処理へ
Call SendAlertEmail(“警告: テーブル構造が変更されました”, targetTable)
End If
End Sub
メール送信のヒント(CDOライブラリ利用)
VBAからメールを送る際は、Outlookを立ち上げるよりも`CDO (Collaboration Data Objects)`を使うのが、バックグラウンド処理の鉄則です。
‘ 簡略化した送信イメージ
Sub SendAlertEmail(subject As String, tableName As String)
Dim msg As Object
Set msg = CreateObject(“CDO.Message”)
‘ SMTP設定などを記述(※社内環境に合わせて設定)
msg.Subject = subject
msg.TextBody = “テーブル [” & tableName & “] に構造変更が検知されました。”
‘ msg.Send
Debug.Print “警告メールを送信しました。”
End Sub
—
5. 陥りやすい罠とエンジニアの心得
この開発で初心者が必ずハマるポイントが2つあります。
1. 「システムテーブル」へのアクセス: `TableDefs`には、MSysから始まるシステムテーブルも含まれます。これらを監視すると収拾がつかなくなるので、`If Left(tdf.Name, 4) <> “MSys” Then` のように除外フィルタを必ず入れてください。
2. 実行タイミング: この監視を「レコードを追加するたび」に行うとパフォーマンスが激減します。監視は「起動時の1回だけ」あるいは「管理者のみが実行できるボタン」に紐付けるのがプロの作法です。
—
まとめ:君はもう「ただのユーザー」ではない
テーブル構造をVBAで制御できるようになった瞬間、あなたはAccessを「単なるデータベース」ではなく、「自律的に状況を監視するシステム」へと進化させたことになります。
- TableDefを理解する。
- 状態(Fingerprint)を保存・比較する。
- 自動通知でガバナンスを効かせる。
この3ステップをマスターすれば、Access VBAの基本は完璧です。あとは、あなたの現場に合わせて、この「番犬」を鍛え上げていってください。
もし詰まったら、いつでも戻ってきてください。私たちは常に、より堅牢で美しいコードを探求し続ける仲間ですから。健闘を祈ります!
