Access VBAの深淵へようこそ。
マクロの記録から脱却し、自分の手でロジックを組み始めたあなたなら、一度は「型が一致しません(Error 3421)」という冷酷なエラーメッセージに突き放された経験があるはずです。
特に`DAO.QueryDef`を使って動的にSQLを組み立てる際、パラメータの型指定をサボると、Accessは容赦なく門前払いを食らわせます。今日は、このエラーを二度と出さないための「型変換の奥義」を伝授しましょう。
—
1. なぜ「型不一致」は起きるのか?
Accessは、SQLの中身(文字列)と、DAOが解釈するパラメータの型を非常に厳格に管理しています。
例えば、VBAで `Dim val as Variant` とした変数をそのままパラメータに放り込むと、Accessは「これは数値なのか? 文字列なのか? それとも日付なのか?」を推測しようとしますが、ここがズレるとエラーになります。
特に、「Null値が含まれる場合」や「日付型が文字列として解釈される場合」に事故は多発します。これを防ぐには、DAOのエンジンに対して「これは間違いなくこの型である」と明示的に伝えるキャスト(型変換)が不可欠です。
—
2. 汎用的なパラメータ設定関数(必携の武器)
毎回 `qdf.Parameters(“ID”).Value = …` と書くのはスマートではありません。型を自動判定し、適切に変換してセットする関数を一つ持っておくだけで、開発効率は劇的に向上します。
以下のコードを標準モジュールにコピペして、あなたの「武器庫」に加えてください。
‘ ———————————————————
‘ 機能: QueryDefのパラメータへ安全に値を代入する
‘ 引数: qdf – 対象のQueryDefオブジェクト
‘ paramName – パラメータ名
‘ val – 代入したい値
‘ ———————————————————
Public Sub SetSafeParam(qdf As DAO.QueryDef, paramName As String, val As Variant)
‘ 値がNullの場合は空文字ではなくNullとして処理する(重要!)
If IsNull(val) Or val = “” Then
qdf.Parameters(paramName) = Null
Else
‘ 型に応じて変換をかける
Select Case VarType(val)
Case vbDate
‘ 日付型はそのまま代入してもDAOが解釈するが、明示的にDate型へ
qdf.Parameters(paramName) = CDate(val)
Case vbString
‘ 文字列はそのまま
qdf.Parameters(paramName) = CStr(val)
Case vbInteger, vbLong, vbDouble, vbSingle
‘ 数値系はそのまま
qdf.Parameters(paramName) = val
Case Else
‘ 未知の型はVariantとして丸投げする
qdf.Parameters(paramName) = val
End Select
End If
End Sub
—
3. 実践:動的SQLを実行するワークフロー
では、この関数を使って、実際にクエリを動的に実行する美しいコードを見てみましょう。
Public Sub ExecuteDynamicQuery()
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Set db = CurrentDb
‘ あらかじめ作成しておいたパラメータクエリを参照
Set qdf = db.QueryDefs(“qry_TargetQuery”)
‘ 安全に関数を呼び出す
‘ フォームのテキストボックスなどから値を取得する想定
Call SetSafeParam(qdf, “[p_ID]”, 101)
Call SetSafeParam(qdf, “[p_Date]”, Date)
Call SetSafeParam(qdf, “[p_Keyword]”, “Access開発”)
‘ SQLの実行
qdf.Execute dbFailOnError
‘ 後始末
qdf.Close
Set qdf = Nothing
Set db = Nothing
MsgBox “クエリの実行が完了しました。”, vbInformation
End Sub
—
4. 伝説のアーキテクトからのアドバイス
ここをクリアすれば、Access VBAの「中級の壁」を確実に超えたと言えます。
- Nullを制するものはAccessを制す:
データベースの世界で最も厄介なのは `0` と `Null` の混同です。上記の関数では `IsNull` チェックを徹底しています。これを怠ると、検索条件がヒットしないという不可解なバグに数時間悩まされることになります。
- VarType関数の恩恵:
`VarType` 関数を使うことで、実行時に変数が何者であるかを正確に把握できます。これはデバッグにおいても非常に強力な武器になります。
まとめ:次に進むために
今回紹介した `SetSafeParam` 関数は、あなたのコードから「型不一致」というノイズを消し去るための第一歩です。
まずは、今書いているコードの `qdf.Parameters(…) = …` の部分を、この関数に置き換えてみてください。エラーが減るだけでなく、コードが驚くほどスッキリと読みやすくなるはずです。
プログラムは、「書く量」ではなく「いかに安全を担保して自動化するか」が重要です。応援していますよ。困ったことがあれば、またいつでも聞きに来てください。
