Access VBAの「当たり前」を疑え:`CurrentDb`を使い捨ててはいけない理由
こんにちは。現場で叩き上げ、数多のAccessシステムを最適化してきたエンジニアです。
皆さんは、Access VBAを書くとき、何気なくこんな風に書いていませんか?
‘ よくある「非効率」な書き方
For i = 1 To 10000
CurrentDb.Execute “INSERT INTO T_Log (LogData) VALUES (‘データ’ & ” & i & “)”
Next i
一見、何の問題もなさそうに見えますよね。でも、これこそが「Accessの動作が重い」「処理が終わらない」という悲劇を生む元凶なのです。今日は、Access VBAの心臓部である`CurrentDb`の正しい付き合い方について、伝説的な知見を伝授しましょう。
—
なぜ `CurrentDb` を連呼してはいけないのか?
まず、`CurrentDb` というメソッドが何をしているかを知る必要があります。
`CurrentDb` は、「現在のデータベースへの接続情報を取得し、DAO.Databaseオブジェクトを新規生成して返す」という重い処理を行っています。
1. 生成コストの闇
`CurrentDb` を呼び出すたびに、Accessは裏で「データベースの現在の状態を調べ、接続し、オブジェクトをメモリ上に構築する」という一連の儀式を繰り返します。1回なら微々たるものですが、ループ処理の中で1万回呼び出せば、そのたびに1万回分の無駄なオーバーヘッドが発生するのです。
2. メモリの浪費と不安定化
使い終わったオブジェクトをその都度破棄(ガベージコレクション)する手間をAccessに強いることになります。これが繰り返されると、メモリの断片化を招き、最悪の場合、アプリケーション全体のレスポンス低下や「メモリ不足」エラーを引き起こす引き金になります。
—
【極意】DAO.Database変数を「キャッシュ」せよ
この問題を解決するのは非常にシンプルです。「最初に1回だけ呼び出し、それを変数に格納して使い回す」。これだけで、劇的な高速化と安定性が手に入ります。
改善されたコード例
Public Sub OptimizedInsert()
‘ DAO.Database型の変数を用意します(これがキャッシュの役割)
Dim db As DAO.Database
‘ 最初に1回だけCurrentDbを代入
Set db = CurrentDb
‘ これ以降、ループ内ではdb変数を使うだけ
Dim i As Long
For i = 1 To 10000
‘ db変数を使うと、オブジェクトの生成コストがかからない!
db.Execute “INSERT INTO T_Log (LogData) VALUES (‘データ” & i & “‘)”, dbFailOnError
Next i
‘ 最後に参照を解放(お行儀の良いエンジニアの嗜み)
Set db = Nothing
End Sub
この書き方に変えるだけで、処理速度は数倍から、場合によっては数十倍に跳ね上がります。
—
実践テクニック:モジュールレベルでの保持
さらに高度な設計として、フォームや標準モジュール全体でデータベース接続を使い回したい場合は、モジュールレベル変数として宣言するのがベストプラクティスです。
‘ モジュールの先頭に記述
Private m_db As DAO.Database
Private Property Get CurrentDB_Cached() As DAO.Database
‘ 初回呼び出し時のみセットする仕組み(遅延初期化)
If m_db Is Nothing Then
Set m_db = CurrentDb
End If
Set CurrentDB_Cached = m_db
End Property
‘ 使用例
Public Sub DoSomething()
‘ どこからでもこのプロパティを呼べば、常にキャッシュされたdbが返る
CurrentDB_Cached.Execute “DELETE FROM T_Temp”
End Sub
このように「必要になった瞬間に作成し、以降は使い回す」という設計こそが、プロのエンジニアの流儀です。
—
ここをクリアすれば、あなたはもう「脱・初心者」です
今回紹介した「オブジェクトの再利用」という概念は、VBAに限らず、あらゆるプログラミング言語における最適化の基本です。
- `CurrentDb` は「使い捨ての道具」ではなく「貴重な接続資源」である。
- ループの中では、なるべくオブジェクトを生成しない。
この2点だけ覚えて帰ってください。これさえ守れば、あなたの書くAccess VBAは、驚くほど軽快で、プロの現場でも通用する「強いコード」へと進化します。
Access VBAは、決して遅い言語ではありません。そのポテンシャルを引き出すか、台無しにするか。それはすべて、皆さんの「書き方」一つにかかっています。ぜひ、次回の開発から試してみてくださいね。応援しています!
