【发布时间】:2019-05-17 00:07:25
【问题描述】:
我正在搜索可以修复此运行时构建的 VBA 代码,或有关可能导致此问题的建议。
我正在运行一个 VBA 脚本,该脚本使用 ADODB 从 SQL Server 数据库中检索数据。我已经在将数据复制到我的 Excel 工作表中的行上运行了运行时测试。运行时间是变化的;但是,我发现该行的运行时间在 3-30 秒之间:
Sheets(1).range("A8").CopyFromRecordset recordSet
记录集中的数据由 300 行和 13 列组成。
我觉得奇怪的一点是,当 excel 应用程序关闭并重新打开时,运行时似乎恢复正常。
以下是对 .copyfromrecordset 行的每个测试的运行时概念:
- 测试 1:3 秒
- 测试 2:3 秒
- 测试 3:3 秒
- 测试 4:5 秒
- 测试 5:5 秒
- 测试 6:6 秒
- 测试 7:7 秒
- 测试 8:6 秒
- 测试 9:8 秒
- 测试 9:10 秒
- ...
- 测试 20:24 秒
我对本地命令进行了测试,例如格式化单元格宽度/高度,这些运行时间恒定为 1 或 2 秒。
也许我错误地使用了记录集,或者如果没有找到解决方案,我只会减少数据库调用,这会阻止我获得最新数据。
我已经检查并检查了我认为可能是问题的任何未关闭的记录集对象,但没有任何东西是打开的。
Function Query(SQL As String)
Dim recordSet As ADODB.recordSet
Dim Field As ADODB.Field
Set recordSet = New ADODB.recordSet
recordSet.Open SQL, Conn, adOpenForwardOnly, adLockReadOnly, adCmdTxt
If recordSet.State Then
'seting up table headers
Dim i As Integer
For i = 0 To recordSet.Fields.Count - 1
Sheets(1).Cells(7, 1 + i).value = recordSet.Fields(i).name
Next i
Sheets(1).range("A7:M7").Font.Bold = True
t = Now()
'insert recordset data into cells
Sheets(1).range("A8").CopyFromRecordset recordSet
MsgBox Format(Now() - t, "hh:mm:ss")**
'close recordset object
recordSet.Close
Set recordSet = Nothing
End If
End Function
数据库连接
Function ConnectToDB(Server As String, Database As String) As Boolean
Set Conn = New ADODB.Connection
On Error Resume Next
Conn.ConnectionString = "Provider=SQLOLEDB; Integrated Security=SSPI; Data Source=" & Server & "; Initial Catalog=" & Database & ";"
Conn.Open
If Conn.State = 0 Then
ConnectToDB = False
Else
ConnectToDB = True
End If
End Function
【问题讨论】:
-
这不可能是你的全部代码。你在哪里设置连接?
-
@kyle 添加 db 连接功能
-
作为替代方案,您可以尝试“数据”选项卡 >“从其他来源”查看是否更快或 Power Query
-
我在
ADODB和.CopyFromRecordset方面拥有丰富的经验(超过几年),这是将记录集放入文件的最快方法。我运行这条线的时间从未超过 1-2 秒(即使是几千行或数据作为回报)。关闭连接不是问题,因为它们会在函数终止时自动关闭 (scope of variables)。您确定这一行花费了这么长时间(并且没有运行查询)吗?我没有在你的函数中看到任何时间跟踪该行。 -
另外,您是否在粘贴新数据之前清理工作表?如果您只是在每次新数据时插入(或附加),那么
.UsedRange会稳步增加,这可能是工作表的性能问题。确保在粘贴时关闭.ScreenUpdating和.Calculation和/或不可见工作表(要粘贴到的位置)。我当然希望你在那张纸上没有任何事件。否则,您也应该为该过程关闭事件。工作表或形状/控件/按钮等是否有任何保护?