エクセルからSQLサーバー接続 日付範囲Where

このQ&Aのポイント
  • エクセルからSQLServer2012へ接続しデータを抽出したいのですが、「'>'付近に不適切な構文があります。」のエラーでうまく抽出できません。
  • Where句のコーディング方法が間違っているとは思うのですが、どこをどう直せばよいかが分からず困っています。
  • 私だけが使うのならば、AccessクエリをVBAでたたくのですが、他のスタッフも使いAccessがイントールされていないため、エクセルで処理出来ればと考えております。
回答を見る
  • ベストアンサー

エクセルからSQLサーバー接続 日付範囲Where

エクセルから、SQLServer2012へ接続しデータを抽出したいのですが、「'>'付近に不適切な構文があります。」のエラーでうまく抽出できません。 テーブル:IncRevDat カラム ・利用日 ・申込先名 ・利用数 ・計上人員 ・計上料金 実行したいSQL文 select 利用日, 利用数, 計上人員, 計上料金 From IncRevDat Where 利用日 >= セルB3の値 And セルD3の値 Order By 利用日 Public Sub GetData() Dim con As New ADODB.Connection Dim connectionString As String Dim sDBSever As String Dim sDBName As String Dim sLoginID As String Dim sPassWD As String sDBSever = "サーバーホスト名" sDBName = "DB名" sLoginID = "ユーザー名" sPassWD = "パスワード" '接続文字列 connectionString = "Provider=Sqloledb;Data Source=" & sDBSever _ & ";Initial Catalog=" & sDBName _ & ";Connect Timeout=15" _ & ";user id=" & sLoginID _ & ";password=" & sPassWD _ & "" On Error GoTo Err_DBConnectOpen '接続 con.Open connectionString 'SQL文を実行(RecordSETで受け取ります) Dim sql As String 'SQL文 sql = "" sql = sql & " SELECT 利用日,,利用数,計上人員,計上室料" & vbCrLf sql = sql & " FROM IncRevDat" & vbCrLf sql = sql & " WHERE 宿泊日 >= " & Cells(3, 2) & "" sql = sql & " AND <= " & Cells(3, 4) & "" & vbCrLf sql = sql & " ORDER BY 利用日" & vbCrLf Set rs = con.Execute(sql) Debug.Print sql 'セルをクリア Range(Range("A4"), ActiveSheet.Cells.SpecialCells(xlLastCell).Address).Select Selection.ClearContents '結果をセルに書き込む Dim i As Long Dim j As Long 'フィールド名をセルに書き込む If rs.EOF Then Cells(5, 1) = "情報が有りません。" Else rs.MoveFirst i = 5 For j = 1 To rs.Fields.Count Cells(i, j) = rs.Fields(j - 1).Name Next i = i + 1 Do Until rs.EOF = True For j = 1 To rs.Fields.Count Cells(i, j) = rs.Fields(j - 1).Value Next rs.MoveNext i = i + 1 Loop End If rs.Close: Set rs = Nothing '接続を閉じる con.Close: Set con = Nothing Exit Sub 'エラー処理 Err_DBConnectOpen: MsgBox Err.Description Debug.Print sql 'Connectionの状態を確認し、クローズ If con.State <> ADODB.adStateClosed Then con.Close End If Set con = Nothing End Sub Where句の部分をコメントアウトし、全出力すると正常にデータを読取ってくれます。 Debug.Printの内容 SELECT 利用日,利用数,計上人員,計上料金 FROM IncRevDat WHERE 宿泊日 >= 2012/08/01 AND <= 2012/08/31 ORDER BY 宿泊日 私だけが使うのならば、AccessクエリをVBAでたたくのですが、他のスタッフも使いAccessがイントールされていないため、エクセルで処理出来ればと考えております。 Where句のコーディング方法が間違っているとは思うのですが、どこをどう直せばよいかが分からず困っています。 間違いをお教え頂けましたら幸いです。 ※内容に間違いが有りましたので、数回質問を削除し、再質問しております。 前の質問を見て頂いた方には、ご迷惑をお掛けしてすいませんでした。

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

  • ベストアンサー
