- ベストアンサー
SELECT文を発行して、ACCESSより取得する方法
既存のプログラムを元に、 以下のようなソースを作成したのですが、 取得出来ませんでした。 参照設定やパスの設定、SQL文は正しいです。 どこがマズイのでしょうか? アドバイスをお願い致します。 Dim db As DAO.Database Dim rs As DAO.Recordset Dim SQL As String 'データベース接続 Set db = OpenDatabase("DBのパス") 'データ検索SQL SQL = "" SQL = " SELECT文 " 'ACCESSより取得 Set rs = db.OpenRecordset(SQL) db.Close rs.Close
- みんなの回答 (11)
- 専門家の回答
質問者が選んだベストアンサー
>vntValuesはvariant型で定義したのですが、 >「型が一致しません」のエラーになりました。 失礼しました。そのまま動かしてみたらエラーになりました。 #ヘルプの構文に嘘つかれた・・・ >Set vntValues = rs.GetRows(最大値) vntValues = rs.GetRows(最大値) のように、Setを消してください。 型はVariant型でOKです。
その他の回答 (10)
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>Getrowsの箇所(※の箇所)を、GetValuesにすると >コンパイルエラー「メソッドまたはデータ メンバが見つかりません」 あちゃ、またチョンボしちゃいました。すみません。 Getrowsが正解です。 >「カレントレコードがありません」のエラーが出ます。 そのままです。レコードが取得されていません。 Debug.Print SQL で、SQL文を表示してみてください。 せっかく直前に設定した年月日の条件、何にも入っていませんよね。 そのSQLですと、日付が'取得開始日'という文字列から'取得終了日'という文字列の間のものを抽出しようとします。 もちろんそんなのないのでレコードが取得できないわけです。 SQL = " SELECT * From カレンダー where 日付 between " & 取得開始日 & " and " & 取得終了日 & " order by 日付 ; " としてください。 あと、9月より大きい月、0ついちゃってますよ。 #おまけにアドバイス。 取得開始日 = 年 * 10000 + 月 * 100 + 1 だったら月の桁数気にしなくても・・・
お礼
回答ありがとうございます。 SQLの発行はうまくいきましたが、 SQL発行以下で質問があります。 'レコードセット取得 Set rs = db.OpenRecordset(SQL) Set vntValues = rs.GetRows(最大値) Debug.Print vntValues(0, 0) vntValuesはvariant型で定義したのですが、 「型が一致しません」のエラーになりました。 String型など他の型を使ってみましたが、ダメでした。 アドバイスや他のやり方などがありましたら、 書き込みお待ちしております。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>SQL文を書くと、 > >SELEST * FROM カレンダー >WHERE 日付 BETWEEN YYYYMM+01 AND YYYYMM+その月の最終日 #7の方の他に、あと ORDER BY 日付 を入れたほうがいいんでは? >取得したその月の日付と休日状況を、配列なり変数なりに >入れるということです。 ということであれば、DAOを使っていることですし、 GwrRowsメソッドを使えば一発です。 'ACCESSより取得 Set rs = db.OpenRecordset(SQL) Dim vntValues As Variant Set vntValues = rs.GetValues(31) '最高で31行 Debug.Print vntValues(0, 0) '最初の行の最初の列の値 rs.Close db.Close vntValuesは、レコードがあれば2次元の配列になっています。 >う~ん。一つ気になったのがtaka_tetsuさんのNo6の回答の中で >loopの前に"rs.MoveNext" が抜けているように思います。 > >これはどうですか?MoveNextしないと永久ループになるのですが? 失礼しました。チョンボしました(^^;; ないとまずいですね。 でも、上の例では要らないです。
お礼
回答ありがとうございます。 回答を元に、以下のソースを作りました。 'データベース接続 Set db = OpenDatabase("DBのパス", True) 'データ検索SQL SQL = "" If 月 <= 9 Then 取得開始日 = 年 & 0 & 月 & 0 & 1 取得終了日 = 年 & 0 & 月 & 表示月の最終日 End If If 月 > 9 Then 取得開始日 = 年 & 0 & 月 & 0 & 1 取得終了日 = 年 & 0 & 月 & 表示月の最終日 End If SQL = " SELECT * From カレンダー where 日付 _ between '取得開始日' and '取得終了日 ' order by 日付 ; " 'レコードセット取得 Set rs = db.OpenRecordset(SQL) Dim vntValues As Variant Set vntValues = rs.Getrows(表示月の最終日)※ Debug.Print vntValues(0, 0) rs.Close db.Close End Select これを実行すると、 「カレントレコードがありません」のエラーが出ます。 ヘルプを表示しても参照出来ませんでした。 DBもデータもSQLもチェックしましたが、ダメでした。 Getrowsの箇所(※の箇所)を、GetValuesにすると コンパイルエラー「メソッドまたはデータ メンバが見つかりません」 (Error 461)が出ました。 環境設定が間違っているのでしょうか?
- ats8181oyaji
- ベストアンサー率38% (94/244)
こんにちは No7のものです >SELEST * FROM カレンダー >WHERE 日付 BETWEEN YYYYMM+01 AND YYYYMM+その月の最終日 >SELEST * FROM カレンダー >WHERE 日付>= YYYYMM+01 AND 日付=< YYYYMM+その月の最終日 了解です。YYYYMM+01とYYYYMM+その月の最終日の部分というのは 200210+01で20021001となっているから ↓正解ということですよね。 >日付の文字列編集はOKでした。 このまま数値だと200210+01で200211となりそうですが・・・ >また、ACCESSでSQL文のチェックも行いました。 ちゃんとクエリを実行されましたか? その時結果のシートも表示されましたか? それでる駄目ということは う~ん。一つ気になったのがtaka_tetsuさんのNo6の回答の中で loopの前に"rs.MoveNext" が抜けているように思います。 これはどうですか?MoveNextしないと永久ループになるのですが?
- ats8181oyaji
- ベストアンサー率38% (94/244)
こんにちは >SQL文でBETWEEN文を使ったり、 >for文を使って1回ずつSQLを切ったりしたのですが、ダメでした。 >申し訳ありませんが、再度アドバイスを頂ければ幸いです。 ということですが、どういうSQL文なのか示していただかないと みんな答えようがないと思います。 で、ですね。私がよくやる、SQL文がうまく動かない場合のデバッグ 方法を書きますのでご自身でチャレンジしてください 1.アクセスからVBへ、SQLの貼り付け これはやりたいことがわかっている場合、アクセスでクエリを作成し それが正しければ、SQL文を表示しVBへコピペ。 2.VBからアクセスへ、1.の逆です VBのデバッグウィンドでSQL文を表示させ、アクセスのクエリにコピペ ちょっとした構文のタイプミスでもSQL文のエラーになるので 正常に動くVBのSQLでアクセスにクエリ化しもそこに手を加えていく というやり方がいいでしょう
お礼
回答ありがとうございます。 どういうSQL文かと言うと カレンダーと言うテーブルがありまして、 指定した年月分の内容を取得するものです。 カレンダーの構成はこうなっています。 ・日付(数値型8桁、YYYYMMDD) ・休日(YES/NO型、休日はオン) 例えば2002年xx月分のデータを取得するとしたら、 2002xx01TRUE, 2002xx02TRUE…といったように 取得したその月の日付と休日状況を、配列なり変数なりに 入れるということです。 SQL文を書くと、 SELEST * FROM カレンダー WHERE 日付 BETWEEN YYYYMM+01 AND YYYYMM+その月の最終日 又は SELEST * FROM カレンダー WHERE 日付>= YYYYMM+01 AND 日付=< YYYYMM+その月の最終日 です。 日付の文字列編集はOKでした。 また、ACCESSでSQL文のチェックも行いました。 再度アドバイス等頂ければ幸いです。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
では、途中から 'ACCESSより取得 Set rs = db.OpenRecordset(SQL) '最後のレコードまで取得 Do While rs.EOF = False '下の3種類のどの方法でもかまいません。 '速度的には下になるほど遅くなります Debug.Print rs(0) 'SELECT文中の、一番左の項目 Debug.Print rs![フィールド名] Debug.Print rs("フィールド名") Loop 'クローズ(後から開いたものを先に閉じましょう) rs.Close db.Close
お礼
回答ありがとうございました。 上記のソースを使って動かしてみたら、 取得は出来ました。 Set rs = db.OpenRecordset(SQL)の部分のSQLを、 範囲指定して複数の内容を取得し、配列の中に格納したいのですが、 SQL文でBETWEEN文を使ったり、 for文を使って1回ずつSQLを切ったりしたのですが、ダメでした。 申し訳ありませんが、再度アドバイスを頂ければ幸いです。
- sienna
- ベストアンサー率35% (51/145)
A=rs!項目名 で「A」に値が入っているはずですが。 試してみてください。
お礼
回答ありがとうございました。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>こけた所は、プログラムを実行しても >取得が出来ませんでした(set rsの所) ということは、エラーは発生していないということなんですけど。 >Debug Printを使うと「型が一致しません」の >エラーになりました。 あのう、rsをDebug.Printしてもオブジェクトなんで中身が見えるわけではないのですが・・・ Recordsetは、”取得したレコードの結果のセットです” もしかして、rsの中身に単純に文字列が入っているとお考えでしょうか? あと、 >Set rs = db.OpenRecordset(SQL) と、 >db.Close >rs.Close の間の処理はどうされていますか?
お礼
>もしかして、rsの中身に単純に文字列が入っているとお考えでしょうか? その通りです(^^; SELECT文の結果が入ってくると思っていました。 処理としてはSELECT文の結果を取得したいだけなので、 その方法例を教えて頂ければ幸いです。
- sienna
- ベストアンサー率35% (51/145)
もう既にご存知かもしれませんが、参考程度にどうぞ。 http://homepage2.nifty.com/inform/vbdb/
お礼
情報提供ありがとうございます。 こちらも参照したいと思います。
- bobble
- ベストアンサー率34% (111/323)
こんばんわ。 確かにtaka_tetsuさんのおっしゃる通り、どこでこけてるのかわからないです。 ので、私なら dim ws as workspace dim db as database dim rs as recordset set ws = dbEngine.workspace(0) set db = ws.opendatabase("dbpath",true) set rs = db.openrecordset("select・・・",dbopendynaset) てな感じでアクセス使ってます。 手法はいろいろあると思いますので、参考程度に・・・
お礼
>回答者の方へ 回答ありがとうございます。 こけた所を書いていませんでしたね。 すみませんでした。 こけた所は、プログラムを実行しても 取得が出来ませんでした(set rsの所) Debug Printを使うと「型が一致しません」の エラーになりました。 このプログラムの中には、INSERT文を使って 処理する箇所がありまして、そちらは 正常終了するのですが。SELECT文の箇所はダメでした。 引き続き、書き込みをお待ちしております。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
どのように取得できないのでしょうか? 何かエラーが出ているのですか? どこまで正しく動いているのでしょうか? Recordsetの使い方はお分かりでしょうか? 補足をお願いいたします
お礼
長々となってしまいましたが、 その都度回答を頂き、ありがとうございました。