• 締切済み

クエリ表示と、ADOで抽出したレコードセットが違う

Accessで作ったクエリで表示されるデータと、VBAでSQLを組んでそのクエリから抽出したデータが異なるので困っています。 ちょっと言葉では説明しにくいので表で説明します。 元となるテーブル(t_test)がたとえば以下のようになっているとします。 t_test 顧客id  商品id 1      A-1 2      A-2 3      B-1 4      A-1 これを元に、以下のようなクエリ(q_test)を作ります。 q_test 顧客id  商品id  式1: IIf([商品id] Like "A*",1,0) 1      A-1    1 2      A-2    1 3      B-1    0 4      A-1    1 VBAで以下のようなSQLを実行すると、なぜか式1の値が全て0となります。 sql = "SELECT * FROM q_test" 1      A-1    0 2      A-2    0 3      B-1    0 4      A-1    0 式1でLIKEを使っていることが原因なのか、 IIf([商品id] = "A-1",1,0) とかだと、クエリとSQLの結果に違いはありません。 IIfだけでなくSwitchを使った場合も同様(LIKEだとおかしい、=だと平気)でした。 ちなみに、Accessのバージョンは2003、VBAで使っているレコードセットはADODBです。 (今確認したところ、DAOでは問題なくできました。) 冒頭で、困っていると書きましたが、これを回避する方法はいくつか思いついていますので、 別の方法を教えていただきたいわけではなく、単純になぜこのようなことが起きるのかが知りたいです。 是非よろしくお願いします。

みんなの回答

  • 30246kiku
  • ベストアンサー率73% (370/504)
回答No.3

> Like "A*" ADO では Like "A%" になると思います。 こういうことではなく、なぜかっていうことになりますか・・・ Access 2003 / 2007 で確認してみました。 Private Sub CheckDAO(sS As String, sSql As String)   Dim rs As DAO.Recordset   Set rs = CurrentDb.OpenRecordset(sSql)   While (Not rs.EOF)     Debug.Print "DAO" & sS & " : ",     Debug.Print "顧客id=" & rs("顧客id"),     Debug.Print "商品id=" & rs("商品id"),     Debug.Print "式1=" & rs("式1")     rs.MoveNext   Wend   rs.Close   Set rs = Nothing End Sub Private Sub CheckADO(sS As String, sSql As String)   Dim rs As New ADODB.Recordset   rs.Source = sSql   rs.Open , CurrentProject.Connection, adOpenForwardOnly, adLockReadOnly   While (Not rs.EOF)     Debug.Print "ADO" & sS & " : ",     Debug.Print "顧客id=" & rs("顧客id"),     Debug.Print "商品id=" & rs("商品id"),     Debug.Print "式1=" & rs("式1")     rs.MoveNext   Wend   rs.Close End Sub Public Sub test21()   Const CSQL As String = "SELECT * FROM q_test;"   Const CSQL2 As String = "SELECT * FROM q_test2;"   Call CheckDAO("", CSQL)   Call CheckADO("", CSQL)   Call CheckDAO("2", CSQL2)   Call CheckADO("2", CSQL2) End Sub クエリ q_test2 は、 A* を A% に変更しただけのもので、 test21 を実行した結果は以下 DAO : 顧客id=1 商品id=A-1 式1=1 DAO : 顧客id=2 商品id=A-2 式1=1 DAO : 顧客id=3 商品id=B-1 式1=0 DAO : 顧客id=4 商品id=A-1 式1=1 ADO : 顧客id=1 商品id=A-1 式1=0 ADO : 顧客id=2 商品id=A-2 式1=0 ADO : 顧客id=3 商品id=B-1 式1=0 ADO : 顧客id=4 商品id=A-1 式1=0 DAO2 : 顧客id=1 商品id=A-1 式1=0 DAO2 : 顧客id=2 商品id=A-2 式1=0 DAO2 : 顧客id=3 商品id=B-1 式1=0 DAO2 : 顧客id=4 商品id=A-1 式1=0 ADO2 : 顧客id=1 商品id=A-1 式1=1 ADO2 : 顧客id=2 商品id=A-2 式1=1 ADO2 : 顧客id=3 商品id=B-1 式1=0 ADO2 : 顧客id=4 商品id=A-1 式1=1 クエリを直接開いた時の表示は、 「q_test」 顧客id 商品id  式1 1    A-1    1 2    A-2    1 3    B-1    0 4    A-1    1 「q_test2」 顧客id 商品id  式1 1    A-1    0 2    A-2    0 3    B-1    0 4    A-1    0 ANSI-92 / ANSI-89 ・・・なんちゃらがあり http://office.microsoft.com/ja-jp/access-help/HP003070483.aspx (DAO / ADO の違いについてのお話ではないと思いますが・・・) ツール→オプションを表示し、 「テーブル/クエリ」のSQLサーバー互換構文(ANSI 92)の 「このデータベース」のチェックを入れ、クエリを直接開くと結果は逆になります。 でも、DAO / ADO での取得(test21 の実行)結果は変わりません。 この辺の動きを説明されているのが以下でしょうか(拡大解釈かも) ADOとDAOを使用したwhere句内の文字列検索にて、*と%の動きの違い http://www.nurs.or.jp/~ppoy/access/access/acM012.html クエリ名で指定しても、その内容の全ての解釈は統一された、 という事になるのでしょうか。(私の解釈ですけど) うそかも・・・ 自己責任にて解釈してください。

  • imogasi
  • ベストアンサー率27% (4737/17069)
