プロが教えるわが家の防犯対策術!

Access ADOでフォームのコントロールを参照するパラメータークエリーを開こうとすると、どうしても「SQLステートメントが正しくありません・・・」のエラーが発生してしまいます。
もちろん、クエリー単体では正常に動作しますが、クエリーのパラメーターに参照するコントロールを登録してもADOでは開けません。
現在はパラメータークエリーの抽出結果を一時テーブルに書き込んで、これをADOで開くという非効率極まりない方法で凌いでいますが、どうすれば良いのでしょうか。

このQ&Aに関連する最新のQ&A

A 回答 (5件)

添付図を忘れていました。

「Access ADO パラメータークエリ」の回答画像5
    • good
    • 0
この回答へのお礼

たいへんありがとうございます。助かりました。
これで、長年の悩みが解決しました。
「外道」的方法ですが、直接SQL文を編集してからADOで開くのが一番簡単かもしれません。

sqlStr="SELECT B.Field_1, B.ID FROM B WHERE (((B.ID)=" & [Forms]![B]![ID] & "));"

rst.open sqlStr,cn, ....

お礼日時:2014/12/05 00:13

・パラメータの指定は最大3つまで。


・パラメータの記述は次で統一。
 一番目=[xxxxx]
 二番目=[yyyyy]
 三番目=[zzzzz]

こういう約束ですと、自分だけが使う次のような関数を用意すれば・・・。

Public Function SetQueryParameters(ByVal strQueryName As String, _
                  Optional varParamValue1 As Variant = Null, _
                  Optional varParamValue2 As Variant = Null, _
                  Optional varParamValue3 As Variant = Null) As String
On Error Resume Next
  Dim cnn As ADODB.Connection
  Dim cat As ADOX.catalog
  Dim cmd As ADODB.Command
  Dim strCommandText As String


  ' 接続を開きます。
  Set cnn = CurrentProject.Connection
  
  ' カタログを開きます。
  Set cat = New ADOX.catalog
  cat.ActiveConnection = cnn

  ' Command オブジェクト
  Set cmd = New ADODB.Command
  Set cmd = cat.Procedures(strQueryName).Command
  
  ' パラメータの置換
  strCommandText = cmd.CommandText
  strCommandText = IIf(Len(varParamValue1 & "") > 0, Replace(strCommandText, "[xxxxx]", varParamValue1), strCommandText)
  strCommandText = IIf(Len(varParamValue1 & "") > 0, Replace(strCommandText, "[yyyyy]", varParamValue2), strCommandText)
  strCommandText = IIf(Len(varParamValue1 & "") > 0, Replace(strCommandText, "[zzzzz]", varParamValue2), strCommandText)
  SetQueryParameters = strCommandText
End Function

添付図では、次のDBSelect()が、ちゃんと"A"を取得しています。

Public Function DBSelect(ByVal strQuerySQL As String, Optional strPause As String = ";") As Variant
On Error GoTo Err_DBSelect
  Dim I      As Integer
  Dim J      As Integer
  Dim R      As Integer  ' DataValue(,) のインデックスを決める行カウンター
  Dim C      As Integer  ' DataValue(,) のインデックスを決める列カウンター
  Dim M      As Integer  ' DataValue(,) の一つ目の添字の最大値=行総数 - 1
  Dim N      As Integer  ' DataValue(,) の二つ目の添字の最大値=列総数 - 1
  Dim rst     As ADODB.Recordset
  Dim fld     As ADODB.Field
  Dim strList   As String   ' 全てのデータをセミコロン(;)等で区切った文字列に
  
  Set rst = New ADODB.Recordset
  ' =================
  ' Begin With: rst
  ' -----------------
  With rst
    .Open strQuerySQL, _
       CurrentProject.Connection, _
       adOpenStatic, _
       adLockReadOnly
    If Not .BOF Then
      ' --------------
      ' 配列を再宣言
      ' --------------
      M = .RecordCount - 1
      N = .Fields.Count - 1
      ReDim dataValues(M, N)
      ' ------------------------------------
      ' 列情報を For-Next で配列に代入する
      ' ------------------------------------
      .MoveFirst
      For R = 0 To M
        C = -1
        For Each fld In .Fields
          With fld
            C = C + 1
            dataValues(R, C) = .Value
          End With
        Next fld
        .MoveNext
      Next R
    Else
      ReDim dataValues(0, 0)
      dataValues(0, 0) = ""
      strList = ""
    End If
  End With
  ' ---------------
  ' End With: rst
  ' ===============
  ' -------------------------------
  ' 区切子(;)で連結して1文に
  ' -------------------------------
  If Len(strPause) Then
    For I = 0 To M
      For J = 0 To N
        strList = strList & dataValues(I, J) & strPause
      Next J
      strList = strList & Chr(13)
    Next I
  End If
