Доступ к базе данных 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