Доступ к базе данных SQL в Excel-VBA

я копирую фрагмент кода VBA из MSDN, который показывает мне, как захватить результаты из SQL-запроса в лист excel (Excel 2007):

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 в качестве ссылки. И эта база данных доступна.

теперь, когда я запускаю эту подпрограмму, она имеет ошибку:

ошибка во время выполнения 3704 операция не допускается, если объект закрыт.

на заявление:

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

есть идеи, почему?

спасибо.

6 ответов


Я добавил исходный каталог в строку подключения. Я также abandonded объекта adodb.Синтаксис команды в пользу простого создания моего собственного оператора SQL и открытия набора записей для этой переменной.

надеюсь, что это помогает.

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

предложенные изменения:

  • не вызывайте метод Execute объекта Command;
  • установите свойство источника объекта набора записей в качестве объекта команды;
  • вызовите метод Open объекта набора записей без параметров;
  • удалите круглые скобки вокруг объекта набора записей в вызове CopyFromRecordset;
  • фактически объявите свои переменные:)

исправленный код:

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

я сижу за компьютером без каких-либо соответствующих бит программного обеспечения, но из памяти этот код выглядит неправильно. Вы выполняете команду, но отбрасываете RecordSet что objMyCommand.Execute возвращает.

Я бы сделал:

Set objMyRecordset = objMyCommand.Execute

...а затем потерять часть "open recordset".


Это правильная строка подключения?
Где находится экземпляр SQL Server?

вам нужно будет убедиться, что вы можете подключиться к SQL Server с помощью строки подключения, указанной выше.

EDIT: посмотрите на свойство State набора записей, чтобы узнать, открыт ли он?
Кроме того, перед открытием набора записей измените свойство CursorLocation на adUseClient.


добавить set nocount on до начала сохраненного proc (если вы находитесь на SQL Server). Я только что решил эту проблему в своей работе, и это было вызвано промежуточными результатами, такими как "1203 Rows Affected", загружается в Recordset Я пытался использовать.


@firedrawndagger: получить список имен полей заголовков/колонки перебора записей поля и введите имя:

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