Exit_DBSelect:
On Error Resume Next
  rst.Close
  Set rst = Nothing
  DBSelect = IIf(Len(strPause), strList, dataValues())
  Exit Function
Err_DBSelect:
  MsgBox "SELECT 文の実行時にエラーが発生しました。(DBSelect)" & Chr$(13) & Chr$(13) & _
      "・Err.Description=" & Err.Description & Chr$(13) & _
      "・SQL Text=" & strQuerySQL, _
      vbExclamation, " 関数エラーメッセージ"
  Resume Exit_DBSelect
End Function
    • good
    • 0

? DBSelect(Replace(GetQueryText("testQ"), "Forms!B!ID", Forms("B").Controls("ID")))


B;1;

添付図が見にくいので・・・。

つまり、クエリのSQL文を取得し、Replace関数でパラメータをセットしてADOに渡せば、<ちょっと面倒なやり方>をする必要はないということです。
    • good
    • 0
この回答へのお礼

ご教示ありがとうございます。
なぜADOでパラメータークエリーがうまく動かないのか、原因と解消法がわかりました。
ただ、一度に複数のパラメーターを取得する場合は、どの様にしたら良いのでしょうか。
とりあえず、フォーム側を細工すればひとつのパラメーターで済ませそうですが。

お礼日時:2014/12/04 18:14

>ADOでフォームを参照するパラメータークエリーを開こうとすると、


>エラーが発生してしまいます。
>もちろん、クエリー単体では正常に動作しますが、
>クエリーのパラメーターを工夫してもADOでは開けません。

これは、当たり前のことですよ。
例えば、次のような関数を用意してテストすると判ります。

Public Function GetQueryText(ByVal strQueryName As String) As String
  Dim cnn As ADODB.Connection
  Dim cat As ADOX.catalog
  Dim cmd As ADODB.Command


  ' 接続を開きます。
  Set cnn = CurrentProject.Connection
  
  ' カタログを開きます。
  Set cat = New ADOX.catalog
  cat.ActiveConnection = cnn

  ' Command オブジェクト
  Set cmd = New ADODB.Command
  Set cmd = cat.Procedures(strQueryName).Command
 
  GetQueryText = cmd.CommandText
End Function

【testQ】

SELECT B.Field_1, B.ID
FROM B
WHERE (((B.ID)=[Forms]![B]![ID]));

Accessでクエリを実行するとtestQ のWhere節は

WHERE ID=2

に変換されてます。しかし、ADOで実行しても、その変換は行われません。ですから、当然にエラーになります。

【一番簡単なエラー回避策】

添付図のように、クエリのパラメータを変換してADOに渡すことです。

【ちょっと面倒なやり方】

http://msdn.microsoft.com/ja-jp/library/cc376629 …
「Access ADO パラメータークエリ」の回答画像2
    • good
    • 0

> Access ADOでフォームのコントロールを参照するパラメータ


単体起動できるんだから、上記の部分があやしい。

パラメータ指定部分を開示いただけますか?
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

関連するカテゴリからQ&Aを探す

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QAccess パラメータクエリーをVBAで実行

初めての質問になります、宜しくお願いします。

Access2007でのPG開発を行っています。

Insertのパラメータクエリーを作成してました(以下Q_Inst)。

