【入門編】【中級】リレーションシップの整合性チェックとエラーハンドリング – Access VBA解析バイブル

スポンサーリンク

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の初級者ではありません。より複雑なテーブル操作や、トランザクション処理の世界が見えてくるはずです。

応援しています。困ったときは、またいつでも聞きに来てくださいね。

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