- 締切済み
クエリ表示と、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では問題なくできました。) 冒頭で、困っていると書きましたが、これを回避する方法はいくつか思いついていますので、 別の方法を教えていただきたいわけではなく、単純になぜこのようなことが起きるのかが知りたいです。 是非よろしくお願いします。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- 30246kiku
- ベストアンサー率73% (370/504)
> 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)
クエリのデザイングリッドのところで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)
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