• ベストアンサー

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

質問者が選んだベストアンサー

  • ベストアンサー
  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.11

>vntValuesはvariant型で定義したのですが、 >「型が一致しません」のエラーになりました。 失礼しました。そのまま動かしてみたらエラーになりました。 #ヘルプの構文に嘘つかれた・・・ >Set vntValues = rs.GetRows(最大値) vntValues = rs.GetRows(最大値) のように、Setを消してください。 型はVariant型でOKです。

usi-iti
質問者

お礼

長々となってしまいましたが、 その都度回答を頂き、ありがとうございました。

その他の回答 (10)

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.10

>Getrowsの箇所(※の箇所)を、GetValuesにすると >コンパイルエラー「メソッドまたはデータ メンバが見つかりません」 あちゃ、またチョンボしちゃいました。すみません。 Getrowsが正解です。 >「カレントレコードがありません」のエラーが出ます。 そのままです。レコードが取得されていません。 Debug.Print SQL で、SQL文を表示してみてください。 せっかく直前に設定した年月日の条件、何にも入っていませんよね。 そのSQLですと、日付が'取得開始日'という文字列から'取得終了日'という文字列の間のものを抽出しようとします。 もちろんそんなのないのでレコードが取得できないわけです。 SQL = " SELECT * From カレンダー where 日付 between " & 取得開始日 & " and " & 取得終了日 & " order by 日付 ; " としてください。 あと、9月より大きい月、0ついちゃってますよ。 #おまけにアドバイス。 取得開始日 = 年 * 10000 + 月 * 100 + 1 だったら月の桁数気にしなくても・・・

usi-iti
質問者

お礼

回答ありがとうございます。 SQLの発行はうまくいきましたが、 SQL発行以下で質問があります。 'レコードセット取得 Set rs = db.OpenRecordset(SQL) Set vntValues = rs.GetRows(最大値) Debug.Print vntValues(0, 0) vntValuesはvariant型で定義したのですが、 「型が一致しません」のエラーになりました。 String型など他の型を使ってみましたが、ダメでした。 アドバイスや他のやり方などがありましたら、 書き込みお待ちしております。

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.9

>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しないと永久ループになるのですが? 失礼しました。チョンボしました(^^;; ないとまずいですね。 でも、上の例では要らないです。

usi-iti
質問者

お礼

回答ありがとうございます。 回答を元に、以下のソースを作りました。 'データベース接続 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)が出ました。 環境設定が間違っているのでしょうか?

回答No.8

こんにちは 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しないと永久ループになるのですが?

回答No.7

こんにちは >SQL文でBETWEEN文を使ったり、 >for文を使って1回ずつSQLを切ったりしたのですが、ダメでした。 >申し訳ありませんが、再度アドバイスを頂ければ幸いです。 ということですが、どういうSQL文なのか示していただかないと みんな答えようがないと思います。 で、ですね。私がよくやる、SQL文がうまく動かない場合のデバッグ 方法を書きますのでご自身でチャレンジしてください 1.アクセスからVBへ、SQLの貼り付け   これはやりたいことがわかっている場合、アクセスでクエリを作成し   それが正しければ、SQL文を表示しVBへコピペ。 2.VBからアクセスへ、1.の逆です   VBのデバッグウィンドでSQL文を表示させ、アクセスのクエリにコピペ ちょっとした構文のタイプミスでもSQL文のエラーになるので 正常に動くVBのSQLでアクセスにクエリ化しもそこに手を加えていく というやり方がいいでしょう

usi-iti
質問者

お礼

回答ありがとうございます。 どういう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)
回答No.6

では、途中から '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

usi-iti
質問者

お礼

回答ありがとうございました。 上記のソースを使って動かしてみたら、 取得は出来ました。 Set rs = db.OpenRecordset(SQL)の部分のSQLを、 範囲指定して複数の内容を取得し、配列の中に格納したいのですが、 SQL文でBETWEEN文を使ったり、 for文を使って1回ずつSQLを切ったりしたのですが、ダメでした。 申し訳ありませんが、再度アドバイスを頂ければ幸いです。

  • sienna
  • ベストアンサー率35% (51/145)
回答No.5

A=rs!項目名 で「A」に値が入っているはずですが。 試してみてください。

usi-iti
質問者

お礼

回答ありがとうございました。

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.4

>こけた所は、プログラムを実行しても >取得が出来ませんでした(set rsの所) ということは、エラーは発生していないということなんですけど。 >Debug Printを使うと「型が一致しません」の >エラーになりました。 あのう、rsをDebug.Printしてもオブジェクトなんで中身が見えるわけではないのですが・・・ Recordsetは、”取得したレコードの結果のセットです” もしかして、rsの中身に単純に文字列が入っているとお考えでしょうか? あと、 >Set rs = db.OpenRecordset(SQL) と、 >db.Close >rs.Close の間の処理はどうされていますか?

usi-iti
質問者

お礼

