Access VBAの深淵へ:リレーションシップの「整合性エラー」を制御せよ
こんにちは。現場で泥臭いトラブルをいくつも乗り越えてきた、一人のエンジニアとしてお話しします。
Accessを使いこなす上で、「テーブル同士の絆」とも言えるリレーションシップは避けて通れません。しかし、いざVBAで自動的に構築しようとすると、容赦なく「実行時エラー」という壁が立ちはだかりますよね。
今回は、この「参照整合性」の設定で発生するエラーをスマートに捌き、ユーザーに優しく、かつシステムとして強靭なコードを書くための秘訣を伝授します。
—
1. なぜ「参照整合性」のエラーは起きるのか?
リレーションシップにおける参照整合性とは、簡単に言えば「親がいないのに子が生まれる(存在しないIDを参照する)ことを許さない」という強力なルールです。
VBAでこれを設定しようとするとき、以下のような状況で必ずエラーが飛んできます。
- データ不整合: 子テーブルに、親テーブルの主キーに存在しないデータが既に混入している。
- 型不一致: 結合するフィールドのデータ型が微妙に違う(例:長整数型と数値型)。
- 重複問題: 一対多の関係において、親側のフィールドに重複がある。
これらを「エラーが出たから止める」のではなく、「エラーを特定してユーザーに教えてあげる」のが、一流のエンジニアの流儀です。
—
2. リレーションシップ設定の「職人コード」
以下のコードは、エラーハンドリングを組み込み、何が原因で設定が失敗したかを判定する実践的な実装です。
Public Sub CreateRelationWithCare()
Dim db As DAO.Database
Dim rel As DAO.Relation
Dim fld As DAO.Field
Set db = CurrentDb
On Error GoTo ErrorHandler
‘ 既存のリレーションが存在する場合に備えて削除(必要に応じて)
‘ db.Relations.Delete “親-子リレーション”
‘ 新規リレーションの作成
Set rel = db.CreateRelation(“RelationName”, “ParentTable”, “ChildTable”)
rel.Attributes = dbRelationUpdateCascade + dbRelationDeleteCascade ‘ 削除/更新の連鎖を設定
‘ フィールドの紐付け
Set fld = rel.CreateField(“ParentKey”)
fld.ForeignName = “ChildKey”
rel.Fields.Append fld
‘ リレーションの追加実行
db.Relations.Append rel
MsgBox “リレーションの構築に成功しました!”, vbInformation
Exit Sub
ErrorHandler:
‘ エラー番号で分岐させるのがプロの技です
Select Case Err.Number
Case 3200, 3012
MsgBox “リレーションが既に存在するか、データが整合していません。” & vbCrLf & _
“子テーブルに『親に存在しないID』が含まれていないか確認してください。”, vbCritical
Case 3376
MsgBox “指定したテーブルが見つかりません。名前を再確認してください。”, vbExclamation
Case Else
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical
End Select
End Sub
—
3. コードのポイントを紐解く
① `rel.Attributes` の役割
ここには「整合性のルール」を詰め込みます。`dbRelationUpdateCascade` を指定することで、親のIDが変わったときに子も自動追従します。これを設定しないと、整合性の維持が非常に困難になります。
② `On Error GoTo` による防御壁
初学者が最も陥りやすいのは、エラーを無視してプログラムを止めてしまうこと。`Select Case Err.Number` を使うことで、「何が原因で失敗したか」を人間がわかる言葉に変換することができます。これがユーザーに愛されるシステムの条件です。
③ なぜ `CreateField` を使うのか
`rel.Fields.Append` は、リレーションシップの設計図を完成させる儀式です。親側の `ParentKey` と子側の `ForeignName` を明示的に結びつけることで、Accessに「どの線で繋ぐか」を正確に伝えています。
—
4. 現場からのアドバイス:チェックリスト
もし実装中にエラーが出たら、以下の順で確認してください。
1. データ型の確認: 親と子、フィールドの型は1ビットの狂いもなく一致していますか?(「数値型」と「長整数型」は別物とみなされることが多いです)
2. 孤立レコードの調査: クエリを作成し、「不一致クエリウィザード」で親のない子レコードがないか検索してください。
3. インデックスの有無: リレーションの親側フィールドには、主キーまたはユニークインデックスが設定されていますか?(ここがボトルネックになることが非常に多いです)
—
最後に:Access VBAは「対話」である
VBAを書くことは、単に処理を自動化することではありません。Accessというデータベースエンジンと「正しく対話する」ことです。
今回紹介したエラーハンドリングをマスターすれば、もう「謎の実行時エラー」に怯える必要はありません。一つ一つ丁寧に構造を整えれば、Accessは必ずあなたの最高のパートナーになります。
ここをクリアできれば、あなたはもうAccess VBAの初級者ではありません。より複雑なテーブル操作や、トランザクション処理の世界が見えてくるはずです。
応援しています。困ったときは、またいつでも聞きに来てくださいね。
