【入門編】サブクエリを多用する複雑なSQLをQueryDefで動的に組み立てるコツ – Access VBA解析バイブル

スポンサーリンク

Access VBAの深淵へ:複雑なサブクエリを「美しく」組み立てる極意

こんにちは。現場で泥臭い自動化を積み重ね、いつしかAccessのクエリ定義(QueryDef)と心中するようになったアーキテクトです。

「サブクエリが何重にも重なったSQLをVBAで書くと、コードがスパゲッティ状態になり、修正のたびに吐き気がする……」。もしあなたがそんな悩みを抱えているなら、安心してください。それはあなたのセンスが悪いのではなく、「SQLを文字列として扱う際の作法」を知らないだけです。

今日は、保守性を極限まで高めるための「SQL構築術」を伝授します。ここをクリアすれば、あなたはもうマクロ記録の呪縛から完全に解放されます。

—

1. なぜ「一行で書く」のが悪手なのか

多くの初学者がやりがちなのが、SQLを一つの長い文字列として繋ぐ書き方です。

‘ 絶対にやってはいけない例
strSQL = “SELECT FROM (SELECT A.ID FROM TableA AS A WHERE A.Flag = True) AS SubQ WHERE SubQ.ID IN (SELECT B.ID FROM TableB AS B)”

これの何が問題か?「どこで改行されているか」「どの括弧がどこに対応しているか」が視覚的に判別不能だからです。 修正が必要になった瞬間、開発者はデバッグという名の迷路に迷い込みます。

—

2. 「インデント」と「改行」をコードに埋め込む

QueryDefで動的SQLを生成する際の鉄則は、「SQLエディタで書くときと同じインデントをVBA内に再現すること」です。

VBAの文字列連結演算子 `&` と、改行コード `vbCrLf` を巧みに使いましょう。

推奨されるコーディングスタイル

Public Sub CreateDynamicQuery()
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim strSQL As String

Set db = CurrentDb

‘ SQLを論理構造ごとに「& _」で繋いでいく
strSQL = “SELECT T1.ID, T1.Name ” & vbCrLf & _
“FROM TableA AS T1 ” & vbCrLf & _
“WHERE T1.ID IN (” & vbCrLf & _
” SELECT T2.ID ” & vbCrLf & _
” FROM TableB AS T2 ” & vbCrLf & _
” WHERE T2.Status = ‘Active'” & vbCrLf & _
“)”

‘ QueryDefオブジェクトとして保存(または実行)
‘ 既に存在する場合は一旦削除して作り直すのが定石
On Error Resume Next
db.QueryDefs.Delete “qryDynamicResult”
On Error GoTo 0

Set qdf = db.CreateQueryDef(“qryDynamicResult”, strSQL)

Debug.Print “SQLの構築が完了しました。”
End Sub

この書き方のメリット:

  • 構造の可視化: サブクエリの開始位置が一目でわかります。
  • デバッグ容易性: `Debug.Print strSQL` を叩いたとき、イミディエイトウィンドウに「整形されたSQL」が出力されます。そのままコピーしてAccessのクエリデザイン画面に貼り付けるだけで動作確認が可能です。

—

3. パラメータークエリへの昇華

文字列を直接埋め込む手法は簡単ですが、数値や日付の形式でエラー(いわゆる「型不一致」)が頻発します。さらに、SQLインジェクションのリスクもゼロではありません。

「動的SQL」の真の力は、QueryDefのParametersコレクションを使うことで発揮されます。

‘ パラメータークエリの動的生成例
Set qdf = db.CreateQueryDef(“qryDynamicResult”)
qdf.SQL = “PARAMETERS TargetDate DateTime; ” & _
“SELECT FROM TableA WHERE CreatedDate >= [TargetDate]”

‘ パラメーター値をセットして実行
qdf.Parameters(“TargetDate”) = #2023/01/01#

このように「SQLの構造」と「中身のデータ」を分離するのが、プロのアーキテクトの思考です。

—

4. 初学者が陥りやすい罠と解決策

  • 罠1:ダブルクォーテーションの迷宮

SQL内の文字列指定(例: `WHERE Status = ‘Active’`)でダブルクォーテーションを多用すると混乱します。SQL内の文字列囲みにはシングルクォーテーション `’` を使う習慣をつけましょう。

  • 罠2:予約語の衝突

テーブル名やフィールド名に `Date` や `Name` などの予約語を使うと、サブクエリ内でエラーが出やすくなります。必ず `[ ]` (ブラケット)で囲む癖をつけてください。

  • 罠3:改行の欠落

`”FROM TableA” & “WHERE…”` と書くと、連結時に `TableAWHERE` となり、構文エラーになります。連結時は必ず `vbCrLf` か、文字列の末尾に半角スペースを入れることを忘れないでください。

—

最後に:自動化は「美学」である

複雑なサブクエリを扱うとき、コードを「ただ動けばいいもの」として書くのか、「後から見た人が一瞬で理解できるもの」として書くのか。この意識の差が、半年後のあなたを救います。

Access VBAは古いと言われますが、「データ構造を理解し、クエリという論理を組み立てる力」は、どの言語に行っても通用する最強の武器です。

まずは、今のその汚いコードを、インデントを入れて「整列」させることから始めてみてください。それが、伝説への第一歩です。

何か詰まったら、いつでも聞いてください。あなたのコードが美しく整うまで、私はここにいますよ。

タイトルとURLをコピーしました