>もしかして、rsの中身に単純に文字列が入っているとお考えでしょうか? その通りです(^^; SELECT文の結果が入ってくると思っていました。 処理としてはSELECT文の結果を取得したいだけなので、 その方法例を教えて頂ければ幸いです。

  • sienna
  • ベストアンサー率35% (51/145)
回答No.3

もう既にご存知かもしれませんが、参考程度にどうぞ。 http://homepage2.nifty.com/inform/vbdb/

usi-iti
質問者

お礼

情報提供ありがとうございます。 こちらも参照したいと思います。

  • bobble
  • ベストアンサー率34% (111/323)
回答No.2

こんばんわ。 確かに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) てな感じでアクセス使ってます。 手法はいろいろあると思いますので、参考程度に・・・

usi-iti
質問者

お礼

>回答者の方へ 回答ありがとうございます。 こけた所を書いていませんでしたね。 すみませんでした。 こけた所は、プログラムを実行しても 取得が出来ませんでした(set rsの所) Debug Printを使うと「型が一致しません」の エラーになりました。 このプログラムの中には、INSERT文を使って 処理する箇所がありまして、そちらは 正常終了するのですが。SELECT文の箇所はダメでした。 引き続き、書き込みをお待ちしております。

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.1

どのように取得できないのでしょうか? 何かエラーが出ているのですか? どこまで正しく動いているのでしょうか? Recordsetの使い方はお分かりでしょうか? 補足をお願いいたします

