Microsoft Access 掲示板

CurrentDb.Execute strSQLでは何故かエラー / 2

6 コメント
views
2

実行時エラー'3061'
パラメータが少なすぎます。4を指定して下さい。

変数 strSQL に格納されている SQL がパラメータクエリになっているからです。

Forms![F_改修履歴に追加設定]![tx受付日付代入用]

Forms![F_改修履歴に追加設定]![tx改修内容代入用]

Forms![F_改修履歴に追加設定]![tx完了日付代入用]

Forms![F_改修履歴に追加設定]![tx_memo代入用]

以上の 4 箇所がそれぞれ暗黙的なパラメータとして認識されています。

そして DAO.Database オブジェクトの Execute メソッドでは、
パラメータへの値渡しを行うことが出来ません。

この場合は、次のいずれかの方法を用いるのが妥当です。

'Access のシステムメッセージの表示を無効にする
DoCmd.SetWarnings False
'Access の[SQL の実行]アクションを呼び出す
DoCmd.RunSQL strSQL
'Access のシステムメッセージの表示を有効にする
DoCmd.SetWarnings True
'フォーム[F_改修履歴に追加設定]のフォームモジュールから実行する場合

Dim dbTarget As DAO.Database
Dim qdfTemp As DAO.QueryDef
Dim lngInsertedCount As Long

'カレントデータベースの参照
Set dbTarget = CurrentDb
'一時的なクエリを作成する
Set qdfTemp = dbTarget.CreateQueryDef("", strSQL)

With qdfTemp
    '各パラメータに値を渡す
    .Parameters("Forms![F_改修履歴に追加設定]![tx受付日付代入用]").Value = Me![tx受付日付代入用].Value
    .Parameters("Forms![F_改修履歴に追加設定]![tx改修内容代入用]").Value = Me![tx改修内容代入用].Value
    .Parameters("Forms![F_改修履歴に追加設定]![tx完了日付代入用]").Value = Me![tx完了日付代入用].Value
    .Parameters("Forms![F_改修履歴に追加設定]![tx_memo代入用]").Value = Me![tx_memo代入用].Value
    'クエリを実行する
    .Execute dbFailOnError
    'クエリによって影響を受けたレコードの件数を取得する
    lngInsertedCount = qdfTemp.RecordsAffected
End With

Set qdfTemp = Nothing
Set dbTarget = Nothing

If lngInsertedCount > 0 Then
    MsgBox "[T_登録中継用_改修履歴]に " & lngInsertedCount & " 件のレコードが追加されました。", _
           vbInformation, _
           "実行完了"
Else
    MsgBox "追加対象となるレコードがありません。", _
           vbInformation, _
           "対象レコードなし"
End If

後者の方法は、主に以下のようなケースにおいて用いるのが適しています。

  • 特定のインターフェース(この場合はフォーム)に依存せず、パラメータに任意の値を直接渡したい場合

  • 実行されたクエリ/SQLによって影響を受けたレコードの件数を取得したい場合

  • DAO.Workspace オブジェクトと連携してトランザクション処理を行いたい場合

通報 ...
  • 3

    なお、任意のコントロールの値を「 SQL 内におけるリテラル」として文字列連結させる手法もよく見られますが、以下のようなケースに備えてエスケープ処理を行うことが望ましいでしょう。

    • コントロールの値(文字列)にシングルクォーテーション( ' )やダブルクォーテーション(")、改行(などの制御文字)が含まれている場合。

    • コントロールの値が Null である場合。

    DAO.QueryDef オブジェクトを使用してパラメータの値渡しを直接行なうのであれば、エスケープ処理は不要です。