【入門編】DAOのプロパティ操作によるインデックスの動的制御 – Access VBA解析バイブル

スポンサーリンク

こんにちは!Access VBAの世界へようこそ。
マクロの記録から一歩踏み出し、「自分の手でシステムをコントロールしたい」と熱意を持っているあなたへ、今日はとびきりエキサイティングな技術をお伝えします。

皆さんは、何万件、何十万件という大量のデータをAccessのテーブルにインポートしたり、一括追加したりしたとき、「なんだか急に処理が遅くなったな……」と感じたことはありませんか?

実はそれ、テーブルに設定された「インデックス(索引)」が原因なんです。

今回は、DAO(Data Access Objects)というAccessの心臓部であるエンジンを使い、「データをガッツリ入れるときはインデックスを一時的に消し、入れ終わったら瞬時に作り直す」という、プロの現場で使われる超高速化テクニックを伝授します。
ここをクリアすれば、あなたのAccess VBAのスキルは確実にワンランク上のステージに到達しますよ。さあ、一緒に扉を開けましょう!

—

1. なぜ「インデックスの動的制御」が必要なのか?

図解:インデックスの「裏側の仕事」を知る

インデックスは、辞書の「索引」のようなものです。これがあるおかげで、レコードの検索が一瞬で終わります。しかし、データを入れる側の視点に立つと、話は別です。

[通常時(インデックスあり)]
データ追加 ──> 「どこに挿入すべきか?」 ──> 索引を書き換える ──> データ保存
※データ1件追加するたびに、この重い整理作業が発生!

[高速化時(インデックスなし)]
データ追加 ──> とにかく末尾にドカンと追加! ──> (整理ナシで爆速)

大量のデータを追加するとき、Accessは「データを1件追加するたびに、インデックスの順番が狂っていないか」を律儀にチェックし、並び替えを行っています。これがパフォーマンス低下の元凶です。

であれば、「データを入れる前はインデックスを剥ぎ取り、丸裸の状態で最速でデータを流し込み、終わったら再びインデックスをバシッと構築し直す」。このアプローチが、大量データ処理の最適解となります。

—

2. DAOとは何か? なぜDAOを使うのか?

Access VBAでデータベースを操作する技術には、大きく分けてDAOとADOの2つがあります。

  • DAO (Data Access Objects): Access(Jet/ACEエンジン)の生まれ故郷であり、最も親和性が高い。テーブルの構造変更やインデックスの操作など、Accessの「設計図」に触れる処理はDAOの得意分野。
  • ADO (ActiveX Data Objects): SQL Serverなどの外部データベースと接続したり、汎用的なデータ操作を行ったりするのに長けたモダンな仕組み。

今回は「インデックスというテーブルの構造そのものをプログラムからいじる」ため、DAO一択となります。

—

3. 実践!インデックスを動的に削除・作成するVBAコード

それでは、実際のコードを見ていきましょう。
今回は `T_売上明細` というテーブルの `商品コード` フィールドに対して設定されているインデックス(例:`IX_ShohinCode`)を対象に、削除と再作成を行うプロシージャを作成します。

ご自身の開発環境ですぐに試せるよう、丁寧なコメントをつけています。

Sub OptimizeIndexForBulkInsert()
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim idx As DAO.Index
Dim idxNew As DAO.Index

‘ エラーハンドリングの準備
On Error GoTo ErrorHandler

‘ 1. 現在のデータベース(Accessファイル)への参照を取得
Set db = CurrentDb

‘ 2. 対象のテーブル定義を取得
Set tdf = db.TableDefs(“T_売上明細”)

‘ —————————————————————–
‘ ステップ1:インデックスの削除(存在する場合のみ)
‘ —————————————————————–
On Error Resume Next
‘ 削除しようとするインデックスが存在しない場合のエラーを防ぐため一時的に無効化
tdf.Indexes.Delete “IX_ShohinCode”
On Error GoTo ErrorHandler ‘ エラー監視を復帰

Debug.Print “インデックスを正常に削除しました。”

‘ —————————————————————–
‘ ステップ2:ここに大量データ追加の処理が入る(イメージ)
‘ —————————————————————–
‘ 例: db.Execute “INSERT INTO T_売上明細 … “, dbFailOnError
Debug.Print “— 大量データのインポート処理中(爆速!) —”

‘ —————————————————————–
‘ ステップ3:インデックスの再作成
‘ —————————————————————–
‘ 新しいIndexオブジェクトを作成
Set idxNew = tdf.Createindex(“IX_ShohinCode”)

‘ インデックスに含めるフィールドを指定(ここでは 商品コード)
Dim fld As DAO.Field
Set fld = idxNew.CreateField(“商品コード”)
idxNew.Fields.Append fld

‘ 必要に応じてプロパティを設定(例:重複を許可する場合は False、ユニークなら True)
idxNew.Unique = False

‘ テーブルの Indexes コレクションに追加してインデックスを確定させる
tdf.Indexes.Append idxNew

Debug.Print “インデックスを正常に再作成しました。”

‘ 終了処理
MsgBox “大量データの投入とインデックスの最適化が完了しました!”, vbInformation
Exit Sub

ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical

‘ 念のためオブジェクトを解放
Set idxNew = Nothing
Set tdf = Nothing
Set db = Nothing
End Sub

—

4. コードの重要ポイントと「初心者がハマりやすい罠」

先輩エンジニアとして、このコードのキモと、現場でよくある失敗をいくつかシェアしておきますね。

① `TableDefs` と `Indexes` の関係を理解する

DAOでは、テーブルの本体は `Recordset` ですが、テーブルの「設計図(列やインデックス)」は `TableDef` というオブジェクトが握っています。インデックスを操作するには、必ず `TableDef` を経由しなければならない、というルールを覚えておきましょう。

② フィールドの追加忘れに注意!

インデックスを作る際、`Createindex(“インデックス名”)` だけでは不十分です。「どのフィールドを対象にするか」を `CreateField` で作成し、それをインデックスの `Fields` コレクションに追加 (`Append`) するという「二段階の手間」が必要です。ここを忘れて実行すると、「フィールドが指定されていません」というエラーに直面します。

③ 排他制御(他のユーザーが使っていないか)

テーブルの構造を変更する(インデックスの削除・追加)には、対象のテーブルが他のユーザーや他の画面で開かれていない状態(排他ロックが取得できる状態)である必要があります。フォームでそのテーブルを開きっぱなしにしているとエラーになりますので注意してください。

—

まとめ

いかがでしたでしょうか?
今回はDAOのプロパティ操作によるインデックスの動的制御について解説しました。

  • 大量データ追加時はインデックスがボトルネックになる。
  • DAOの `TableDef` を使えば、VBAからインデックスの削除(`Delete`)と作成(`Append`)を自在にコントロールできる。
  • 処理の前後でインデックスをつけ外しすることで、圧倒的なパフォーマンス向上を手に入れられる。

ここをクリアできれば、単なる「マクロの延長」ではない、本物のデータベースエンジニアとしてのスキルが身についています。ぜひ、実際の業務データやテスト環境でその爆速ぶりを体感してみてください。

あなたのAccessライフが、よりスマートで快適なものになりますように。それではまた次の技術でお会いしましょう!

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