こんにちは!日々のAccess開発、お疲れ様です。
マクロの記録から一歩踏み出し、「自分でコードを書けるようになりたい!」という熱意を持ってこのページにたどり着いたあなたへ。今回は、プロの現場でも不可欠な「テーブル定義のユニットテスト」という、ワンランク上の技術を一緒に学んでいきましょう。
「プログラムのテストって、画面の動きや計算結果を確認するものじゃないの?」
そう思った方、素晴らしい着眼点です。しかし、プロの世界では「データを保存する入れ物(テーブル)そのものが壊れていないか、仕様通りに作られているか」も、プログラムで自動的にチェックします。
ここをクリアすれば、あなたも単なる「Access使い」から「システム建築のプロ」への仲間入りです。優しく、そして本質的なところまでしっかり解説していくので、安心してついてきてくださいね!
—
1. なぜ「テーブル定義のユニットテスト」が必要なのか?
皆さんは、こんな経験はありませんか?
- 「あれ?このフィールド、前は『数値型』だったはずなのに、いつの間にか『短いテキスト』に変わってる!?」
- 「誰かが勝手にリレーションシップの設定を消しちゃって、データがボロボロになった……」
Accessは非常に手軽に作れる反面、誰でも簡単にテーブルの構造(設計)を変更できてしまいます。これが原因で、後から動かしたVBAプログラムがエラーを起こす「魔のバブル」がよく発生するのです。
そこで登場するのが、「VBAを使った自動テスト(ユニットテスト)」です。
「このテーブルには、この名前のフィールドがあって、データ型はこれであるべきだ」というルールをVBAで記述し、一瞬でチェックする仕組みを作ります。これにより、手動での確認ミスをゼロにできるというわけです。
—
2. Access VBAにおける「TableDef」の基礎知識
テーブルの構造をVBAでいじる・調べるためには、DAO(Data Access Objects)という仕組みの`TableDef`(テーブル定義)オブジェクトを使います。
イメージ図で構造を見てみましょう。
[CurrentDb (現在のデータベース)]
└── TableDefs (すべてのテーブルの集まり)
├── “T_顧客マスタ” [TableDefオブジェクト]
│ ├── Fields (フィールドの集まり)
│ │ ├── “顧客ID” [Fieldオブジェクト (数値型)]
│ │ └── “顧客名” [Fieldオブジェクト (テキスト型)]
│ └── Attributes (属性)
└── “T_受注明細” [TableDefオブジェクト]
VBAを使うと、このツリー構造のなかに「狙ったテーブルがあるか」「フィールドのデータ型は正しいか」をプログラムから直接覗き見ることができます。
—
3. 実践!テーブル定義を自動テストするVBAコード
それでは、実際に動くコードを見てみましょう。
今回は例として、「T_顧客マスタ」というテーブルが存在し、その中に「顧客ID(数値型)」と「顧客名(テキスト型)」が正しく存在するかをテストするコードを書きます。
以下のコードを、Accessの標準モジュールにそのまま貼り付けてみてください。
Option Compare Database
Option Explicit
‘ =================================================================
‘ @Title: テーブル定義ユニットテスト
‘ @Description: 指定したテーブルの存在と、必須フィールド・データ型を検証する
‘ =================================================================
Public Sub RunTableDefinitionTest()
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim fld As DAO.Field
Dim testPassed As Boolean
Set db = CurrentDb
testPassed = True ‘ テスト結果の初期値(合格仮定)
On Error GoTo ErrorHandler
Debug.Print “=== テーブル定義テスト開始 ===”
‘ —————————————————————-
‘ テスト1: 「T_顧客マスタ」テーブルが存在するか?
‘ —————————————————————-
If Not TableExists(db, “T_顧客マスタ”) Then
Debug.Print “❌ [FAIL] テーブル ‘T_顧客マスタ’ が存在しません。”
testPassed = False
GoTo TestEnd
Else
Debug.Print “✔ [PASS] テーブル ‘T_顧客マスタ’ は存在します。”
End If
‘ テーブル定義を取得
Set tdf = db.TableDefs(“T_顧客マスタ”)
‘ —————————————————————-
‘ テスト2: 「顧客ID」フィールドが存在し、かつ長整数型(dbLong)か?
‘ —————————————————————-
If Not FieldExists(tdf, “顧客ID”) Then
Debug.Print “❌ [FAIL] フィールド ‘顧客ID’ が存在しません。”
testPassed = False
Else
Set fld = tdf.Fields(“顧客ID”)
‘ dbLong は Accessの長整数型を指します
If fld.Type <> dbLong Then
Debug.Print “❌ [FAIL] ‘顧客ID’ のデータ型が不正です。(期待値: 長整数型)”
testPassed = False
Else
Debug.Print “✔ [PASS] ‘顧客ID’ の存在とデータ型は正常です。”
End If
End If
‘ —————————————————————-
‘ テスト3: 「顧客名」フィールドが存在し、かつテキスト型(dbText/dbChar系)か?
‘ —————————————————————-
If Not FieldExists(tdf, “顧客名”) Then
Debug.Print “❌ [FAIL] フィールド ‘顧客名’ が存在しません。”
testPassed = False
Else
Set fld = tdf.Fields(“顧客名”)
‘ dbText または dbMemo (短いテキスト/長いテキスト) かを判定
If fld.Type <> dbText And fld.Type <> dbMemo Then
Debug.Print “❌ [FAIL] ‘顧客名’ のデータ型がテキスト型ではありません。”
testPassed = False
Else
Debug.Print “✔ [PASS] ‘顧客名’ の存在とデータ型は正常です。”
End If
End If
TestEnd:
‘ —————————————————————-
‘ 総合結果の判定
‘ —————————————————————-
Debug.Print “================================”
If testPassed Then
MsgBox “すべてのテーブル定義テストが合格しました!🎉”, vbInformation, “テスト成功”
Else
MsgBox “テーブル定義に異常が見つかります。イミディエイトウィンドウを確認してください。”, vbCritical, “テスト失敗”
End If
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical
End Sub
‘ =================================================================
‘ 補助関数: 指定したテーブルが存在するかチェックする
‘ =================================================================
Private Function TableExists(db As DAO.Database, tableName As String) As Boolean
Dim tdf As DAO.TableDef
On Error Resume Next
Set tdf = db.TableDefs(tableName)
If Err.Number = 0 Then
TableExists = True
Else
TableExists = False
End If
On Error GoTo 0
End Function
‘ =================================================================
‘ 補助関数: 指定したフィールドが存在するかチェックする
‘ =================================================================
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)
If Err.Number = 0 Then
FieldExists = True
Else
FieldExists = False
End If
On Error GoTo 0
End Function
—
4. 初学者が陥りやすいエラーとハマりポイント
このコードを動かす時、あるいは自分で応用する時に、初心者が必ずと言っていいほど躓くポイントを先回りして解説しておきますね。
① `db.TableDefs` で存在しない名前を指定すると即死する
VBAでよくやりがちなのが、`db.TableDefs(“存在しないテーブル名”)` と直接書いてしまうことです。これを行うと、VBAは親切に教えてくれる暇もなく、「実行時エラー ‘3265’:アイテムが見つかりませんでした。」を起こしてプログラムが強制終了します。
これを防ぐために、上記のコードでは `TableExists` という補助関数の中で `On Error Resume Next` を使い、エラーを安全に捕捉して「False(存在しない)」を返すように工夫しています。ここがプロっぽいテクニックです!
② データ型の定数(`dbLong` や `dbText`)の罠
DAOにおけるフィールドの型は、見た目の名前(「数値型」「短いテキスト」など)とは異なり、内部では定数(数値)で管理されています。
- 長整数型 = `dbLong` (値は 4)
- 短いテキスト = `dbText` (値は 10)
- 日付/時刻型 = `dbDate` (値は 8)
「あれ?判定がうまく通らないな?」と思ったら、`Debug.Print fld.Type` をイミディエイトウィンドウに出力して、実際の型番号を確認してみましょう。
—
5. おわりに:ここをクリアすれば、もう怖くない!
お疲れ様でした!ここまで読み進められたあなたは、単に「動くコードをコピペする人」から、「システムの品質をコードで担保できるエンジニア」へと確実にステップアップしています。
今回紹介したテーブル定義のテストを応用すれば、「外部からインポートしたCSVのフォーマットが正しいか」をシステム起動時に自動チェックする堅牢なアプリケーションを作ることも可能です。
「たかがAccess、されどAccess」。その奥深い世界を、これからも一緒に楽しく極めていきましょう。ここをクリアできたら、あなたのVBAスキルはもうバッチリですよ!次のステップも、私と一緒に頑張りましょうね。
