こんにちは!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でリレーションを一時削除して、処理後に復元する。
- 注意点は? ➡ 復元する時にデータが矛盾しているとエラーになるので、データの綺麗さに気を配る。
このテクニックを手に入れたあなたなら、重いデータ処理に怯える必要はもうありません。ぜひ実際の業務システムやツール開発に取り入れて、周囲を驚かせてみてくださいね。
それでは、また次の知見でお会いしましょう。バッチリ使いこなしてください!
