こんにちは! Access VBAでの開発、日々の試行錯誤お疲れ様です。
マクロの記録から一歩踏み出し、「自分でコードを書いてシステムをコントロールしたい!」そう思ってVBAを学び始めたあなたへ。今回は、Access開発の現場で「知っているか、知らないかで生産性が10倍変わる」と言っても過言ではない、超重要テクニックをお伝えします。
ここをクリアすれば、あなたの書くコードは一気にプロのそれへと進化しますよ。ぜひ最後までついてきてくださいね!
—
1. なぜ「VBAの中にSQLを直接書く」のは危険なのか?
VBAを書いていると、ついやりがちなのがこんなコードです。
‘ ありがちな悪い例
Dim strSQL As String
strSQL = “SELECT FROM T_受注 WHERE 顧客ID = ” & Me.txt顧客ID & ” AND 受注日 >= #” & Me.txt開始日 & “#”
DoCmd.RunSQL strSQL ‘ ※実際はSELECT文には使えませんがイメージです
一見動くように見えますよね? でも、実務でこれをやると、以下の地獄が待っています。
1. シングルクォーテーションや日付の「#」の付け忘れで、毎日エラーの嵐
2. SQLが長くなると、VBAのコード内が文字列の連結だらけで何が書いてあるか全く読めない
3. 「SQLインジェクション」というセキュリティ上の脆弱性の温床になる
「じゃあ、どうすればいいの?」
そこで登場するのが、今回マスターする 「QueryDef(クエリディフィニション)を使った固定クエリの動的書き換え」 という設計術です。
—
2. QueryDefってなに?(図解的イメージ)
Accessのナビゲーションウィンドウ(左側のオブジェクト一覧)にある「クエリ」を、VBAから自由自在に操るためのオブジェクト、それが QueryDef です。
イメージとしては、Accessの裏側に「ホワイトボード」があらかじめ用意されていると思ってください。
[Accessの裏側(デザイン画面)]
QueryDef: “q_受注抽出” (← ホワイトボードに書かれた基本のSQL)
↓
[VBAの魔法]
「おいQueryDef、今日の条件に合わせて、ホワイトボードのWHERE句の部分だけ書き換えておいてくれ!」
↓
[実行結果]
常に最新かつ安全な状態でクエリが実行される!
あらかじめAccess側に「ひな形(固定クエリ)」を作っておき、実行する直前にVBAからその中身(SQLプロパティ)を書き換える。これが、保守性と可読性を劇的に向上させる王道のアーキテクチャです。
—
3. 実践!QueryDefでSQLを書き換えるコード
百聞は一見に如かず。実際にコードを見てみましょう。
今回は、フォームに入力された条件(顧客名と担当者)を使って、あらかじめ作っておいたクエリのSQLを書き換え、それを元にレポートを開く処理を想定します。
ステップ1:準備
Accessのクエリデザイナで、適当なSELECT文のクエリを作成し、名前を `q_受注検索` と保存しておいてください(中身は `SELECT FROM T_受注;` だけでもOKです)。
ステップ2:VBAコードの実装
フォームの検索ボタンなどに、以下のように記述します。
Sub 検索実行ボタン_Click()
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim strSQL As String
On Error GoTo ErrorHandler
‘ 1. 現在のデータベース(自分自身)を参照する
Set db = CurrentDb
‘ 2. あらかじめ用意したクエリ(q_受注検索)をQueryDefとして取得する
Set qdf = db.QueryDefs(“q_受注検索”)
‘ 3. 動的に埋め込む条件をフォームから取得
Dim 顧客名条件 As String
Dim 担当者条件 As String
‘ 未入力なら条件なし(全員対象)にする優しさ設計
If IsNull(Me.txt顧客名) Then
顧客名条件 = “1=1” ‘ 常に真となる条件
Else
‘ フォームの値は必ずシングルクォーテーションで囲むなどの配慮を
顧客名条件 = “顧客名 LIKE ‘” & Me.txt顧客名 & “‘”
End If
If IsNull(Me.cmb担当者) Then
担当者条件 = “1=1”
Else
担当者条件 = “担当者ID = ” & Me.cmb担当者
End If
‘ 4. 基本となるSQLを構築し、QueryDefのSQLプロパティに流し込む!
‘ ★ここが今回の最大の肝です!
strSQL = “SELECT FROM T_受注 ” & _
“WHERE ” & 顧客名条件 & ” ” & _
“AND ” & 担当者条件 & ” ” & _
“ORDER BY 受注日 DESC;”
‘ QueryDefのSQLを上書き!これでAccess側のクエリが「変身」します
qdf.SQL = strSQL
‘ 5. 書き換わったクエリを元に、レポートを開く!
DoCmd.OpenReport “r_受注一覧”, acViewPreview
MsgBox “検索が完了しました!”, vbInformation, “成功”
CleanUp:
‘ 6. オブジェクトの開放(メモリリークを防ぐプロの作法)
Set qdf = Nothing
Set db = Nothing
Exit Sub
ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “異常終了”
Resume CleanUp
End Sub
—
4. このテクニックが「神」である3つの理由
初学者のうちは「ふーん、変数に入れたSQLをそのまま `DoCmd.OpenReport` の条件に書いちゃダメなの?」と思うかもしれません。ですが、このQueryDef書き換え方式には圧倒的なメリットがあります。
① デバッグが秒で終わる
もしSQLに間違いがあっても、Accessのクエリ画面を開けば、VBAによって書き換えられた最新のSQLがそのまま残っています。
それをクエリデザイナの「SQLビュー」に貼り付ければ、何が間違っているか一目瞭然です。VBAのイミディエイトウィンドウにSQLを出力して睨めっこする必要はもうありません。
② クエリの再利用性が爆上がりする
裏側のクエリ(`q_受注検索`)をベースにして、フォームのリストボックスのデータソースに設定したり、Excelへエクスポートする処理の流用が簡単にできます。「データを取り出す窓口」がクエリという実体として目に見える形でお釣りが来るのです。
③ メンテナンスが圧倒的に楽
半年後に「やっぱり表示する項目に『備考』を追加して欲しい」と言われたとします。
VBAの文字列を直す必要はありません。Accessのクエリデザイナを開いて、GUIで「備考」フィールドを追加して保存するだけ。VBA側のコードは一文字も変えなくていいのです!これぞ保守性抜群のシステム設計です。
—
5. 開発現場で役立つ、ワンランク上の心得
最後に、プロのエンジニアとして一つだけアドバイスを。
コードの最後にある `Set qdf = Nothing` や `Set db = Nothing`。
「めんどくさいから書かなくても動くじゃん」と思っていませんか? 小規模なアプリなら動きますが、Accessのデータベースエンジン(ACE)はメモリ管理に少しデリケートです。これらのオブジェクトを明示的に解放する習慣をつけることで、長期間稼働してもメモリリークしない、堅牢なシステムが作れるようになります。
「動けばいいコード」から「メンテナンスしやすく美しいコード」へ。
今回のQueryDefを使いこなす技術は、間違いなくあなたをそのステージへ引き上げてくれます。
ここをクリアしたあなたなら、もうAccess VBAの基礎はバッチリです!
ぜひ今日の開発から、この「QueryDef動的書き換えテクニック」を取り入れてみてくださいね。応援しています!
