У меня есть макросы для вызова SSMS 2014 для запуска запроса и возврата результатов в определенной ячейке на моем листе. Они работают успешно, но когда я пытаюсь использовать некоторые запросы с временными таблицами я получаю следующее сообщение об ошибке:Excel VBA - SQL Call - операция не разрешена, когда объект закрыт.
Я исследовал онлайн и лучший ответ, который я могу найти, чтобы добавить SET NOCOUNT ON
в начале мой запрос. Я попробовал это и все еще получил то же сообщение.
Кусок кода, что Debug
приносит мне следующим образом:
bqr.Range("B6").CopyFromRecordset rst
Мясо и картофель моего кода, наряду с переменными установками, которые имеют значение, заключается в следующем:
Dim cnn As New ADODB.Connection
Dim rst As New ADODB.Recordset
Dim ConnectionString As String
Dim StrQuery As String
Dim SOURCE As String
Dim DATABASE As String
Dim QUERY As String
Dim intColIndex As Integer
Dim sDate As String
Dim eDate As String
Dim qt As Worksheet
Dim qtr As Worksheet
Dim bqr As Worksheet
Dim bp As Worksheet
ConnectionString = "Provider=SQLOLEDB;Data Source=" & SOURCE & "; Initial Catalog=" & DATABASE & "; Integrated Security=SSPI;"
cnn.Open ConnectionString
cnn.CommandTimeout = 900
StrQuery = QUERY
rst.Open StrQuery, cnn
bqr.Range("B6").CopyFromRecordset rst
For intColIndex = 0 To rst.Fields.Count - 1
Range("B5").Offset(0, intColIndex).Value = rst.Fields(intColIndex).Name
Next
Самая запутанная часть состоит в том, что ошибка говорит о том, что мой набор записей rst
закрыт, хотя он открыт только до того, как я использую CopyFromRecordset
Я попытался добавить DROP TABLE
в конце моего запроса, функцию SET NOCOUNT ON
в начале и даже протестировал несколько небольших простых временных таблиц в качестве тестов.
Например, я поставил свою QUERY
переменный:
QUERY = "CREATE TABLE #Test1 (TestID INT, TestValue VARCHAR(20))"
QUERY = QUERY + " INSERT INTO #Test1"
QUERY = QUERY + " VALUES (1, 'Pass'), (2, 'Fail'), (3, 'Try Again')"
QUERY = QUERY + " SELECT * INTO #Test2 FROM #Test1 WHERE TestID = 1"
QUERY = QUERY + " SELECT * FROM #Test2"
Затем побежал код для извлечения и прошлого в Excel, и она работала.
Поэтому я в тупике. Может быть, существует ограничение на длительность запроса? Прямо сейчас это 180 строк, поэтому он довольно большой ...
Любые предложения приветствуются!
EDIT: Полный макрос ниже (меньше фактический запрос):
Private Sub CommandButton1_Click()
If TextBox1.Value = "i.e. 20160101" Or TextBox2.Value = "i.e. 20160131" Then
MsgBox "Please fill out all fields before proceeding"
ElseIf Len(TextBox1.Value) <> 8 Or Len(TextBox2.Value) <> 8 Or Not IsNumeric(TextBox1.Value) Or Not IsNumeric(TextBox2.Value) Then
MsgBox "Please use correctly formatted Datekeys (i.e. yyyymmdd)"
Else
Application.DisplayAlerts = False
Sheets(ActiveWorkbook.Sheets.Count).Select
While ActiveSheet.Name <> "[worksheet I want to keep]"
ActiveSheet.Delete
Sheets(ActiveWorkbook.Sheets.Count).Select
Wend
Dim cnn As New ADODB.Connection
Dim rst As New ADODB.Recordset
Dim ConnectionString As String
Dim StrQuery As String
Dim SOURCE As String
Dim DATABASE As String
Dim QUERY As String
Dim intColIndex As Integer
Dim sDate As String
Dim eDate As String
Dim qtr As Worksheet
Dim bqr As Worksheet
Dim bp As Worksheet
Set qtr = Sheets([sheet name])
Sheets.Add after:=qtr
Set bqr = ActiveSheet
bqr.Name = "[sheet name]"
Sheets.Add after:=bqr
Set bp = ActiveSheet
bp.Name = "[sheet name]"
SOURCE = "[server]"
DATABASE = "[database]"
sDate = UserForm1.TextBox1.Value
eDate = UserForm1.TextBox2.Value
QUERY = "[beginning of query]"
QUERY = QUERY + " [more query here]" 'This gets repeated a lot for each additional line in the query'
qtr.Select
Range("B6").Select
While ActiveCell.Value <> ""
QUERY = QUERY + " " + ActiveCell.Value
ActiveCell.Offset(1, 0).Select
Wend
QUERY = QUERY + " [more query here]" 'This gets repeated a lot for the remaining lines in the query'
ConnectionString = "Provider=SQLOLEDB;Data Source=" & SOURCE & "; Initial Catalog=" & DATABASE & "; Integrated Security=SSPI;"
cnn.Open ConnectionString
cnn.CommandTimeout = 2000
StrQuery = QUERY
rst.Open StrQuery, cnn
bqr.Range("B6").CopyFromRecordset rst
For intColIndex = 0 To rst.Fields.Count - 1
Range("B5").Offset(0, intColIndex).Value = rst.Fields(intColIndex).Name
Next
End If
Application.DisplayAlerts = True
End Sub
Это 'QUERY =' бит около дна. Это было запущено в 'rst.Open', или вы запускали это непосредственно в SMSS и вставляете значения обратно в excel. Предложение «Затем запустило код для извлечения и прошлых действий в Excel, и это сработало». неясно. – JNevill
Это было запущено в 'rst.Open', извините, что было неясно –
Так что сработало, но у вас есть другой запрос, который нет? Можете ли вы поделиться запросом, который не работает? Как правило, набор записей, который закрыт (или установлен в Nothing) после попытки открыть, является причиной ошибки базы данных по какой-либо причине. – JNevill