関連するQ&A

  • DAO エクセルvbaからアクセスのレコードの件数

    DAOで、エクセルvbaからアクセスのレコードの件数を取得したいのですが Dim ac As Object Dim db As DAO.Database Dim rs As DAO.Recordset Set ac = CreateObject("Access.Application") Set db = ac.DBEngine.OpenDatabase("D:\あああ.accdb", False, True) Set rs = db.OpenRecordset("SELECT * FROM Tマスタ WHERE masterkey like '*四*';") i = rs.RecordCount Debug.Print rs("masterkey") rs.Close: Set rs = Nothing db.Close: Set db = Nothing ac.Quit: Set ac = Nothing をすると、抽出するレコードが1000件でも、必ず1が返ります。 masterkeyフィールドは文字列型です。 なぜ実際はたくさんのレコードがあるのに、1が返るのでしょうか?

  • 初歩的なSQLですが・・・

    私の環境はOS:Xp      ACCESS2000です。 宜しくお願いします 今AccessVBAで作業をしているのですが、 Dim ws As DAO.Workspace Dim DB As DAO.Database Dim rs As DAO.Recordset Dim sql As String Set ws = DBEngine.Workspaces(0) Set DB = ws.Databases(0) sql = "select MAX(銀行コード) from 銀行テーブル ;" Set rs = DB.OpenRecordset(sql) Me.合計 = rs このSQL文で銀行テーブルに入っている銀行コードの最大値を取得したいのですが、取得した後どのように記述したら「rs」から値を引っ張り出せるのでしょうか? 宜しくお願いします。

  • DAOでレコード数を取得したい(ACESSVBA)

    レコードの行数は複数あるのに --------------------------------------------------------- Sub あ() Dim db As DAO.Database Dim rs As DAO.Recordset Set db = CurrentDb Set rs = db.OpenRecordset("T_test", dbOpenDynaset) MsgBox rs.RecordCount Set rs = Nothing Set db = Nothing End Sub --------------------------------------------------------- これでレコード数を取得しようとすると1がかえるのですが なぜレコードの行数を取得できないのでしょうか?

  • Access VBA 添付型フィールド

    Access VBAで添付型フィールドからファイル名を取りだしたいのですが、どのようにすればいいでしょうか? Private Sub Sample() Dim DB As DAO.Database Dim RS As DAO.Recordset Dim SQL As String   Set DB = CurrentDb SQL_1 = "SELECT * FROM ボランティア情報 ORDER BY 分野 & 団体名読み;" Set RS = DB.OpenRecordset(SQL_1, dbOpenDynaset) With RS   Do While Not .EOF   MsgBox (!写真.FileName)  ←ここでエラーが出ます。 .   MoveNext   Loop End With RS.Close Set RS = Nothing Set MDB = Nothing End Sub

  • DAOでODBC経由のRDBに接続し、SQLでアクセスしたい。

    Dim ws As DAO.Workspace, db As DAO.Database Dim rs As DAO.Recordset ' デフォルトのワークスペースを定義する Set ws = DBEngine.Workspaces(0) ' ODBC接続文字列を指定してデータベースを開く Set db = ws.OpenDatabase("", False, False, _ "DSN=SQL_K;ODBC;Driver={SQK_K};" & _ "SERVER=(local);DATABASE=pubs;" & _ "UID=*****;PWD=*****;" ' SQLステートメントを指定してレコードセットを作成する Set rs = db.OpenRecordset("select * from TWSQLK1",dbOpenDynaset, dbSeeChanges)   このレコードセットは正常に行きますが   直接SQLを記述する方法が、わかりません   

  • SQLSERVERからデータを取得する方法

    SQLSERVERに商品テーブルを作り ACCESSにローカルテーブル(下記の例では入力テーブル)を 作りました。 ACCESS VBAで ACCESSのローカルテーブルを1件ずつ読み SQLSERVERの商品テーブルを検索したいのですが 下記の例 どちらが処理スピードが速いのですか? なお下記以外にも処理スピードが速い方法が あったら教えてください。 ●例1 Dim db As DATABASE Dim rs As Recordset   dim rt as Recordset Set db = CurrentDb Set rt = db.OpenRecordset("入力テーブル", dbOpenDynaset) sql = "SELECT 商品名 FROM 商品テーブル " sql = sql & "where 商品ID = '" & rt![商品ID] & "'" Set rs = db.OpenRecordset(sql) If rs.RecordCount = 0 Then MsgBox "NG" Else MsgBox rs![商品名] End If ●例2 Dim db As DATABASE Dim rs As Recordset   dim rt as Recordset Set db = CurrentDb Set rt = db.OpenRecordset("入力テーブル", dbOpenDynaset) Set rs = db.OpenRecordset("商品テーブル", dbOpenDynaset) rs.FindFirst "商品CD = '" & rt![商品CD] & "'" If rs.NoMatch Then MsgBox "NG" Else MsgBox rs![商品名] End If よろしくお願いします。

  • 空欄を含む項目のレコードセット

    Access 2003 DAO.Recordsetにてデータを取得しようと思うのですが テーブル項目に空欄がある場合はどのように書けばよろしいのでしょうか? Dim DB As DAO.Database Dim RS As DAO.Recordset Set DB = CurrentDb Set RS = daoDB.OpenRecordset("Aテーブル", dbOpenDynaset) RS.AddNew daoRS!ああ ああ = xx RS!Update ・・・ とするとエラーになります。 項目名"ああ ああ"はどのように書けばいいのでしょうか? よろしくおねがいします。

  • ACCESSの SELECT SUM

    SELECT SUMを 計算させると ゼロしか 出てきません。 どこが悪いのでしょうか?  日付         出金       氏名 2012/12/10      540      安田 2012/12/10      1020      斉藤 2012/12/10       970      TOM 2012/12/11      650      池田  2012/12/11     2010      南 2012/12/12      350      林田 2012/12/12     1200      加藤 のようなテーブルがあり Private Sub コマンド_click() Dim Db As Database Dim SQL As String Dim rs As Recordset Dim gokei As Long Set Db = CurrentDb SQL = "SELECT Sum(出金) as gokei FROM テーブル  WHERE 日付= #" & [Forms]![フォームアルファ]![テキスト] & "# " Set rs = Db.OpenRecordset(SQL) MsgBox gokei End Sub を フォームアルファに 新しく作ったコマンドボタンのクリック時に 書きました。 これを テキストの日付を変えておいて いろいろ試しても ゼロのメッセージしか出ません。 WHERE以下が 間違っていないか 試しに Private Sub コマンド_click() Dim Db As Database Dim SQL As String Dim rs As Recordset Dim Count As Long Set Db = CurrentDb SQL = "SELECT (出金)  FROM テーブル  WHERE 日付= #" & [Forms]![フォームアルファ]![テキスト] & "# " Set rs = Db.OpenRecordset(SQL) If rs.EOF Then Count = 0 Else rs.MoveLast Count = rs.RecordCount End If MsgBox Count End Sub を 実行すると ちゃんと 正しいレコード数が 表示されます。 「出金」のデータ型は 長整数になっています。 どこが 悪いのでしょうか? 目的は 指定した日付の 出金の合計を取り出したいのです。 . . .

  • DAOでのコードをADOへ書き直し

    Access2003、WinXPです。 レコードセットの取得関係をDAOで書いていたのですが ADOに途中から変更しました。 変数宣言を Public db As DAO.Database ⇒Public cn As ADODB.Connection Public rs As DAO.Recordset ⇒Public rs As ADODB.Recordset Public Fld As DAO.field  ⇒Public Fld As ADODB.field レコードセット取得を Set db = CurrentDb      Set rs = db.OpenRecordset(strSQL) ↓ Set cn = CurrentProject.Connection Set rs = New ADODB.Recordset rs.Open strSQL, cn レコードセット クローズを Set rs = Nothing Set db = Nothing ↓ rs.Close: Set rs = Nothing cn.Close: Set cn = Nothing としました。今のところ動いているようですが、 何か勘違い、気をつけないといけない事等ありますでしょうか・・・?

  • accessからsqlserverにアップサイジングしましたが,テーブ

    accessからsqlserverにアップサイジングしましたが,テーブルにデータを入力出来なくなってしまいました。 Dim rs As DAO.Recordset Dim db As DAO.Database Set db = CurrentDb() Set rs = db.OpenRecordset("確認用", dbOpenDynaset) rs.AddNew rs!品番 = Me.品番 rs.Update 上記のようにDAOを介してテーブルにデータを入れていました。 アップサイジングする前は、問題なかったのですが、どういったことが原因になりますでしょうか?

専門家に質問してみよう