回答No.3

ごめん。 sql = "" sql = sql & " SELECT 利用日,利用数,計上人員,計上室料" & vbCrLf sql = sql & " FROM IncRevDat" & vbCrLf sql = sql & " WHERE 宿泊日 >= '" & Cells(3, 2) & "'" sql = sql & " AND 宿泊日<= '" & Cells(3, 4) & "'" & vbCrLf sql = sql & " ORDER BY 利用日;" rs.open sql,con Debug.Print sql だと・・・? >ユーザー名とパスワードを埋め込まなくてよい方法が有るのでしょうか? これをやれば鉄壁の防御・・・というのがあればこちらが知りたいです! 小手先ですが、 Excel2010では、xlsmファイルのBookにもパスワードを設定すると ファイルの拡張子を ZIP に変えて中身の確認・・・が出来なくなります。 どこまで有効かはわかりませんが『出来心で』という人には役立つかと思います。

sujinosuke00
質問者

お礼

度々の回答ありがとうございます。 お教え頂いた、コーディングで目的が達成できました。 原因については、時間のある時に見比べて今後tの参考にしたいと思います。 あわせて、セキュリティ設定についてもお教え頂きありがとうございました。

その他の回答 (2)

回答No.2

'SQL文 sql = "" sql = sql & " SELECT 利用日,利用数,計上人員,計上室料" & vbCrLf sql = sql & " FROM IncRevDat" & vbCrLf sql = sql & " WHERE 宿泊日 >= #" & Cells(3, 2) & "#" sql = sql & " AND 宿泊日<= #" & Cells(3, 4) & "#" & vbCrLf sql = sql & " ORDER BY 利用日;" rs.open sql,con Debug.Print sql では。 あと今回は問題はならないだろうけど Do Until rs.EOF = True For j = 1 To rs.Fields.Count Cells(i, j) = rs.Fields(j - 1).Value Next rs.MoveNext i = i + 1 Loop だと電話番号などでは前ゼロがクリアされてしまうので cells(i,1).copyfromrecordset rs とした方がデータ型通りに入るので良いかも。 さらに余計なお世話かもしれませんが ユーザー名・パスワードを埋め込んでいるのは不安です。 たとえVBAProjectの保護を行う予定であっても。

sujinosuke00
質問者

お礼

#1のお礼にも記載しましたが、質問内容に間違いが有りました。申し訳ありません。 あわせて、回答頂きありがとうございます。 >だと電話番号などでは前ゼロがクリアされてしまうので >cells(i,1).copyfromrecordset rs >とした方がデータ型通りに入るので良いかも。 全く意識してませんでした、今後の参考にさせて頂きます。 お教え頂いたとおり、Where句の部分を下記の通り書いた所 sql = sql & " WHERE 宿泊日 >= #" & Cells(3, 2) & "#" & vbCrLf sql = sql & " AND 宿泊日<= #" & Cells(3, 4) & "#" & vbCrLf エラーメッセージに、「'#'付近に不適切な構文があります。」 と表示され、SQL NGになります。 確かに、Accessでは、日付型にするためには"#"でくくる必要が有りますが、エクセルでも同じと考えてよろしいでしょうか? また、その場合の「'」、「"」のくくり方だと思うのですが、どう書けばうまく抽出出来ますでしょうか? ちなみに、debug.print sqlの値は SELECT i通番,宿泊日, 泊数,泊目,申込先名,総室数,計上人員,計上室料 FROM IncRebDat WHERE 宿泊日 >= 2012/08/01 AND 宿泊日<= 2012/12/31 ORDER BY 宿泊日 となっております、「#」でくくられてません。 多分初歩的な「'」や「"」の意味合いを理解していないのだと思いますが、VBAは難しいです。 余談ですが、ユーザー名とパスワードを埋め込まなくてよい方法が有るのでしょうか? 今回は、SQLSERVER側に接続用の閲覧ユーザーにしてますので、問題は無いと思いますが、書込み権限を付与した場合には大きな問題になりそうなので、あつかましいお願いですがお教え頂けたら幸いです。 また、VBAProjectの保護についても、全く知りませんでした。 VBAは奥が深いですね。。。 上記については、時間のある時に調べてみます。 アドバイス頂きありがとうございました。

