2016-03-04 904 views
2

我有幾個宏調用SSMS 2014來運行查詢,並將結果返回到工作表中定義的單元格中。他們成功地工作,但是當我嘗試使用與臨時表的某些查詢我收到以下錯誤信息:Excel VBA - SQL調用 - 當對象關閉時不允許操作

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 TABLESET 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線長,所以它是相當大的...

任何建議表示讚賞!

編輯:低於滿宏(實際查詢以下):

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 ='位於底部附近。它是在'first.Open'中運行,還是直接在SMSS中運行,然後將值粘貼回excel。這句話「然後運行代碼提取和過去到Excel中,它的工作。」不清楚。 – JNevill

+0

這是在'rst.open'運行,對不起,這不明確 –

+0

所以這樣的工作,但你有一些其他的查詢不?你能分享不工作的查詢嗎?通常,在嘗試打開後關閉(或設置爲「無」)的記錄集是由於某種原因導致數據庫出錯的結果。 – JNevill

回答

0

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" 

啓動T-SQL查詢那麼它應該工作。下一個例子也可以工作,並且更接近你的例子(但使用表變量)。

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

有趣......我會給出一個鏡頭,謝謝 –

相關問題