Access VBAを掌握せよ:QueryDefの「隠し属性」で実現する、堅牢な動的クエリ管理術
Accessでシステムを構築していると、必ず突き当たる壁がある。「動的なSQLをどう扱うか」だ。
初学者は`CurrentDb.Execute`に文字列を直書きし、中級者は`QueryDef`オブジェクトを使い始める。しかし、真のプロフェッショナルは、「QueryDefのライフサイクル」を制御し、システムを汚染させないことに心血を注ぐ。
今回は、ユーザーの目に触れさせず、かつ実行後に痕跡を残さない「隠し属性(Temporary QueryDef)」を活用した、セキュアで保守性の高いクエリ実行術を伝授する。
—
1. なぜ「直書きSQL」と「固定クエリ」は悪手なのか
多くの現場で、以下のようなコードが散見される。
- SQLの直書き: コンパイル時のチェックが効かず、保守性が皆無。
- 固定のQueryDef作成: 実行するたびに「クエリ」タブにゴミが溜まり、最終的に何が管理用かわからなくなる。
これらは、Accessのパフォーマンスとセキュリティを蝕む「負債」だ。
我々が目指すべきは、「必要な時に生成し、用が済んだら物理的に存在を抹消する」という、メモリと名前空間を汚さない設計である。
—
2. 隠し属性「Temporary QueryDef」の極意
`CurrentDb.CreateQueryDef` の第1引数に空文字列 `””` を渡す。これだけで、そのクエリは「名前のない、一時的なQueryDef」としてメモリ上に展開される。
- メリット:
- 名前空間の汚染ゼロ: クエリ一覧に表示されない。
- 排他制御の回避: 既存のクエリ名と衝突しない。
- 自動消滅: `Close` メソッドを呼ぶか、スコープを抜ければメモリから解放される。
—
3. 実装:堅牢な動的SQL実行エンジン
以下は、実務でそのまま利用できるプロダクションコードだ。エラーハンドリングとクリーンアップを徹底し、トランザクションとの親和性も考慮している。
‘ ————————————————————————-
‘ 目的:一時的なQueryDefを使用して、安全にパラメータクエリを実行する
‘ 引数:sql – SQL文字列, params – パラメータの辞書(Dictionary等で渡す想定)
‘ ————————————————————————-
Public Sub ExecuteTemporaryQuery(ByVal sql As String, Optional ByVal params As Object = Nothing)
Dim qdf As DAO.QueryDef
Dim key As Variant
‘ エラーハンドリングは必須
On Error GoTo ErrorHandler
‘ 1. 名前なし(””)でQueryDefを作成することで、一時的オブジェクトとして生成
Set qdf = CurrentDb.CreateQueryDef(“”, sql)
‘ 2. パラメータの注入(SQLインジェクション対策および型安全性の担保)
If Not params Is Nothing Then
For Each key In params.Keys
qdf.Parameters(key).Value = params(key)
Next
End If
‘ 3. 実行(レコードセットを返さない更新・削除クエリ用)
qdf.Execute dbFailOnError
‘ 4. クリーンアップ:即座にメモリを解放
qdf.Close
Set qdf = Nothing
Exit Sub
ErrorHandler:
‘ ログ出力やユーザー通知をここで行う
MsgBox “クエリ実行エラー: ” & Err.Description, vbCritical
If Not qdf Is Nothing Then qdf.Close
Set qdf = Nothing
End Sub
—
4. なぜこの設計が最強なのか
型安全性の確保
`qdf.Parameters` を使用することで、SQL文字列に直接値を埋め込む「文字列連結」を避けている。これにより、日付型や数値型のフォーマットエラーを回避し、意図しないSQLインジェクションのリスクを根絶できる。
パフォーマンスの最適化
`CreateQueryDef` で生成されたオブジェクトは、データベースエンジンによって最適化された実行プランがキャッシュされる可能性がある。同じ構造のSQLを何度も実行する場合、単なる `Execute` よりも効率的に動作するケースが多い。
保守性の最大化
管理用クエリが「クエリ一覧」を埋め尽くすことはない。システム管理者がデータベースを開いたとき、そこにあるのは「必要な永続クエリ」だけだ。これが、長期運用に耐えうるシステムの条件である。
—
5. チーフアーキテクトからの提言
君たちが書くコードは、単なる機能の羅列であってはならない。
「Accessがメモリをどう管理し、DAOがどのタイミングでロックを解放するか」を意識せよ。
今回紹介した「一時的QueryDef」は、大規模な基幹システムをAccessで構築する際の必須教養だ。クエリを無秩序に作成するのではなく、ライフサイクルを管理する。この意識を持つだけで、君たちが作るシステムの安定感は劇的に向上するはずだ。
次は、この「一時的QueryDef」を応用した、トランザクション制御と組み合わせた大規模データ更新のテクニックについて話そうか。
手を動かせ。そして、Accessを支配しろ。
