共有環境の落とし穴:Access VBAで「QueryDef」を安全に使いこなす極意
こんにちは。Accessの迷宮を探索する皆さんに、今日は「マルチユーザー環境におけるクエリ定義(QueryDef)の競合」という、現場で必ずぶつかる壁を突破する秘策を授けましょう。
「クエリをVBAで書き換えて実行する」という手法は非常に強力です。しかし、複数人が同時にアクセスする共有データベースでこれを行うと、突然「他のユーザーが使用中です」という無慈悲なエラーに遭遇します。
なぜこんなことが起きるのか? どうすればスマートに解決できるのか? 伝説のエンジニアの視点で、その「解法」を伝授します。
—
1. なぜ「QueryDef」は競合するのか?
そもそも `QueryDef` とは、Accessの中に保存されたクエリの「設計図」そのものです。
VBAで `CurrentDb.QueryDefs(“クエリ名”).SQL = “…”` と書くと、Accessは即座にデータベースファイル内の定義を書き換えようとします。
ここで問題が発生します。
Aさんがクエリを書き換えている瞬間に、Bさんが同じクエリを開こうとすると、Accessは「設計図が今まさに書き換え中なので渡せません」とロックをかけてしまうのです。
いわば、「全員で同じホワイトボードに書き込んでいる状態」。これでは効率が悪すぎますよね。
—
2. 解決策:名前を「被らせない」戦略
この問題を解決する最もエレガントな手法は、「一時的にクエリを生成し、使い終わったら即座に消す」という戦略です。
固定の名前(例: `qry_DynamicFilter`)を使うのではなく、ユーザーごとのユニークなIDや、実行時のタイムスタンプを付与して「専用の作業用クエリ」をその場で作成するのです。
実践コード:安全な動的クエリ実行テンプレート
以下のコードは、既存のクエリを上書きせず、自分専用の「使い捨てクエリ」を生成して実行するプロフェッショナルな実装例です。
Public Sub ExecuteDynamicQuery(strSQL As String)
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim tempQueryName As String
‘ 1. 自分専用の一時クエリ名を生成(ユーザー名 + タイムスタンプで衝突を防ぐ)
tempQueryName = “tmp_” & Environ(“UserName”) & “_” & Format(Now, “hhmmss”)
Set db = CurrentDb
On Error GoTo Cleanup
‘ 2. 一時クエリを生成(CreateQueryDefの第1引数に名前を渡す)
Set qdf = db.CreateQueryDef(tempQueryName, strSQL)
‘ 3. ここでクエリを実行(例:フォームのレコードソースに指定するなど)
‘ Debug.Print “実行中: ” & tempQueryName
‘ — 本来はここでフォームのレコードソースを切り替える等を行う —
‘ Forms!YourForm.RecordSource = tempQueryName
Cleanup:
‘ 4. 処理が終わったら必ず削除(ここが重要!)
If Not qdf Is Nothing Then
db.QueryDefs.Delete tempQueryName
Set qdf = Nothing
End If
Set db = Nothing
If Err.Number <> 0 Then
MsgBox “エラーが発生しました: ” & Err.Description
End If
End Sub
—
3. このコードの「本質的なポイント」
初心者のうちは「動けばいい」と思いがちですが、プロは「後始末」に命をかけます。
- `Environ(“UserName”)` の活用: 誰が実行しているかを識別子にすることで、物理的に名前が被る確率を限りなくゼロにします。
- `On Error GoTo` によるクリーンアップ: もし途中で処理が失敗しても、必ず `Cleanup` ラベルを通るように設計しています。これがないと、失敗するたびにゴミのクエリがデータベース内に溜まり、容量を圧迫し、いずれシステム全体を重くします。
- オブジェクトの破棄: `Set … = Nothing` を忘れないこと。これはメモリの解放という、Accessのパフォーマンスを維持するための礼儀作法です。
—
4. 次のステップへ
この「一時クエリ生成」のパターンをマスターすれば、もうマルチユーザー環境でエラーに怯える必要はありません。
今回学んだのは、単なるVBAのコードではなく、「共有資源をどう制御するか」というシステム設計の基礎体力です。ここをクリアできたあなたは、もうマクロの記録を卒業した立派なAccess開発者です。
次は、パラメータークエリの安全な渡し方(`Parameters`コレクションの利用)に挑戦してみましょう。それについては、また別の機会に深く深く、掘り下げて解説しますね。
まずはこのコードを、あなたの開発環境で試してみてください。エラーのない、軽快なシステム作りを応援しています!
