web-dev-qa-db-ja.com

Excel-VBAでSQLデータベースにアクセスする

SQLクエリの結果をExcelシート(Excel 2007)に取り込む方法を示したMSDNのVBAコードスニペットをコピーしています。

Sub GetDataFromADO()

    'Declare variables'
        Set objMyConn = New ADODB.Connection
        Set objMyCmd = New ADODB.Command
        Set objMyRecordset = New ADODB.Recordset

    'Open Connection'
        objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;User ID=abc;Password=abc;"
        objMyConn.Open

    'Set and Excecute SQL Command'
        Set objMyCmd.ActiveConnection = objMyConn
        objMyCmd.CommandText = "select * from myTable"
        objMyCmd.CommandType = adCmdText
        objMyCmd.Execute

    'Open Recordset'
        Set objMyRecordset.ActiveConnection = objMyConn
        objMyRecordset.Open objMyCmd

    'Copy Data to Excel'
        ActiveSheet.Range("A1").CopyFromRecordset (objMyRecordset)

End Sub

参照としてMicrosoft ActiveX Data Objects 2.1 Libraryを既に追加しています。そして、このデータベースはアクセス可能です。

さて、このサブルーチンを実行すると、エラーが発生します。

実行時エラー3704:オブジェクトが閉じられている場合、操作は許可されません。

声明について:

ActiveSheet.Range("A1").CopyFromRecordset (objMyRecordset)

理由は何ですか?

ありがとう。

26
Saobi

接続文字列に初期カタログを追加しました。また、単純に独自のSQLステートメントを作成し、その変数のレコードセットを開くために、ADODB.Command構文を放棄しました。

お役に立てれば。

Sub GetDataFromADO()
    'Declare variables'
        Set objMyConn = New ADODB.Connection
        Set objMyRecordset = New ADODB.Recordset
        Dim strSQL As String

    'Open Connection'
        objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=MyDatabase;User ID=abc;Password=abc;"
        objMyConn.Open

    'Set and Excecute SQL Command'
        strSQL = "select * from myTable"

    'Open Recordset'
        Set objMyRecordset.ActiveConnection = objMyConn
        objMyRecordset.Open strSQL            

    'Copy Data to Excel'
        ActiveSheet.Range("A1").CopyFromRecordset (objMyRecordset)

End Sub
25
David Walker

推奨される変更:

  • CommandオブジェクトのExecuteメソッドを呼び出さないでください。
  • RecordsetオブジェクトのSourceプロパティをCommandオブジェクトに設定します。
  • パラメーターを指定せずにRecordsetオブジェクトのOpenメソッドを呼び出します。
  • CopyFromRecordsetへの呼び出しでRecordsetオブジェクトの周りから括弧を削除します。
  • 実際に変数を宣言します:)

修正されたコード:

Sub GetDataFromADO()

    'Declare variables'
        Dim objMyConn As ADODB.Connection
        Dim objMyCmd As ADODB.Command
        Dim objMyRecordset As ADODB.Recordset

        Set objMyConn = New ADODB.Connection
        Set objMyCmd = New ADODB.Command
        Set objMyRecordset = New ADODB.Recordset

    'Open Connection'
        objMyConn.ConnectionString = "Provider=SQLOLEDB;Data Source=localhost;User ID=abc;Password=abc;"    
        objMyConn.Open

    'Set and Excecute SQL Command'
        Set objMyCmd.ActiveConnection = objMyConn
        objMyCmd.CommandText = "select * from mytable"
        objMyCmd.CommandType = adCmdText

    'Open Recordset'
        Set objMyRecordset.Source = objMyCmd
        objMyRecordset.Open

    'Copy Data to Excel'
        ActiveSheet.Range("A1").CopyFromRecordset objMyRecordset

End Sub
16
onedaywhen

私は関連するソフトウェアがまったくないコンピューターに座っていますが、メモリーからはコードが間違っているように見えます。コマンドを実行していますが、RecordSet that objMyCommand.Executeが戻ります。

私がやる:

Set objMyRecordset = objMyCommand.Execute

...そして「オープンレコードセット」部分を失います。

1
Gary McGill

@firedrawndagger:フィールド名/列ヘッダーをリストして、レコードセットFieldsコレクションを反復処理し、名前を挿入するには:

Dim myRS as ADODB.Recordset
Dim fld as Field
Dim strFieldName as String 

For Each fld in myRS.Fields
    Activesheet.Selection = fld.Name
    [Some code that moves to next column]
Next
0
Jock

それは適切な接続文字列ですか?
SQL Serverインスタンスはどこにありますか?

上記で指定した接続文字列を使用してSQL Serverに接続できることを確認する必要があります。

編集:レコードセットの状態プロパティを見て、それが開いているかどうかを確認しますか?
また、レコードセットを開く前に、CursorLocationプロパティをadUseClientに変更します。

0
shahkalpesh