Excel VBA - SQL调用 - 当对象关闭时不允许操作
我有几个宏调用SSMS 2014来运行查询,并将结果返回到工作表中定义的单元格中。他们成功地工作,但是当我尝试使用与临时表的某些查询我收到以下错误信息:Excel VBA - SQL调用 - 当对象关闭时不允许操作
我已经在网上进行搜索,最好的答案,我能找到的是在开始时添加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线长,所以它是相当大的...
任何建议表示赞赏!
编辑:低于满宏(实际查询以下):
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
与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
正如我在问题中所述,我试过了,它仍然没有工作:( –
如果你坚持使用临时表,你是对的,如果你愿意使用表变量,那么它的工作方式如上所述 – Ralph
有趣......我会给出一个镜头,谢谢 –
'QUERY ='位于底部附近。它是在'first.Open'中运行,还是直接在SMSS中运行,然后将值粘贴回excel。这句话“然后运行代码提取和过去到Excel中,它的工作。”不清楚。 – JNevill
这是在'rst.open'运行,对不起,这不明确 –
所以这样的工作,但你有一些其他的查询不?你能分享不工作的查询吗?通常,在尝试打开后关闭(或设置为“无”)的记录集是由于某种原因导致数据库出错的结果。 – JNevill