sujinosuke00
質問者

補足

すいません、また内容が間違ってました。 debug.print sqlの値は、 SELECT i通番,宿泊日, 泊数,泊目,申込先名,総室数,計上人員,計上室料 FROM IncRebDat WHERE 宿泊日 >= #2012/08/01# AND 宿泊日<= #2012/12/31# ORDER BY 宿泊日 で、ちゃんと「#」でくくられてました。

  • maiko0318
  • ベストアンサー率21% (1483/6970)
回答No.1

構文が違います。 Where 利用日 >= セルB3の値 And セルD3の値 間を取りたいなら Where 利用日 between セルB3の値 And セルD3の値 別の条件なら Where 利用日 >= セルB3の値 And 比較したいカラム = セルD3の値 です。

sujinosuke00
質問者

お礼

maiko0318様 回答ありがとうございます。 すいません、質問内容に誤りがありました。 もう、旅行業界がバレバレですので正確に記載します。 実行したいSQLのWhere句が where 宿泊日 >= セルB3の値 And <= セルD4の値 これをVBA的に書く方法が良くわかりません。 お教え頂いた内容を書くと sql = sql & " WHERE 宿泊日 between " & Cells(3, 2) & "" sql = sql & " AND " & Cells(3, 4) & "" & vbCrLf debug.print sqlが SELECT i通番,宿泊日, 泊数,泊目,申込先名,総室数,計上人員,計上室料 FROM IncRebDat WHERE 宿泊日 between 2012/08/01 AND 2012/12/31 ORDER BY 宿泊日 SQLとしては通っていると思うのですが、シートには、「情報が有りません」とRecoresetにデータが無いとされます。 または、 sql = sql & " WHERE 宿泊日 >= " & Cells(3, 2) & "" sql = sql & " AND 宿泊日<= " & Cells(3, 4) & "" & vbCrLf と書くと結果は同じで、debug.print sql の値は、 SELECT i通番,宿泊日, 泊数,泊目,申込先名,総室数,計上人員,計上室料 FROM IncRebDat WHERE 宿泊日 >= 2012/08/01 AND 宿泊日<= 2012/12/31 ORDER BY 宿泊日 やはり、シートには、何も書かれません。 エクセルのVBAは難しいです。

