我有一个在Excel中运行的查询,其中包含可在工作簿中更改的变量参数。
在整个SQL语句中多次引用它,因此我在Select之前声明了一个变量(@Days),然后在整个查询中引用它。
这在管理工作室很好用。
如果我尝试在VBA中执行此操作,则会收到应用程序定义或对象定义错误。
如果我取消注释我的剪贴板代码,并将结果粘贴到管理工作室,它就不会执行任何问题。 如果我在.Refresh之前停止VBA,并手动刷新查询,它会刷新。
VBA如下:
Sub Refresh()
Dim Days As String
Dim SQLStat As String
Dim RChar As Integer
Days = Sheets("Data").Range("A1").Value
' Gets current Query, and strips off declaration
SQLStat = ActiveWorkbook.Connections("Query").ODBCConnection.CommandText
SQLStat = Right(SQLStat, (Len(SQLStat) - (InStr(1, SQLStat, "Select") - 1)))
' Adds Declaration with new days value.
SQLStat = "Declare @Days integer set @Days = " & Days & " " & Chr(13) & SQLStat
' Puts SQL in clipboard for test purposes
'Dim clipboard As MSForms.DataObject
'Set clipboard = New MSForms.DataObject
'clipboard.SetText SQLStat
'clipboard.PutInClipboard
With ActiveWorkbook.Connections("Query").ODBCConnection
.BackgroundQuery = False
.CommandText = SQLStat
.Refresh
End With
MsgBox "Refreshed"
End Sub
我将其分解为测试场景。 Test1失败。查询无法更新。 Test2会像你期待的那样刷新。
Sub Test1()
Dim SqlStr As String
Dim Days As String
Days = Sheets("test").Range("A1").Value
SqlStr = "declare @Days int set @Days = " & Days & " select dateadd(day,@days,getdate())"
With ActiveWorkbook.Connections("Query").ODBCConnection
.CommandText = SqlStr
.Refresh
End With
End Sub
Sub Test2()
Dim SqlStr As String
Dim Days As String
Days = Sheets("test").Range("A1").Value
SqlStr = "select dateadd(day," & Days & ",getdate())"
With ActiveWorkbook.Connections("Query").ODBCConnection
.CommandText = SqlStr
.Refresh
End With
End Sub
答案 0 :(得分:1)
我认为问题在于,当您通过ODBC执行查询时,您无法声明临时变量@Days
,就像将剪贴板内容粘贴到SSMS中一样,尽管我可能错了。
正如Sean Lange所说,这不是理想的做法,但您可以在VBA中构建整个查询,然后将其传递给服务器。像这样:
Dim Days As String
Dim SQLStat As String
Dim RChar As Integer
Days = Sheets("Data").Range("A1").Value
' Gets current Query, and strips off declaration
SQLStat = ActiveWorkbook.Connections("Query").ODBCConnection.CommandText
SQLStat = Right(SQLStat, (Len(SQLStat) - (InStr(1, SQLStat, "Select") - 1)))
'Build the new query string using the actual value of Days
SQLStat = Replace(SQLStat, "@Days", Days)
这将在VBA中构建整个查询字符串,从而省去了在服务器上声明@Days
局部变量的需要。 Replace()
在VBA中与@Days
在服务器上执行的操作相同。