【入門編】【中級】リレーションシップの「参照整合性」をVBAで一時解除・再設定し、大量データ投入を高速化する – Access VBA解析バイブル

スポンサーリンク

こんにちは!Access VBAの世界へようこそ。
日々、膨大なデータと格闘していると、「なんだか最近、データのインポートや一括更新の処理がやたらと遅いな……」と感じる瞬間はありませんか?

数万件、数十万件ものレコードをガッツリ取り込もうとしたとき、Accessが急にフリーズしたかのように遅くなる。この原因の多くは、テーブル同士を結ぶ「リレーションシップの参照整合性」にあります。

今回は、この参照整合性をVBAの力で一時的にスパッと解除し、爆速でデータを流し込んだあとに、何食わぬ顔で元通りに再設定するという、プロの現場では常識のパフォーマンスチューニング術を伝授します。

ここをクリアすれば、Access VBAの基本はバッチリですよ!さあ、一緒にワンランク上のエンジニアへステップアップしましょう。

—

1. なぜ「参照整合性」があるとインポートが遅くなるのか?

まず、敵を知ることから始めましょう。
リレーションシップを設定するとき、「参照整合性を強制する」にチェックを入れていますよね。これは、親子関係にあるテーブル間で「親がいない子データは登録させない!」という、データの綺麗さを保つための素晴らしい機能です。

しかし、「大量データを一気にインポートする瞬間」において、この正義感が仇(あアダ)になります。

Accessは、データを1件追加するたびに、裏側でこう叫んでいます。
> 「おい!今追加したこの子データ、本当に親データが実在するか、毎回テーブルの最初から最後まで確認したからな!!よし、じゃあ次の1件!」

これを数万回繰り返すわけですから、遅くなって当然です。エンジンをフル回転させながら、毎回ブレーキを踏みながら走っているような状態ですね。

解決策:マラソン中はブレーキを外す!

発想を転換しましょう。
データを一気に放り込む間だけは参照整合性のチェック(ブレーキ)を外し、インポートが終わった瞬間に再びチェックを入れ直せばいいのです。この手順をVBAで完全に自動化します。

—

2. 実装の全体像(ロジックの設計図)

VBAを書く前に、頭の中で処理の流れを整理しておきましょう。プログラミングで最も重要なのは「手順の組み立て」です。

1. 既存のリレーションシップを一旦削除する(参照整合性の解除)
2. 高速でデータのインポート(または追加処理)を行う
3. リレーションシップを再構築する(参照整合性の復活)

これをVBAのコードに翻訳していきます。

—

3. 実践!コピペで使える高速化VBAコード

それでは、実際のコードを見てみましょう。
今回は例として、親テーブルである `T_顧客` と、子テーブルである `T_受注` の間を結ぶリレーションシップを操作するシナリオを想定します。

開発環境の標準モジュールなどに、以下のコードを貼り付けてみてください。

Option Compare Database
Option Explicit

‘ ==============================================================================
‘ 処理名 : FastImportWithRelationControl
‘ 概要 : 参照整合性を一時解除して大量データ処理を高速化するサンプルプロシージャ
‘ ==============================================================================
Public Sub FastImportWithRelationControl()

Dim db As DAO.Database
Dim rel As DAO.Relation
Dim relName As String
Dim isRelExists As Boolean

‘ 対象となるリレーション名、テーブル名、フィールド名を設定
relName = “顧客_受注” ‘ ご自身の環境のリレーション名に変更してください

Set db = CurrentDb()
isRelExists = False

On Error GoTo ErrorHandler

‘ ————————————————————————–
‘ ステップ1:既存のリレーションシップの存在確認と削除(一時解除)
‘ ————————————————————————–
For Each rel In db.Relations
If rel.Name = relName Then
isRelExists = True
Exit For
End If
Next rel

If isRelExists Then
‘ リレーションが存在する場合は削除(これで整合性チェックの呪縛から解放されます)
db.Relations.Delete relName
Debug.Print “【情報】参照整合性を一時解除しました。”
End If

‘ ————————————————————————–
‘ ステップ2:大量データのインポートや追加処理(ここに重い処理を書く)
‘ ————————————————————————–
Debug.Print “【情報】大量データの処理を開始します…”

‘ 【例】ここにINSERT文やDoCmd.TransferTextなどを記述します
‘ 今回はダミーとしてメッセージを表示します
MsgBox “ここで大量データのインポート処理を実行します。” & vbCrLf & _
“(現在は参照整合性がオフなので爆速です!)”, vbInformation, “処理中”