関連するQ&A

  • ADOでエクセルからSQL Serverへデータを移行するには

    エクセルvbaのADOを使って、 SQL Serverの「test」という名のデータベースの「Table_1」に 新規レコードを追加する事はできますか? エクセルからアクセスには Sub test() Dim データベース名 As String Dim cn As ADODB.Connection Dim rs As ADODB.Recordset Set cn = New ADODB.Connection Set rs = New ADODB.Recordset cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & データベース名 rs.Open "Tテーブル1", cn, adOpenKeyset, adLockOptimistic rs.AddNew rs.Fields("フィールド1") = データ rs.Update rs.Close cn.Close Set rs = Nothing Set cn = Nothing End Sub で移行しています。 これをエクセルからSQL Serverへ移行させるにはどうすればいいのでしょうか? よろしくお願いします。

  • SQL Serverへの接続について

    すみませんが、どなたか教えてください。 Access2000のプロジェクトからADOを使って、OLE-DB経由でSQL Serverに接続しようとしています。 SQLステートメントを指定して、レコードセットを作成したいのですが、 以下のSQL分のテーブル名のSYARMに対して、オブジェクト名SYARMは無効ですというメッセージが出てきます。どこが問題になっているのでしょうか? Dim cn As New ADODB.Connection Dim rs As New ADODB.Recordset cn.Open "Provider=SQLOLEDB;" & "datasource=(local);" & "Integrated Security=SSPI;" rs.Open "SELECT * FROM SYARM WHERE KANNO=12345;", cn, adOpenKeyset, adLockOptimistic rs.Close cn.Close Set rs = Nothing Set cn = Nothing

  • Access ADP テーブル 説明欄を取得したい

    大変お世話になります。 Access 2007 ADPファイルにて SQL Server 2005 との接続でのシステムを運用しています。 テーブル情報のフィールド説明欄(Description) の値の一覧を取得したいと思い下記のプログラムを作ってみたのですが、Descriptionの値以外はおおむね取得できるのですが、説明欄のところがすべてエラーになってしまい説明欄の Description の取得ができません。 格納場所か、プロパティの参照の仕方が原因だと思うのですが、解決できません。 テーブルの説明欄(Description)値の参照の仕方をご存じの方がいらっしゃいましたら何卒ご教授いただければと存じます。 よろしくお願いいたします。     Dim Cn As ADODB.Connection     Dim Rs As New ADODB.Recordset     Dim SQL As String     Dim i As Integer          Set Cn = CurrentProject.Connection          SQL = " SELECT dbo.テーブルA.* "     SQL = SQL & " FROM dbo.テーブルA"     Dim MyDB As New ADOX.Catalog     Dim MyTable As ADOX.Table     Dim MyField As ADOX.Column     MyDB.ActiveConnection = CurrentProject.Connection     Set MyTable = MyDB.Tables("テーブルA")          Rs.Open SQL, Cn, adOpenForwardOnly, adLockReadOnly         For i = 0 To Rs.Fields.Count - 1             MsgBox Rs.Fields(i).Name                                     'MsgBox MyTable.Columns(Rs.Fields(j).Name).Properties("Description").Value             MsgBox Rs.Fields(i).Properties("Description").Value             MsgBox Rs.Fields(i).ActualSize             MsgBox Rs.Fields(i).Attributes             'MsgBox Rs.Fields(i).DataFormat             MsgBox Rs.Fields(i).DefinedSize             MsgBox Rs.Fields(i).NumericScale             'MsgBox Rs.Fields(i).OriginalValue             MsgBox Rs.Fields(i).Precision                          'MsgBox Rs.Fields(i).Properties("Description")                                      MsgBox Rs.Fields(i).Status             MsgBox Rs.Fields(i).Type             'MsgBox Rs.Fields(i).UnderlyingValue             MsgBox Rs.Fields(i).Value                  Next     Set MyDB = Nothing     Rs.Close     Set Rs = Nothing     Cn.Close     Set Cn = Nothing     Exit Sub

  • ExcelにSQLの結果を表示

    ExcelVBAにてSQLで取得した値を貼り付けたいのですが どのようにコードを記入すればいいんでしょうか? ネットで調べたら下記のような参考コードを見つけたのですが dim SQL as String dim rs As Recordset SQL = " SELECT SUM(フィールド名) AS 名前 FROM テーブル名 " Set rs = CurrentDb.OpenRecordset(SQL) この後 RANGE("A1")=rs としても種々のエラーが出ます? どうしたらよいでしょうか? よろしくお願いします

  • オラクルのデータをAccessに追加 無限ループ

    前回、オラクルからデータを取り出し、Accessのテーブルに書き込みを教えて頂き、データ追加は出来たのですが、データ追加時に無限ループが発生しました。 【環境】 Oracle:10g Access:2010 Dim CON As New ADODB.Connection 'Oracle側コネクション Dim RS As ADODB.Recordset 'Oracle側レコードセット Dim SQL As String 'Oracle側SQL文 Dim i As Integer '処理用インクリメント Dim DT As Date '抽出日付変数(日付型) Dim sDT As String '抽出日付変数(テキスト型) Dim RS2 As ADODB.Recordset 'Access側レコードセット ◎現在の状況 Dim CON As New ADODB.Connection Dim RS As ADODB.Recordset Dim SQL As String Dim i As Integer 'DB接続定義 CON.Open "DSN=DNS名;UID=ユーザー名;PWD=パスワード;" 'SQL文 SQL = "SELECT " SQL = SQL & "カラム1," SQL = SQL & "カラム2," SQL = SQL & "カラム3" SQL = SQL & "FROM オラクルテーブル名 " SQL = SQL & "WHERE 抽出条件 " SQL = SQL & "AND 抽出条件" SQL = SQL & "GROUP BY カラム" SET RS = CON.EXCUTE(SQL) ’取得したレコード数表示 MsgBox "オラクル側のレコード数は: " & RS.RecordCount (1)↑↑↑オラクルから、抽出したレコード数表示 rs2.Open "新しいテーブル名", CurrentProject.Connection, adOpenKeyset, adLockOptimistic rs.MoveFirst Do Until rs.EOF rs2.AddNew rs2!カラム1 = rs!カラム1 rs2!カラム2 = rs!カラム2 rs2!カラム3 = rs!カラム3 rs2.Update rs2.Close: Set rs2 = Nothing rs.close: SET RS = Nothing con.close:SET CON=Nothing end sub 上記を実行したところ、いくら待っても処理がおわらず、強制終了をかけた所、新テーブルには、約150万件追加されてました。 (1)でオラクルから抽出した、レコード数を表示させてみた所、-1でした。 ◎疑問点、 -1ってありえない数値だと思うのですが。 ちなみに、オラクル側で同様のSQLを実行させた所、取得件数は48件でした。 上記について、ご存じの方がいらっしゃいましたら、アドバイスお願いいたします。

  • SQL SERVER の Where条件

    初めて質問させて頂きます。 VB内でSQL文を作成し、それをSqlServerに送り実行させているのですが、 VB内でSQL文を作成する時に、Whereの条件を入れたり入れなかったりします。 その時、都度、WhereをつけるのかAndをつけるのか判断してプログラムを書くのが億劫なので Dim SqlString as string SqlString = "SELECT * FROM テーブルA WHERE 0 = 0" IF txtA.text <> "" then SqlString = SqlString & " AND 項目A = " & txtA.text END IF IF txtB.text <> "" then SqlString = SqlString & " AND 項目B = " & txtB.text END IF こういうズボラをしてるのですが、これってSqlの実行スピードに影響したりしますか? 思うようにインデックス使ってくれなかったりしますか? ご存知の方がご教授下さい。 よろしくお願いします。

  • excel vba で .mdb のデータ抽出

    excel vba で postdata.mdbのpostレコードから条件に合うデータを抽出しようとしています。 数日間、いろいろ調べていますが分かりません。 おそらく、SQLの部分だと思うのですが・・・ adoは初めて使う素人なので教えていただけないでしょうか。 On Error GoTo ErrGyo Set cn = New ADODB.Connection cn.Provider = "Microsoft.Jet.OLEDB.4.0" cn.Open ThisWorkbook.Path & "\postdata.mdb" Dim Rs As ADODB.Recordset Dim SQL As String Dim T_ken As String Dim T_si As String Dim T_mati As String Dim i As Long T_ken = TextBox1.Value  ’フォームにテキストボックス T_si = TextBox2.Value T_mati = TextBox3.Value SQL = "SELECT * FROM post WHERE ken like '" & T_ken & "' and si LIKE '" & T_si & "' and mati LIKE '" & T_mati & "'" Set Rs = New ADODB.Recordset Rs.Open SQL, cn, adOpenForwardOnly, adLockReadOnly MsgBox Rs.RecordCount  ’ここでチェックすると -1 となる??? If Rs.RecordCount = 0 Then MsgBox "該当するレコードは見つかりませんでした。", vbInformation Else For i = 1 To Rs.RecordCount Cells(i, 1) = Rs!num Cells(i, 2) = Rs!ken Cells(i, 3) = Rs!si Cells(i, 4) = Rs!mati Rs.MoveNext Next End If Rs.Close: Set Rs = Nothing cn.Close: Set cn = Nothing Exit Sub ErrGyo: MsgBox "postdataへの接続に失敗しました", vbCritical

  • エクセルVBAでSQLサーバーの値を編集したい

    エクセルVBAでSQLサーバーの値を編集したい 「エクセルVBAとSQLサーバーを接続し、SQLサーバー上の、指定したテーブルのセル(?)番地の内容を、エクセルのセルに入力されたものに変更し、上書きする」プログラムを作成しています。 エクセルVBA→SQLサーバーへの接続は初めてです。 以下の文で、SQLサーバーに接続する所までは進みました。 ここから先、「SQLサーバー上の、指定したテーブルのセル(?)番地の内容を、エクセルのセルに入力されたものに変更し、上書きする」の部分は、SQL文の形式でコーディングしなければいけないのでしょうか? 当方、SQL文を記述した事が無いため、例えば 'アクセスのテーブル名.range("A2").value = Sheets("test").range("A2").value のようにコーディングできると楽なのですが... 目的のプログラムを作成するのに手がかりになりそうな方法や、ヒントとなるwebサイトがありましたらお教え下さい。 Dim con As New ADODB.Connection Dim connectionString As String Dim sDBSever As String Dim sDBName As String Dim sLoginID As String Dim sPassWD As String sDBSever = "(local)\SQLEXPRESS" sDBName = "DBName" sLoginID = "id" sPassWD = "pass" '接続文字列 connectionString = "Provider=Sqloledb;Data Source=" & sDBSever _ & ";Initial Catalog=" & sDBName _ & ";Connect Timeout=15" _ & ";user id=" & sLoginID _ & ";password=" & sPassWD _ & "" On Error GoTo Err_DBConnectOpen '接続 con.Open connectionString

  • エクセルからSQLの接続の仕方

    エクセルを使ってMSSQLに接続したいのですが、エラーがでて接続できません。 なぜでしょうか? [エラー内容] コンパイルエラー: ユーザー定義型は定義されれいません。 コードの下の部分で発生します。 Dim Cn As New System.Data.SqlClient.SqlConnection [コード] Private Sub CommandButton1_Click() Dim St As String Dim Cn As New System.Data.SqlClient.SqlConnection Dim SQL As System.Data.SqlClient.SqlCommand Dim ServerName As String Dim UserID As String Dim Password As String Dim DatabaseName As String ServerName = "TEST-PC" 'サーバー名(またはIPアドレス) UserID = "sa" 'ユーザーID Password = "password" 'パスワード DatabaseName = "TEST_DB_20140801" 'データベース St = "Server=" & ServerName & ";" & "User ID=" & UserID & ";" & "Password=" & Password & ";" & "Initial Catalog=" & DatabaseName Cn.ConnectionString = St SQL = Cn.CreateCommand SQL.CommandText = "SELECT * FROM LOG_DATA_XLINE" Cn.Open MsgBox (SQL.ExecuteScalar) Cn.Close SQL.Dispose Cn.Dispose End Sub

  • Excel VBA EOFに関して

    テキストボックスにDateを入力し、SQLServerに接続しSelectの結果をシートに書き込むだけのものなのですが、「BOFとEOFのいずれかがTrueになっているか、または現在のレコードが削除されています」というエラーでさっぱりわかりません。どなたかアドバイスをお願い致します。 -前後省略- stdate = UserForm1.stdate.Value endate = UserForm1.endate.Value strsql = "select ***" strsql = strsql & "from ***" strsql = strsql & "where *** and ***.start_date between '" & stdate & "' and '" & endate & "' " con.Open connectionString Set rs = con.Execute(strsql) Sheets("Data1").Select rs.MoveFirst i = 2 Do Until rs.EOF Cells(i, 1) = rs.Fields(0).Value Cells(i, 2) = rs.Fields(1).Value Cells(i, 3) = rs.Fields(2).Value Cells(i, 4) = rs.Fields(3).Value i = i + 1 rs.MoveNext Loop con.Close Set con = Nothing Exit Sub Err_DBConnectOpen: MsgBox Err.Description If con.State <> ADODB.adStateClosed Then con.Close End If Set con = Nothing End Sub

専門家に質問してみよう