VBA側でパラメータをセットして実行するとエラーが出てしまいます。

実行時エラー3265
要求された名前、または・・・

dbCmd.CommandText = "Q_Inst"
dbCmd.CommandType = adCmdStoredProc
dbCmd.Parameters.Refresh
dbCmd.Parameters("[ID]") = 1 ' ←ここでエラー
dbCmd.Parameters("[Name]") = TanakaTarou
dbCmd.Parameters("[Birth]") = "1980/12/01"

ADODB.Command をあまり使わないので勝手がいまいち分かりません。
SELECT、INSERT、UPDATEは今までdbCon.Execute(strSQL)でstrSQLの中にべた書きしてました。

エラーの対処方法をご教授お願い致しますm( _ _ )m

初めての質問になります、宜しくお願いします。

Access2007でのPG開発を行っています。

Insertのパラメータクエリーを作成してました(以下Q_Inst)。

VBA側でパラメータをセットして実行するとエラーが出てしまいます。

実行時エラー3265
要求された名前、または・・・

dbCmd.CommandText = "Q_Inst"
dbCmd.CommandType = adCmdStoredProc
dbCmd.Parameters.Refresh
dbCmd.Parameters("[ID]") = 1 ' ←ここでエラー
dbCmd.Parameters("[Name]") = TanakaTarou
dbCmd.Parameters("[Birt...続きを読む

Aベストアンサー

以下もみてください。

ADOでのパラメータクエリの使用例

http://www.accessclub.jp/ado/createparameter.html
http://www.accessclub.jp/ado/refresh.html

Q選択クエリを開けない

お尋ねします。
OSはXP、ACCESS2002でDB作成中です。

ADOで選択クエリを開きたいのですが、エラーが出てうまくいきません。

Dim cnc As New ADODB.Connection
Dim rst As New ADODB.Recordset
Set cnc = CurrentProject.Connection

stSQL = "Q_残高計算"
rst.Open stSQL, cnc

・・・・・・・・・・・・・・・・・・・・・・・

上記のコードで、”Q_残高計算”という選択クエリを開きたいのですが、実行すると、
「実行時エラー'2147217900(80040e14)':
SQLステートメントが正しくありません。'DELETE'、'INSERT'、'PROCEDURE'、'SELECT'、または'UPDATE'を使用してください。」
というエラーメッセージが出てしまいます。

どこがまずいのでしょうか?
よろしくお願いします。

Aベストアンサー

> パラメータの指定は「開始日」「終了日」「仕入先」の3つが必要なのでしょうか。
その通りです。
・「クエリ」-「パラメータ」でその3つを定義
・SQL条件で上記パラメータを参照
・ADOからパラメータ値を指定して実行

QVBAからクエリのパラメータを設定したいです。

いつもお世話になっております。

クエリーは全く同じ内容ですが、
複数のフォームにパラメータを入力するユーザーインターフェースのため、ク
エリーを複数用意して、それぞれに
[forms]![F_TEST]![テキスト名]というパラメータを設定し、フォームの帳票やレポートの帳票に出力していま
した。

このクエリを一本にして、VBAから動的にパラメータを参照するフォームを指定
できないでしょうか?

よろしくお願いいたします。

Aベストアンサー

再びmaruru01です。
既存のクエリもVBAのSQLステートメント化をお奨めします。
それを標準モジュールに、

Public Sub myRunSQL(Para As String)

  Dim SQL As String

  SQL = "(SQL文の前の方)" & Para & "(SQL文の後ろの方)"
  DoCmd.RunSQL SQL

End Sub

という風にそれぞれのクエリを各プロシージャにしておけば、どこからでも呼び出せるわけです。
すでに作ってあるクエリを書き直すのは面倒ですが、一度書いてしまえばあとは楽です。
また、まったく同じじゃないんだけど結構似てるというクエリは、プロシージャをコピーして名前と中身をかえてやればすぐ出来るわけです。
ちなみに私は、基本的には、クエリもマクロも使用せず、すべてVBAで書いています。
では。

QDAOとADOの違いについて

Accessからイントラネット上のデータベースに接続するための接続方法で困っています。
DAOとADOの違いが分からず困っています。
メリット、デメリットが分かる方、どうか教えてください。

宜しくお願い致します。

Aベストアンサー

DAO(データアクセスオブジェクト)はAccessで使用されるMicrosoftJetデータベースエンジン を公開した最初のオブジェクト指向インターフェイスです。DAOは単一システムのアプリケーションや小規模でローカルなネットワークで使用するのに最も適しています。
とMSDNライブラリでは説明しています。
DAOはJetデータベースエンジンを対象にして開発されているのでJetのもつセキュリティ機能・データ定義機能などを十分に操作することができます。
ADO(ActiveXDataObjects)ではオブジェクトの種類が簡素化されているためJetデータベースエンジンの細かな機能を制御することができないといった点が不足している部分がありますがADOXやJROの各オブジェクトモデルで使用できる機能を使えばADOで不足している機能をほとんど補うことができます。
DAOはデータベースにAccessを使用するアプリケーションの場合、最大のパフォーマンスを得ることができます。しかしアプリケーションを運用していくうちに規模が大きくなってデータベースをSQLServerに移行することがあるかもしれません。
そのような可能性が含まれているのであれば最初からADOで開発しておいたほうが無難です。ADOはSQLServerに対する処理で良いパフォーマンスを得ることができます。

Jetデータベースエンジンを主なターゲットにしているならDAOで可。それ以外のデータベースを利用するのであればADOを選択する方が良いのではと思います。

DAO(データアクセスオブジェクト)はAccessで使用されるMicrosoftJetデータベースエンジン を公開した最初のオブジェクト指向インターフェイスです。DAOは単一システムのアプリケーションや小規模でローカルなネットワークで使用するのに最も適しています。
とMSDNライブラリでは説明しています。
DAOはJetデータベースエンジンを対象にして開発されているのでJetのもつセキュリティ機能・データ定義機能などを十分に操作することができます。
ADO(ActiveXDataObjects)ではオブジェクトの種類が簡素化されて...続きを読む

Q実行時エラー 3265「要求された名前、または序数

ADOで
rs.Open strSQL, cn, adOpenKeyset, adLockOptimistic
を過ぎようとすると
実行時エラー 3265「要求された名前、または序数に対応する項目がコレクションに見つかりません」
になるのですが、
strSQLの文字列をクエリのSQLビューに張り付けると、問題なくクエリが表示されます。

だから、
存在しないフィールド名を指定した訳ではないのですが
なぜこの部分でエラーになるのでしょうか?

オブジェクトが閉じてないのかと思い、
rs.Close: Set rs = Nothing
をイミディエイトでやってみたら
オブジェクトが閉じている場合は、操作は許可されません。
になります。

Aベストアンサー

参照設定で、ADOにチェックがあり、かつ、DAOより上にありますか?

QAccessのRefresh・Requery・Repaintの違い

Requeryはもう一度ソースレコード(テーブル)を読み込むようです。このとき、テーブルの先頭レコードに移動してしまいます。
Refreshは最新のレコード(テーブル)を再表示するような気がします。レコードの移動は起こらない気がします。
Repaintは、VBAでキャプションなどを変更したとき使っています。
でも、よくわかっていません。
どんなときにどんなメソッドを使えばいいのでしょうか?
詳しい方、よろしくお願いいたします。

Aベストアンサー

たびたびすみません。
調べてたらこんなのがでてきました。
http://www.nurs.or.jp/~ppoy/access/access/acF007.html

参考URL:http://www.nurs.or.jp/~ppoy/access/access/acF007.html

QAccess サブフォームでの選択行の取得

こんにちは。

Access初心者です。

サブフォームでテーブルの項目を表示させていますが、
選択された行を取得する方法はありますか?
サボフォームの下の方に現在選択されているレコード数が表示されてますが、その値でかまいません。

調べているのですが、なかなか検討がつきません。
宜しくお願い致します。

Aベストアンサー

フォーム名がフォーム1、サブフォームコントロールの名前がサブフォーム1だとすると、

Forms!フォーム1!サブフォーム1.Form.CurrentRecord

で取得できます。
(「Forms」と「Form」がありますのでご注意下さい)


また、フォーム1にコードを記述する場合であれば

Me!サブフォーム1.Form.CurrentRecord

サブフォーム1へのコード記述であれば

Me.CurrentRecord

という構文によっても、それぞれ取得が可能です。

QAccess2000でVBAからパラメータクエリを実行

Access2000でフォームからの値を参照して実行するクエリを作りました。
SQLで表すと、以下のようなものです。

クエリ名:test
SELECT TEST.HAKKODTE FROM TEST
WHERE (((TEST.HAKKODTE)=Format([Forms]![F_メニュー]![txtNyukinDate],"yyyymmdd")));

このクエリをダブルクリックで実行すると問題なく実行できます。


これを、VBAからレコードを参照したいと思い、
以下のように記述しました。

Dim cn As ADODB.Connection
Set cn = CurrentProject.Connection

Dim rs1 As ADODB.Recordset
Set rs1 = New ADODB.Recordset

Dim sqlstr As String

sqlstr = "SELECT * FROM test;"

rs1.Open sqlstr, cn, adOpenKeyset, adLockOptimistic


しかし、Open処理で、「1つ以上の必要なパラメータの値が設定されていません」
というエラーになってしまいます。

VBAを実行するときに、[Forms]![F_メニュー]![txtNyukinDate]に
きちんと値は入力されています。

これを実行する方法はあるでしょうか?

Access2000でフォームからの値を参照して実行するクエリを作りました。
SQLで表すと、以下のようなものです。

クエリ名:test
SELECT TEST.HAKKODTE FROM TEST
WHERE (((TEST.HAKKODTE)=Format([Forms]![F_メニュー]![txtNyukinDate],"yyyymmdd")));

このクエリをダブルクリックで実行すると問題なく実行できます。


これを、VBAからレコードを参照したいと思い、
以下のように記述しました。

Dim cn As ADODB.Connection
Set cn = CurrentProject.Connection

Dim rs1 As ADODB.Recordset
S...続きを読む

Aベストアンサー

すみません、No.6です。補足です。

当方のテストでは "yyyy/mm/dd" を使いましたが、
テーブルの「HAKKODTE」列のデータ型によっては
違うと思います。


自作関数の
Function date_return() As Date
も、
takuchantikuさんの環境では
Function date_return() As String
が正解かもしれません。
(フォールドのデータ型のご提示が無いので適当にテストしました。)

ご自分の環境に合わせて適当に読み替えてください。
上記はあくまでもテストなので、適当です。


言いたかった事は…、
パラメータクエリをレコードセットして開きたい時は…。

・フォームの値を自作関数を使って(自作関数を経由させて)
クエリの抽出条件に(言わば間接的に)セットし、
・そのクエリをVBAで、"まんま"で実行する

というやり方です。

説明不足ですみませんでした。

Q実行時エラー -2147217900 ADODBでレコードセットオープン時エラー

お世話になります!
AccessVBAで実行時エラーが出ます。

SQLステートメントが正しくありません。 DELETE INSERT PROCEDURE SELECT または UPDATEを使用してください。

と表示されます。

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset 'URLマスタ
'接続
Set cn = Application.CurrentProject.Connection
Set rs = New ADODB.Recordset

'レコードセットを取得

rs.Open "URLマスタ", cn ・・・・・・・・・・・・・ここでエラー

つい先日までエラーが出ませんでした。
久しぶりにすると、私のPCではエラーが出ます。
他のPCでは出ません。

Windows7
Access2016 Office solo
を使用しています。
よろしくお願い申し上げます。

お世話になります!
AccessVBAで実行時エラーが出ます。

SQLステートメントが正しくありません。 DELETE INSERT PROCEDURE SELECT または UPDATEを使用してください。

と表示されます。

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset 'URLマスタ
'接続
Set cn = Application.CurrentProject.Connection
Set rs = New ADODB.Recordset

'レコードセットを取得

rs.Open "URLマスタ", cn ・・・・・・・・・・・・・ここでエラー

つい先日...続きを読む

Aベストアンサー

No.1 です。

> rs.Open "URLマスタ", cn , adCmdTable
> こうでしょうか?

これでは 3番目の引数ですね。 (^^;)

rs.Open "URLマスタ", cn , , , adCmdTable

これは
rs.Open "URLマスタ", cn ,adOpenForwardOnly ,adLockReadOnly , adCmdTable
と同等です。

良く使うメソッドでも、一応ヘルプで確認することをお勧めします。
https://msdn.microsoft.com/ja-jp/library/cc364218.aspx

Q【AccessVBA】レコードセットOpen時の引数について

AccessVBAで、以下のように記述して実行したらOpen時にエラーが出てしまいました。
エラーは、「SQLステートメントが正しくありません。'DELETE'、'INSERT'、'PROCEDURE'、'SELECT'、または'UPDATE'を使用してください。」というものでした。

Dim cn As ADODB.Connection
Dim rs1 As ADODB.Recordset
Set cn = CurrentProject.Connection
Set rs1 = New ADODB.Recordset

rs1.Open "Q_F_新規契約登録_定期取引ヘッダ内容抽出", cn, adOpenForwardOnly, adLockReadOnly

いろいろと調べて、Open時の引数を一つ加えて、Openの行を以下のように書いたのですが、またエラーが出てしまいました。
エラーは、「一つ以上の必要なパラメータが設定されていません。」というものです。

rs1.Open "Q_F_新規契約登録_定期取引ヘッダ内容抽出", cn, adOpenForwardOnly, adLockReadOnly, adCmdTable

この記述はどこが間違っているのでしょうか。
足りないパラメータとは、何のことなのか、教えていただけないでしょうか。

AccessVBAで、以下のように記述して実行したらOpen時にエラーが出てしまいました。
エラーは、「SQLステートメントが正しくありません。'DELETE'、'INSERT'、'PROCEDURE'、'SELECT'、または'UPDATE'を使用してください。」というものでした。

Dim cn As ADODB.Connection
Dim rs1 As ADODB.Recordset
Set cn = CurrentProject.Connection
Set rs1 = New ADODB.Recordset

rs1.Open "Q_F_新規契約登録_定期取引ヘッダ内容抽出", cn, adOpenForwardOnly, adLockReadOnly

いろいろと調べて、Open時の引数...続きを読む

Aベストアンサー

VBA の記述には問題ありません。
問題があるのはクエリの記述です。
クエリ単独では正しく動作するんですよね。
この場合考えられるのは、
(1)パラメータクエリであること。
(2)抽出条件などで、フォームのコントロールを参照したものがあること
などです。

(1)なら、「一つ以上の必要なパラメータが設定されていません。」というエラーメッセージでピンとくるでしょうから、この先(2)として話を進めます。

例として、クエリの[ID]フィールドに
抽出条件 [Forms]![フォーム名]![ID]が書かれているものとします。

標準モジュールにフォームの[ID]の値を返すプロシージャを作成します。
例えば
  Public Function GetFormID() As Variant
    GetFormID=[Forms]![フォーム名]![ID]
  End Function
クエリの抽出条件を
  =GetFormID()
とします。

DAO に限られますが、Qerydef の Parameter を使う方法もあります。

VBA の記述には問題ありません。
問題があるのはクエリの記述です。
クエリ単独では正しく動作するんですよね。
この場合考えられるのは、
(1)パラメータクエリであること。
(2)抽出条件などで、フォームのコントロールを参照したものがあること
などです。

(1)なら、「一つ以上の必要なパラメータが設定されていません。」というエラーメッセージでピンとくるでしょうから、この先(2)として話を進めます。

例として、クエリの[ID]フィールドに
抽出条件 [Forms]![フォーム名]![ID]が書かれているも...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング