AccessVBAで動的クエリ生成、開発効率を高めるTIPS

AccessVBA

AccessVBAでクエリを簡単に作成するには?

AccessVBAのプログラム処理中に動的にSQLからクエリを作成したい場合があります。

シチュエーション

帳票・エクスポート処理との連携
DoCmd.OpenReportや DoCmd.TransferSpreadsheet と組み合わせることで、帳票出力やExcel出力用のクエリを動的に切り替える設計が可能になります。

クエリの動的再作成処理
条件や集計ロジックが頻繁に変わる帳票処理では、クエリを毎回手動で作り直すのは非効率です。最新のSQLを指定するだけでクエリを自動生成でき、開発・保守の手間を大幅に削減できます。

バッチ処理前のクエリ初期化
夜間バッチや定期処理の前に、使用するクエリを毎回作り直したいケースがあります。同名クエリが存在しても自動削除されるため、意図しない古い定義を使ってしまうリスクを防げます。

条件切替型の集計処理
画面入力された条件に応じてSQLを組み立て、その内容でクエリを作成することで、処理の流れが分かりやすくなります。Recordset直操作よりも、クエリベースの設計が可能になります。

デバッグ・検証用クエリの生成
一時的にデータ確認用のクエリを作成したい場合にも便利です。SQLをそのままクエリとして残せるため、Accessのクエリデザイナで内容を目視確認できます。

動的クエリ生成するサンプルコード

サンプルコードを紹介します。

'================================================================================
'  関数名:gf_CreateQuery
'  機能 :指定したクエリ名でクエリを作成します。
'           同名のクエリが既に存在する場合は、一度削除してから再作成します。
'
'  【引数】
'    strQueryName : 作成するクエリ名
'    strSql       : クエリに設定する SQL 文
'
'  【戻り値】
'    True  : クエリ作成成功
'    False : エラーにより作成失敗
'================================================================================
Public Function gf_CreateQuery(strQueryName As String, strSql As String) As Boolean

    Dim l_db As Database
    Dim l_qd As QueryDef
    Dim l_er As Error
    Dim l_msg As String

    On Error GoTo Err_CreateQuery
    gf_CreateQuery = False

    Set l_db = CurrentDb()

    If gf_ExistQuery(strQueryName) Then
        l_db.QueryDefs.Delete strQueryName
    End If

    Set l_qd = l_db.CreateQueryDef(strQueryName, strSql)
    gf_CreateQuery = True
    Exit Function

Err_CreateQuery:
    l_msg = ""
    For Each l_er In Errors
        l_msg = l_msg & _
                "Error No : " & l_er.Number & vbCrLf & _
                "内容     : " & l_er.Description & vbCrLf & vbCrLf
    Next l_er

    MsgBox l_msg, vbCritical, "gf_CreateQuery エラー"
    gf_CreateQuery = False

End Function


'================================================================================
'  関数名:gf_ExistQuery
'  機能 :指定したクエリ名が存在するかを判定します。
'================================================================================
Public Function gf_ExistQuery(strQueryName As String) As Boolean

    Dim l_db As Database
    Dim l_qd As QueryDef

    gf_ExistQuery = False
    Set l_db = CurrentDb()

    For Each l_qd In l_db.QueryDefs
        If l_qd.Name = strQueryName Then
            gf_ExistQuery = True
            Exit Function
        End If
    Next l_qd

End Function

使い方

基本構文

If gf_CreateQuery("クエリ名", "SQL文") Then
    ' 正常にクエリ作成
Else
    ' エラー発生
End If

使用例①:単純なSELECTクエリを作成する

Dim strSql As String

strSql = "SELECT * FROM Q_船マスタ"

Call gf_CreateQuery("Q_船マスタ", strSql)

使用例②:条件付きクエリを作成する

Dim strSql As String

strSql = "SELECT * FROM T_売上 " & _
         "WHERE 売上日 >= #2024/01/01#"

If gf_CreateQuery("Q_売上抽出", strSql) Then
    DoCmd.OpenQuery "Q_売上抽出"
End If

使用例③:集計クエリを作成する

Dim strSql As String

strSql = "SELECT 部署, SUM(金額) AS 合計金額 " & _
         "FROM T_売上 " & _
         "GROUP BY 部署"

If gf_CreateQuery("Q_部署別売上集計", strSql) Then
    MsgBox "クエリ作成しました。"
Else
    MsgBox "クエリ作成失敗しました。"
End If

実行結果

使用例①:単純なSELECTクエリを作成するの例です。

指定した名称のクエリオブジェクトが作成されていることが確認できます。
※表示されない場合には、オブジェクト一覧で【F5】キーを押下すると最新化されます。

最後に

Access開発では、クエリをどのように管理するかが、保守性や開発効率に大きく影響します。画面や処理ごとにSQLを直書きしていると、後から仕様変更が入った際に修正箇所が増え、トラブルの原因になりがちです。

サンプルのようにクエリ作成処理を関数化しておくことで、クエリ定義を一元的に扱えるようになり、処理の流れも明確になります。また、Accessのクエリとして残るため、デザイナで内容を確認できる点も大きなメリットです。
日々の作業で「条件が異なる同じクエリ作成を何度も書いている」と感じたら、ぜひこの関数を取り入れてみてください。Accessらしい堅実で分かりやすい設計につながるはずです。

コメント

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