Access VBAを掌握する:動的クエリ生成による「見えないセキュリティ」の極意
こんにちは。システム開発の現場で、Accessと長く付き合ってきたエンジニアです。
皆さんは、Accessの「クエリ」画面に、管理用の複雑なクエリがズラリと並んでしまい、どれが本番用でどれがテスト用か分からなくなった経験はありませんか? あるいは、機密性の高いクエリをユーザーの目から隠したいと悩んだことはないでしょうか。
今日は、そんな悩みを一掃する「QueryDefの動的生成と即時破棄」という、プロフェッショナルな設計手法を伝授します。これを使えば、クエリは「保存するもの」から「必要な時に生まれ、役目を終えたら消えるもの」へと進化します。
—
なぜ「クエリを保存しない」のか?
通常、Accessのクエリは「クエリデザイン」で作成して保存します。しかし、これは以下のリスクを孕んでいます。
1. セキュリティリスク: ユーザーがクエリを直接開いて、SQLの中身を改ざんしたり、全データを閲覧できてしまう。
2. 保守性の低下: 開発が進むにつれ、管理用クエリが散乱し、どれを消していいか分からなくなる。
3. 環境の汚染: 本番環境に不要なオブジェクトを残すことは、予期せぬ不具合の温床となります。
これを解決するのが、「VBAでSQLを組み立て、メモリ上で実行し、終わったら消す」というアプローチです。
—
ステップ1:隠し属性を活用する「QueryDef」の基本
Access VBAにおいて、クエリを操作する最強のオブジェクトが `QueryDef` です。これを使うと、クエリの作成から実行までをコードで制御できます。
まず、最も重要なのは「作成したクエリをユーザーに見せない」という工夫です。実は、クエリ名に特定のルール(例:`~`で始めるなど)を使うか、あるいは「隠し属性」を付与することで、ナビゲーションウィンドウから姿を消すことができます。
今回は、もっとスマートに「一時的なクエリとして作成し、即座に破棄する」方法を見ていきましょう。
—
ステップ2:実戦的なVBAコード
以下のコードは、指定したユーザーIDに応じたデータを動的に取得し、処理完了後にそのクエリを削除するテンプレートです。
Public Sub ExecuteTemporaryQuery(ByVal userID As String)
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim strSQL As String
Dim queryName As String
Set db = CurrentDb
queryName = “tmp_SecureQuery_” & Format(Now, “hhmmss”) ‘ 一意の名前を生成
‘ 1. SQL文字列を組み立てる(パラメーター化して注入を防ぐ)
strSQL = “SELECT FROM T_SensitiveData WHERE OwnerID = ‘” & userID & “‘;”
‘ 2. 一時クエリを定義して作成
Set qdf = db.CreateQueryDef(queryName, strSQL)
‘ 3. 実行(DAOを使って効率的に)
‘ ここで例えばRecordsetを開いて処理を行う
Dim rs As DAO.Recordset
Set rs = qdf.OpenRecordset
‘ — ここで必要なデータ処理を行う —
Debug.Print “データ取得成功: ” & rs.RecordCount & ” 件”
‘ ———————————–
‘ 4. 後始末(クエリを削除して痕跡を残さない)
rs.Close
db.QueryDefs.Delete queryName
‘ オブジェクトの解放
Set rs = Nothing
Set qdf = Nothing
Set db = Nothing
MsgBox “処理が完了しました。一時クエリは破棄されました。”, vbInformation
End Sub
—
コードの解説:ここがプロのポイント
- `CreateQueryDef`: これが魔法のコマンドです。データベース内に新しいクエリ定義を「動的に」書き込みます。
- 名前の工夫 (`Format(Now, “hhmmss”)`): 複数人が同時にシステムを使っても、クエリ名が競合しないように現在時刻を付与しています。
- `db.QueryDefs.Delete`: これが今回の核です。使い終わったら即座に消す。これにより、データベースが「ゴミ屋敷」になることを防ぎます。
- メモリの解放: `Set … = Nothing` を忘れないでください。Accessはメモリ管理がデリケートなソフトです。これをするだけで、アプリの動作が軽快になります。
—
陥りやすいエラーと対策
1. 「その名前のクエリは既に存在します」エラー:
- 対策: 実行前に `Delete` するか、上記のように必ず時刻等で一意の名前を作成するようにしてください。
2. パーミッションエラー:
- 対策: 共有環境でバックエンドが読み取り専用になっていないか確認してください。一時クエリ作成には書き込み権限が必要です。
3. SQLインジェクション:
- 対策: 今回は単純な例ですが、外部入力をSQLに含める場合は、必ず `Replace(str, “‘”, “””)` を使ってシングルクォーテーションをエスケープしてください。
—
まとめ:Accessを「プログラム」として使いこなそう
「クエリをデザイン画面でポチポチ作る」のは卒業です。VBAでクエリを動的に生成できるようになると、Accessは単なる「集計ツール」から「堅牢な業務アプリケーション」へと変貌します。
今日紹介したコードは、現場のセキュリティを一段引き上げるための第一歩です。ぜひ、ご自身のシステムで試してみてください。ここをクリアすれば、あなたはもう「Accessマクロ使い」ではなく、「Accessエンジニア」の仲間入りです。
応援しています。何か分からないことがあれば、またいつでも聞いてくださいね。
