Я копирую фрагмент кода 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)
Любая идея, почему?
Спасибо.
Я добавил исходный каталог в строку подключения. Я также отказался от синтаксиса 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
Предлагаемые изменения:
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".
@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
Добавьте set nocount on
в начало хранимой процедуры (если вы находитесь на SQL Server). Я просто решил эту проблему в своей собственной работе, и это было вызвано промежуточными результатами, такими как "1203 Rows Affected"
, загружаемыми в Recordset
, который я пытался использовать.
Является ли это правильной строкой соединения?
Где находится экземпляр SQL Server?
Вам нужно будет убедиться, что вы можете подключиться к SQL Server, используя указанную выше строку соединения.
РЕДАКТИРОВАТЬ. Посмотрите на свойство State набора записей, чтобы увидеть, является ли оно открытым?
Кроме того, измените свойство CursorLocation на adUseClient, прежде чем открывать набор записей.