2016-03-04 4 views
2

У меня есть макросы для вызова SSMS 2014 для запуска запроса и возврата результатов в определенной ячейке на моем листе. Они работают успешно, но когда я пытаюсь использовать некоторые запросы с временными таблицами я получаю следующее сообщение об ошибке:Excel VBA - SQL Call - операция не разрешена, когда объект закрыт.

VBA Error Message

Я исследовал онлайн и лучший ответ, который я могу найти, чтобы добавить 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 
+0

Это 'QUERY =' бит около дна. Это было запущено в 'rst.Open', или вы запускали это непосредственно в SMSS и вставляете значения обратно в excel. Предложение «Затем запустило код для извлечения и прошлых действий в Excel, и это сработало». неясно. – JNevill

+0

Это было запущено в 'rst.Open', извините, что было неясно –

+0

Так что сработало, но у вас есть другой запрос, который нет? Можете ли вы поделиться запросом, который не работает? Как правило, набор записей, который закрыт (или установлен в Nothing) после попытки открыть, является причиной ошибки базы данных по какой-либо причине. – JNevill

ответ

0

Начните T-SQL запрос с set nocount on;

QUERY = "set nocount on;" 
QUERY = QUERY & "declare @Test1 table (TestID INT, TestValue VARCHAR(20))" 
QUERY = QUERY & " INSERT INTO @Test1" 
QUERY = QUERY & " VALUES (1, 'Pass'), (2, 'Fail'), (3, 'Try Again')" 
QUERY = QUERY & " SELECT * FROM @Test1 WHERE TestID = 1" 

Затем он должен работать. Следующий пример также будет работать и немного ближе к вашему примеру (но с использованием переменных таблицы).

set nocount on; 
declare @Test1 table (TestID INT, TestValue VARCHAR(20)) 
declare @Test2 table (TestID INT, TestValue VARCHAR(20)) 

INSERT INTO @Test1 
VALUES (1, 'Pass'), (2, 'Fail'), (3, 'Try Again') 

insert into @Test2 
select * 
from @Test1 WHERE TestID = 1 

select * from @Test2 
+0

Как я уже сказал в вопросе, я пробовал это и он по-прежнему не работает :( –

+0

Если вы настаиваете на том, чтобы использовать временные таблицы, вы правы. Если вы хотите использовать переменные таблицы вместо этого, то он работает так, как описано. – Ralph

+0

Интересно ... Я дам этот снимок, спасибо –

Смежные вопросы