VBA ADO Recordset .Copyfromrecordset长运行时

时间:2016-08-22 20:07:24

标签: excel vba excel-vba adodb

我正在搜索可以修复此运行时构建的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

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。通过一次单步执行某些代码,我隔离了CopyFromRecordset命令的两个实例,在处理包含约30K-40K记录的记录集时,大约需要5-6分钟才能完成。这是一部包含许多公式的庞大工作手册。添加行:

Application.Calculation = xlManual

到宏的开头,整个过程的时间从大约10-12分钟减少到了30-40秒。

这可以防止Excel尝试将成千上万条记录中的每一个都复制到工作表中时,重新计算大规模工作簿中每个公式的值。宏后面已经有了一行,可以通过以下方式将行为恢复为默认值:

Application.Calculation = xlAutomatic