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

20

Я копирую фрагмент кода 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)

Любая идея, почему?

Спасибо.

  • 0
    Помогите! У меня та же ошибка, но приведенные ниже решения не помогли: stackoverflow.com/questions/1682717/…
Теги:
excel-vba
excel
adodb

6 ответов

18
Лучший ответ

Я добавил исходный каталог в строку подключения. Я также отказался от синтаксиса ADODB.Command в пользу просто создания моего собственного оператора 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
  • 2
    Это сработало для меня, спасибо, не забудьте добавить ссылку на Microsoft ActiveX Data Objects 2.1, хотя я добавил версию 2.6. Также вам не нужно закрывать соединение в конце? как objMyRecordset.Close?
14

Предлагаемые изменения:

  • Не вызывать метод Execute объекта Command;
  • Задайте свойство Source объекта Recordset как ваш объект Command;
  • Вызов объекта Recordset Открытый метод без параметров;
  • Удалите круглые скобки вокруг объекта Recordset при вызове 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
  • 0
    +1 за удаление скобок. Ненужные скобки в сочетании со ссылками на объекты, кажется, вызывают странные ошибки VBA
  • 0
    Я понимаю, что это старый поток - но мне было интересно, есть ли способ изменить приведенный выше код, чтобы также получить заголовки таблицы?
1

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

Я бы сделал:

Set objMyRecordset = objMyCommand.Execute

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

0

@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
0

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

0

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

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

РЕДАКТИРОВАТЬ. Посмотрите на свойство State набора записей, чтобы увидеть, является ли оно открытым?
Кроме того, измените свойство CursorLocation на adUseClient, прежде чем открывать набор записей.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню