【入門編】【中級】テーブル内の不要なインデックスをVBAで検出し、書き込み速度を改善するクリーンアップツール – Access VBA解析バイブル

スポンサーリンク

こんにちは!Access VBAの世界へようこそ。
マクロの記録ボタンを押して「動いたから良し!」とするステージから、一歩先へ進みたいあなたへ。今回は、プロの現場でも見落とされがちな「インデックスの闇と、テーブルの書き込み速度を極限まで引き上げるクリーンアップ手法」についてお話しします。

「ここをクリアすれば、Access VBAの基本はもちろん、データベースの構造を操る面白さがバッチリ分かりますよ!」
優しく、かつ本質的なエンジニアの視点でお伝えしますので、ぜひ最後までついてきてくださいね。

—

なぜ、あなたのAccessは「書き込み」が遅いのか?

Accessを使っていると、「レコードの追加や更新にやたら時間がかかる…」という壁にぶつかりませんか?
その原因の多くは、実は「不要なインデックス(索引)」にあります。

インデックスは、データの検索を爆速にする魔法の仕組みです。しかし、これには大きな代償があります。
テーブルに新しいデータを書き込む(INSERT/UPDATE)たびに、Accessはすべてのインデックスを裏側で一生懸命「更新」しなければならないのです。

つまり、使われていないインデックスがテーブルにびっしり生えていると、書き込みのたびにエンジンが重労働を強いられ、パフォーマンスがガタ落ちします。
今回は、VBAを使ってこの不要なインデックスを自動検出・削除し、テーブルをスリム化する「インデックス・スイーパー」を作ってみましょう。

—

基礎知識:TableDef と Indexes コレクション

VBAでテーブルの構造をいじるには、DAO(Data Access Objects)というエンジンを使います。
ここで登場する重要なオブジェクトが2つあります。

1. `TableDef` オブジェクト:テーブルの設計図そのもの。
2. `Indexes` コレクション:その設計図の中にぶら下がっている、インデックスたちの集まり。

イメージ図で表すと、こんな構造になっています。

Database (現在のDB)
└─ TableDefs (テーブルの設計図たち)
└─ TableDef (“T_売上データ” など)
└─ Indexes (インデックスたち)
├─ Index (“PrimaryKeyCode” -> プライマリキーは消しちゃダメ!)
├─ Index (“CustomerID” -> 検索に使うから残す)
└─ Index (“Temp_12345” -> ★過去のテストで作った不要な奴!)

この「Indexesコレクション」をVBAで1つずつペロリと舐める(走査する)ことで、不要なものを見つけ出して削除していくわけです。

—

実装コード:不要インデックス検出&クリーンアップツール

それでは、開発環境(VBAエディタ)を開いて、以下のコードを標準モジュールに貼り付けてみてください。
実務でそのまま使えるよう、プライマリキー(主キー)や外部キーをうっかり消してしまわないための安全装置もしっかり組み込んでいます。

Option Explicit

‘ ====================================================================
‘ 処理名 : CleanUpUnusedIndexes
‘ 概要 : 指定したテーブルのIndexesを走査し、不要なインデックスを削除する
‘ ====================================================================
Public Sub CleanUpUnusedIndexes()
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim idx As DAO.Index
Dim targetTableName As String
Dim deletedCount As Long

‘ 対象とするテーブル名を指定(実際のテーブル名に書き換えてください)
targetTableName = “T_売上データ”

Set db = CurrentDb
deletedCount = 0

On Error GoTo ErrorHandler

‘ テーブル定義(設計図)を取得
Set tdf = db.TableDefs(targetTableName)

MsgBox “【開始】テーブル「” & targetTableName & “」のインデックスをスキャンします。”, vbInformation
番
‘ Indexesコレクションをループ(裏側から安全に削除するために逆順で回すテクニックもありますが、今回はシンプルに)
For Each idx In tdf.Indexes

