Access VBAを掌握せよ:FindFirstの「遅延」を消し去るインデックス戦略
こんにちは。現場で泥臭いトラブルをいくつも乗り越えてきた、一人のアーキテクトです。
Access VBAを使っていて、「`FindFirst`で検索をかけたら、レコードが増えるごとにアプリが重くなっていく…」と頭を抱えたことはありませんか?特にリンクテーブルを使っている場合、その「もっさり感」は致命的です。
今日は、DAOの`FindFirst`を魔法のように高速化する「インデックス活用術」を、技術の本質から解説します。これをマスターすれば、あなたのAccessアプリは劇的に軽快になります。
1. なぜ「Like演算子」を使うと検索が遅くなるのか?
まず、敵を知りましょう。`rs.FindFirst “Name Like ‘A*'”` と書いたとき、Accessの裏側で何が起きているかご存知ですか?
もし`Name`フィールドにインデックスが貼られていない場合、Accessは「テーブルの先頭から最後までのレコードを一つずつ開いて、名前がAから始まるかチェックする」という作業(フルテーブルスキャン)を行います。
データが1,000件なら平気ですが、10万件を超えた瞬間にアプリはフリーズしたかのように固まります。これが「重い」の正体です。
2. インデックスを「味方」にするための鉄則
インデックスは、辞書の「索引」と同じです。目的のデータがどこにあるか、あらかじめ地図を作っておく技術です。
鉄則:前方一致(A*)で検索せよ
インデックスが有効なのは、基本的に「前方一致」です。
- `”Name Like ‘A*'”` → 爆速(インデックスが効く)
- `”Name Like ‘*A*'”` → 激遅(インデックス無視!全件走査になる)
`*`(ワイルドカード)を先頭に持ってくると、インデックスは無力化します。「何で始まるか」を特定するのが、高速化の第一歩です。
3. 実践:FindFirst高速化コード例
では、実際に現場で使えるコードを見てみましょう。テーブルの特定のフィールドに対して効率的に検索を行うテンプレートです。
Public Sub FindRecordFast()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strCriteria As String
Set db = CurrentDb
' ダイナセットタイプで開くのが鉄則
Set rs = db.OpenRecordset("T_Customer", dbOpenDynaset)
' 検索条件:前方一致に絞ることでインデックスを有効活用
' ※Nameフィールドに必ずインデックスを貼っておくこと!
strCriteria = "CustomerName Like '株式会社*'"
rs.FindFirst strCriteria
' 検索結果の判定
If rs.NoMatch Then
MsgBox "該当する顧客は見つかりませんでした。", vbExclamation
Else
MsgBox "見つかりました: " & rs!CustomerName
End If
' 後処理(メモリ解放の作法)
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
このコードのポイント
1. dbOpenDynasetの活用: リンクテーブルを扱う場合、`Dynaset`として開くことで、Accessエンジンが最適化されたクエリをサーバー側(あるいはリンク先)に投げやすくなります。
2. NoMatchプロパティ: `FindFirst`の直後には必ず`NoMatch`を確認してください。これをサボると、見つからなかった場合にエラーが連鎖します。
3. インデックスの確認: 何よりもまず、テーブルデザインビューで対象フィールドの「インデックス」を「はい(重複なし)」または「はい(重複あり)」に設定してください。ここが全てです。
4. アーキテクトからのアドバイス:それでも遅いときは?
もしインデックスを貼っても遅いなら、それは「ネットワークの帯域」か「クエリの複雑さ」が原因です。
- リンクテーブルの罠: リンク先がネットワーク上の共有フォルダにある場合、そもそもレコードセットを全件読み込もうとするだけで遅延します。
- 解決策: `FindFirst`を使う前に、`rs.Filter`でサーバー側で絞り込みをかけるか、最初から検索結果だけを抽出した「パススルー・クエリ」や「SQLによる抽出」を検討してください。
まとめ:ここをクリアすれば、あなたはもう中級者
- Like演算子は「前方一致(A*)」で使うべし。
- 検索対象フィールドには必ずインデックスを貼るべし。
- コードの最後には必ず`rs.Close`と`Nothing`で後始末すべし。
Access VBAは、古い言語だと思われがちです。しかし、DAOやインデックスの仕組みを理解して書かれたコードは、驚くほどモダンで高速に動作します。
「動けばいい」から「速く、正しく動かす」へ。この一歩を踏み出せたあなたなら、どんな業務システムも自在に操れるはずです。ぜひ、現場のコードで試してみてください!
また次回、さらに深い「ADOとDAOの使い分け」の領域でお会いしましょう。