回答No.2

クエリのデザイングリッドのところでSQLビューを表示すると、SQL文がどういうようになっているか分かるのではないですか。 <--ここがミソ そのSQL文を間違いなく写して Sub test15() Dim dbs As DAO.Database Dim rs As DAO.Recordset Set dbs = CurrentDb Set rs = dbs.OpenRecordset("select 氏名,住所 from 社員3") rs.MoveFirst Do Until rs.EOF MsgBox rs!住所 rs.MoveNext Loop rs.Close: Set rs = Nothing dbs.Close: Set dbs = Nothing End Sub でselect 氏名,住所 from 社員3の部分を変えて そのSQL文で実行して何かヒントが得られないですか。 (ちなみに上記は私のテストデータでは動きます。) ADOでやるならSQL文で開くコードでやってみるとか。

  • jcctaira
  • ベストアンサー率58% (119/204)
回答No.1

rodoniさん はじめまして。 私も同じようにAccess2003,EXCEL2003で作成し試してみました。 結論か言うと、ADOでもDAOも結果が同じでした。 ※下記のプログラムと結果参照 参照設定(ADOのバージョン等)とか環境とか何か違いがあるのでしょうかね? ※DAOは3.6,ADOは6.0で確認 あまりお役に立てず、申し訳ありません。 以下、サンプルと結果です。 【DAO ソース】 Sub DAO_Access() Dim objDtbs As DAO.Database Dim objRcrd As DAO.Recordset Set objDtbs = OpenDatabase(ThisWorkbook.Path & "\" & "test.mdb") Set objRcrd = objDtbs.OpenRecordset("SELECT * FROM q_test", dbOpenForwardOnly) With objRcrd  Do While Not (objRcrd.EOF)   Debug.Print "顧客id="; objRcrd.Fields("顧客id"),   Debug.Print "商品id="; objRcrd.Fields("商品id"),   Debug.Print "式1="; objRcrd.Fields("式1")   objRcrd.MoveNext  Loop End With objRcrd.Close objDtbs.Close Set objRcrd = Nothing Set objDtbs = Nothing End Sub 【DAO 結果】 顧客id=1 商品id=A-1 式1= 1 顧客id=2 商品id=A-2 式1= 1 顧客id=3 商品id=B-1 式1= 0 顧客id=4 商品id=A-1 式1= 1 【ADO ソース】 Sub ADO_Access()  Dim adoCON As New ADODB.Connection  Dim adoRS As ADODB.Recordset  adoCON.Open "Driver={Microsoft Access Driver (*.mdb)}; DBQ=" & ThisWorkbook.Path & "\" & "test.mdb"  Set adoRS = adoCON.Execute("select * from q_test")  Do While Not (adoRS.EOF)   Debug.Print "顧客id="; adoRS("顧客id"),   Debug.Print "商品id="; adoRS("商品id"),   Debug.Print "式1="; adoRS("式1")   adoRS.MoveNext  Loop  adoRS.Close  adoCON.Close  Set adoRS = Nothing  Set adoCON = Nothing End Sub 【ADO 結果】 顧客id=1 商品id=A-1 式1= 1 顧客id=2 商品id=A-2 式1= 1 顧客id=3 商品id=B-1 式1= 0 顧客id=4 商品id=A-1 式1= 1

関連するQ&A

専門家に質問してみよう