‘ —————————————————————-
‘ 【重要】消してはいけないインデックスの条件
‘ 1. Primary 属性(主キー)
‘ 2. Foreign 属性(リレーションシップの外部キー)
‘ 3. システムが自動作成したもの(Nameが “PrimaryKey” など)
‘ —————————————————————-
If idx.Primary = True Then
Debug.Print “スキップ(主キー): ” & idx.Name
ElseIf (idx.Attributes & dbUnique) = dbUnique And idx.Required = True Then
‘ ※厳密な外部キー判定は複雑になるため、今回は「主キー以外で絶対に消したくないもの」を弾くロジックの例
Debug.Print “スキップ(ユニーク制約など): ” & idx.Name
Else
‘ ここに引っかかったものは「不要(または一時的)」とみなして削除対象に!
Debug.Print “【削除対象】” & idx.Name

‘ インデックスを削除
tdf.Indexes.Delete idx.Name
deletedCount = deletedCount + 1
End If

Next idx

MsgBox “クリーンアップ完了! ” & deletedCount & ” 件の不要なインデックスを削除しました。”, vbInformation

CleanUp_Exit:
Set idx = Nothing
Set tdf = Nothing
Set db = Nothing
Exit Sub

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

—

コードのポイントと、陥りやすい罠(エラー対策)

このコードには、ベテランエンジニアならではの「知見」がいくつか詰まっています。初学者がハマりがちなポイントを解説します。

1. コレクションをループするときの「罠」

プログラミング初学者がやりがちなのが、`For Each` でループしながら、その場で `Delete` メソッドを呼ぶミスです。
今回はAccessのDAOが比較的よしなに処理してくれますが、場合によってはコレクションのインデックスが狂ってエラー(実行時エラー 3265など)になることがあります。
実務でより安全に書きたい場合は、コレクションを後ろから前へ(`For i = tdf.Indexes.Count – 1 To 0 Step -1`)回すのが、オブジェクト指向における鉄則です。今回は分かりやすさ重視で `For Each` にしていますが、安全装置(後述のバックアップ)を必ずセットで行いましょう。

2. 「主キー」と「外部キー」を絶対に消さない防壁

コード内の `If idx.Primary = True Then` が命綱です。
ここを書き間違えて主キーを消してしまうと、テーブルのデータ構造が崩壊し、リレーションシップがエラーを起こします。「消していいもの・いけないもの」の判定条件をビジネスロジックに合わせて厳しく設定するのが、プロの仕事です。

3. 最強の安全装置:「実行前のバックアップ」

データベースの構造をVBAで書き換えるコードを実行する前には、必ずファイルのバックアップ(コピペ保存)をとる癖をつけてください。「やっちゃった!」の瞬間に戻れる保険が、エンジニアの心を救います。

—

さらにパフォーマンスを極限まで高めるトドメの一手

不要なインデックスを掃除したら、最後に必ずセットで行ってほしい作業があります。それが「データベースの最適化(Compact and Repair)」です。

Accessは、データを削除したりインデックスを消したりしても、ファイル自体のサイズ(領域)は縮みません。内部に「隙間」が空いている状態です。
VBAからこれを実行するには、以下の1行を使います。

‘ ※現在のデータベースを最適化して物理的なサイズと断片化を解消する
DBEngine.CompactDatabase CurrentDb.Name, CurrentDb.Name & “_bk.accdb”

(※実際には一時ファイルを使った置換処理が必要になりますが、UIの「データベースの最適化」ボタンをポチッと押すだけでも十分効果的です!)

—

まとめ

今回は、`TableDef` と `Indexes` コレクションを操り、不要なインデックスを駆逐して書き込み速度を改善するクリーンアップツールを解説しました。

  • 不要なインデックスは書き込み(INSERT/UPDATE)のスピードを殺す
  • `TableDef` を使えば、テーブルの設計図をVBAから自由にいじれる
  • 主キーなどの重要資産を守るガードロジックを必ず入れる

ここをクリアできれば、あなたはもう単なる「Accessのマクロ利用者」ではありません。データベースの構造を意のままに最適化できる「熟練のAccessエンジニア」の仲間入りです。

ぜひ、ご自身の開発環境で試してみてくださいね。あなたのAccessが爆速に生まれ変わる瞬間を、ぜひ楽しんでください!

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