我在SQL Server中有一个数据库,用于在Excel中提供一些财务报告。我通过自定义Excel函数使用Recordset,该函数使用来自Cells的参数来构建SQL查询。以下是代码的外观:
Public Function Test(arg1 As String, arg2 As String, arg3 As Integer, arg4 As Integer, arg5 As String) As Variant
Dim oConnection As ADODB.Connection
Set oConnection = New ADODB.Connection
Dim oRecordset As ADODB.Recordset
Set oRecordset = New ADODB.Recordset
Dim strSQL As String
strSQL = "SELECT SUM(BALANCE) as Total FROM Accounting WHERE ARGUMENT1 = " & Chr$(39) & arg1 & Chr$(39) & " AND ARGUMENT2 = " & Chr$(39) & arg2 & Chr$(39) & " AND ARGUMENT3 = " & Chr$(39) & arg3 & Chr$(39) & " AND ARGUMENT4 = " & arg4 & " AND ARGUMENT5 = " & arg5 & ""
oConnection.Open "Provider=SQLOLEDB;" & _
"Data Source=(IP of database);" & _
"Initial Catalog=(catalog of database);" & _
"Trusted_connection=yes;"
oRecordset.Open Source:=strSQL, ActiveConnection:=oConnection, CursorType:=adOpenForwardOnly, LockType:=adLockReadOnly, Options:=adCmdText
Test = oRecordset!Total
oRecordset.Close
Set oRecordset = Nothing
End Function
因此,此代码运行良好,但我遇到了性能问题。我必须填充数十个单元格,每个单元格使用来自不同单元格的不同参数。所以我的报告需要1分多钟才能完全加载。
我正在使用adOpenForwardOnly,但是我可以对代码进行任何其他微调以加快速度吗?
非常感谢
答案 0 :(得分:0)
如果您的数据不是特别时间敏感,那么您可以通过使用字典对象缓存以前查询的结果来“记忆”您的UDF。
未测试:
Public Function Test(arg1 As String, arg2 As String, arg3 As Integer, _
arg4 As Integer, arg5 As String) As Variant
Static dict As Object
Dim k As String, rv
Dim oConnection As ADODB.Connection
Dim oRecordset As ADODB.Recordset
Dim strSQL As String
'create the dictionary if not already created
If dict Is Nothing Then
Set dict = CreateObject("scripting.dictionary")
End If
'create a unique "key" from the arguments
k = Join(Array(arg1, arg2, arg3, arg4, arg5), Chr(0))
'need to run this query?
If Not dict.exists(k) Then
Set oConnection = New ADODB.Connection
Set oRecordset = New ADODB.Recordset
strSQL = "SELECT SUM(BALANCE) as Total FROM Accounting WHERE ARGUMENT1 = '" & _
arg1 & "' AND ARGUMENT2 = '" & arg2 & _
"' AND ARGUMENT3 = '" & arg3 & "' AND ARGUMENT4 = " & arg4 & _
" AND ARGUMENT5 = " & arg5 & ""
oConnection.Open "Provider=SQLOLEDB;" & _
"Data Source=(IP of database);" & _
"Initial Catalog=(catalog of database);" & _
"Trusted_connection=yes;"
oRecordset.Open Source:=strSQL, ActiveConnection:=oConnection, _
CursorType:=adOpenForwardOnly, LockType:=adLockReadOnly, _
Options:=adCmdText
rv = oRecordset!Total
dict.Add k, rv
oRecordset.Close
Set oRecordset = Nothing
Else
'already ran the SQL - just return the result
rv = dict(k)
End If
Test = rv
End Function