‘ ————————————————————————–
‘ ステップ3:リレーションシップの再構築(参照整合性の復活)
‘ ————————————————————————–
If isRelExists Then
‘ 新たにRelationオブジェクトを作成
Set rel = db.CreateRelation(relName, “T_顧客”, “T_受注”, dbRelationUpdateCascade)

‘ 結びつけるフィールドを追加
‘ 引数:(ローカル側のフィールド名, 外部側のフィールド名)
rel.Fields.Append rel.CreateField(“顧客ID”)
rel.Fields!LocalField = “顧客ID”
rel.Fields!ForeignField = “顧客ID”

‘ 参照整合性の強制(Attributesに dbRelationDeleteCascade や dbEnforceIntegrity を設定)
‘ ※参照整合性を有効にするには dbEnforceIntegrity を指定します
rel.Attributes = dbEnforceIntegrity

‘ データベースにリレーションを登録
db.Relations.Append rel
Debug.Print “【情報】参照整合性を再設定しました。”
End If

MsgBox “すべての処理が爆速で完了しました!”, vbInformation, “完了”
Exit Sub

ErrorHandler:
‘ ————————————————————————–
‘ エラー処理:データに矛盾がある場合などの対策
‘ ————————————————————————–
MsgBox “エラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“内容: ” & Err.Description, vbCritical, “致命的エラー”

‘ ※実務では、エラー時にリレーションが消えたままにならないよう、
‘ ここでロールバックやリレーションの強制復旧処理を入れるのがプロの技です。

End Sub

—

4. コードの重要なポイントを優しく解説

初心者のあなたに向けて、このコードのキモとなる部分をいくつかピックアップして解説しますね。

① `CurrentDb()` と `DAO.Database`

Access VBAでテーブル構造やリレーションシップをプログラムからいじる場合、ADOではなくDAO(Data Access Objects)という古くからあるエンジンを使います。`CurrentDb()` は「今開いているデータベースの設計図そのもの」を取得する魔法の関数です。

② リレーション名の特定

Accessの画面上(データベースツール > リレーションシップ)で、線の上にマウスカーソルを合わせるとリレーション名が表示されます。コード内の `relName = “顧客_受注”` の部分は、ご自身の環境の名前と一致させておく必要があります。ここが一致していないと、VBA迷子になってエラーを起こすので注意してくださいね。

③ `dbEnforceIntegrity` の魔法

ステップ3のコードで、リレーションを再登録する際に `rel.Attributes = dbEnforceIntegrity` という記述があります。これがまさに「もう一度、参照整合性のルールを厳しく監視してください!」という命令になります。

—

5. 陥りやすい罠(エラー)と現場の知見

このテクニックを使うにあたって、絶対に知っておかなければならない「最大の罠」があります。

⚠️ 再設定時にエラーが出る理由

インポートしたデータの中に、「親がいないのに勝手に入り込んでしまった子データ(孤児レコード)」が紛れ込んでいる場合、ステップ3の「リレーションシップの再構築(`db.Relations.Append rel`)」の瞬間に、次のようなエラーで怒られます。

> 「参照整合性が要件を満たしていないため、リレーションシップを作成または変更できません。」

【チーフアーキテクトからのアドバイス】

  • インポートする前のデータクレンジング(不整合データの排除)を徹底すること。
  • もしデータに不備がある可能性があるなら、インポート後にいきなりリレーションを張るのではなく、一度クエリを使って「親がいない子データ」をあらかじめ検出して削除・修正するフェーズをVBAのプログラム内に挟むのが、プロフェッショナルな設計というものです。

—

まとめ

いかがでしたか?
今回は、リレーションシップの参照整合性をVBAで一時解除し、大量データ処理を爆速化するテクニックをご紹介しました。

  • なぜ遅いのか? ➡ 1件ごとに整合性チェックのブレーキを踏んでいるから。
  • どう解決する? ➡ VBAでリレーションを一時削除して、処理後に復元する。
  • 注意点は? ➡ 復元する時にデータが矛盾しているとエラーになるので、データの綺麗さに気を配る。

このテクニックを手に入れたあなたなら、重いデータ処理に怯える必要はもうありません。ぜひ実際の業務システムやツール開発に取り入れて、周囲を驚かせてみてくださいね。

それでは、また次の知見でお会いしましょう。バッチリ使いこなしてください!

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