Accessの「定型入力」をVBAで掌握せよ:データ品質を劇的に向上させるメタプログラミング手法
現場のAccess運用で最も頭を抱えるのが「入力のゆらぎ」だ。電話番号がハイフンあり・なしで混在し、郵便番号のフォーマットがバラバラなDB。これらをUIの入力規則だけで制御しようとするのは、泥舟をバケツで汲み出すようなものだ。
真の業務自動化エンジニアは、UIに頼らない。「テーブル定義(TableDef)」を直接VBAで書き換えることで、データベースの基盤レベルから強制的に入力を標準化する。
本稿では、全テーブルの指定フィールドに対し、定型入力(InputMask)を一括適用する「プロダクション級のVBAコード」を授ける。
—
1. なぜ「手動設定」ではいけないのか
多くの開発者は、AccessのGUIを開き、一つずつテーブルの「定型入力」を設定する。しかし、これは以下の理由から「悪手」である。
- スケーラビリティの欠如: テーブル数が100を超えた際、手動でミスなく設定し続けることは不可能だ。
- 保守性の欠如: 運用途中でフォーマットの変更(例:郵便番号の桁数変更など)が発生した際、全てやり直す必要がある。
- 属人化: 「誰がいつ設定したか」がブラックボックス化し、ドキュメントの更新漏れが頻発する。
「コードが定義を管理する」。この原則を徹底すれば、大規模な改修も数行のロジック修正で完了する。
—
2. 実装の要諦:DAOの操作とエラーハンドリング
DAO(Data Access Objects)を用いて`TableDef`を操作する際、最も重要なのは「排他制御」と「プロパティの有無」の確認だ。定型入力プロパティ(InputMask)は、新規作成時には存在しない場合があるため、生成ロジックを組み込む必要がある。
プロダクションコード:ApplyInputMaskAllTables
このコードは、指定したフィールド名を持つすべてのテーブルに対し、指定したマスクを一括適用する。
Option Compare Database
Option Explicit
‘ ==============================================================================
‘ 目的: 指定したフィールド名の「定型入力」を一括更新する
‘ 引数: targetFieldName – 対象のフィールド名
‘ maskString – 設定する定型入力マスク文字列
‘ ==============================================================================
Public Sub ApplyInputMaskToAllTables(targetFieldName As String, maskString As String)
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim fld As DAO.Field
Dim prp As DAO.Property
Set db = CurrentDb
‘ システムテーブルを除外してループ
For Each tdf In db.TableDefs
If Left(tdf.Name, 4) <> “MSys” Then
‘ フィールドが存在するか確認
If FieldExists(tdf, targetFieldName) Then
Set fld = tdf.Fields(targetFieldName)
‘ 定型入力プロパティの設定
On Error Resume Next
fld.Properties(“InputMask”) = maskString
‘ プロパティが未作成の場合は新規作成して追加
If Err.Number = 3270 Then
Set prp = fld.CreateProperty(“InputMask”, dbText, maskString)
fld.Properties.Append prp
End If
On Error GoTo 0
Debug.Print “更新完了: ” & tdf.Name & “.” & targetFieldName
End If
End If
Next tdf
Set db = Nothing
MsgBox “全テーブルの定型入力適用が完了しました。”, vbInformation
End Sub
‘ フィールドの存在判定補助関数
Private Function FieldExists(tdf As DAO.TableDef, fieldName As String) As Boolean
Dim fld As DAO.Field
On Error Resume Next
Set fld = tdf.Fields(fieldName)
FieldExists = (Err.Number = 0)
On Error GoTo 0
End Function
—
3. 現場で生き残るための「鉄則」
このスクリプトを安全に運用するための技術的注意点を共有する。
1. プロパティの存在判定: DAOの`Properties`コレクションは、値が設定されていないとそもそも存在しないことがある。`Err.Number = 3270`(プロパティが見つかりません)を捕捉して動的に作成するアプローチが、唯一の「堅牢な」解法だ。
2. バックアップの必須化: テーブル定義を直接書き換える操作は、不可逆な変更を伴う。必ず実行前にバックアップを取り、トランザクションの概念を意識せよ。
3. システムテーブルの除外: `MSys`で始まるシステムテーブルを操作対象に含めてはならない。Accessの挙動が不安定になり、最悪の場合はファイル破損を招く。必ずフィルタリングを行うこと。
—
4. 総括:システムを「育てて」いくために
この手法を導入する最大のメリットは、「DB構造をコードで宣言的に記述できるようになった」という点だ。
例えば、新しい要件で「電話番号のマスクを少し変えたい」と言われた場合、GUIでポチポチ作業をする必要はない。メインルーチンの引数を書き換えて実行するだけで、全テーブルの定義が数秒で同期される。
エンジニアリングとは、単に動くものを作ることではない。「変更に対するコストを極限まで低減できるアーキテクチャ」を構築することだ。この一括設定スクリプトは、あなたのAccess開発を、属人的な作業から解放する強力な武器となるはずだ。
次は、これを「データ型」や「必須入力設定」にまで拡張してみるといい。Access VBAの可能性は、あなたが想像しているよりもずっと深い場所にある。
