【问题标题】:how to Speed Up the VBA Macros如何加速 VBA 宏
【发布时间】:2010-08-17 06:36:01
【问题描述】:

我正在使用宏生成新表格。对于新一代工作表,从超过 4 个 MS Access DB 中检索数据。每个数据库至少有 200 个字段。我的宏代码包括

  1. Cell locking
  2. Alignment and formatting
  3. One third of the cells in the sheet had a formulas
  4. Cell reference with other Workbooks

我的问题是每一代板材至少需要一个小时才能完成打孔过程。但在我看来,这需要的时间太长了。

我已经添加了Application.ScreenUpdating = True 以加快代码速度,但仍然需要同样的时间。如何加快代码速度,如果您有任何想法,请指导我。

     `For Ip = 5 To  150
     resp = Range("B" & Ip).Value
     With ActiveSheet.QueryTables.Add(Connection:= _
    "ODBC;DSN=henkel2;DBQ=C:\Hl-RF\RSF-Temp.mdb;DriverId=25;FIL=MS Access;MaxBufferSize=2048;" _
    , Destination:=Range("IV4"))
    .CommandText = "select Vles from " & Shtname & " where cint(PrductID)='" & resp & "' and cint(DepotID) = '" & cnt1 & "' and Mnth = '" & mnths & "' and Type='" & typs & "'"
    .Name = "tab product"
    .FieldNames = True
    .RowNumbers = False
    .FillAdjacentFormulas = False
    .PreserveFormatting = True
    .RefreshOnFileOpen = False
    .BackgroundQuery = True
    .RefreshStyle = xlInsertDeleteCells
    .SavePassword = False
    .SaveData = True
    .AdjustColumnWidth = True
    .RefreshPeriod = 0
    .PreserveColumnInfo = True
    .SourceConnectionFile = _
    "C:\Hl-RF\tabct.odc"
    .Refresh BackgroundQuery:=False
    End With`


    Is There Is any way to Reduce the loop iteration time

提前致谢

【问题讨论】:

  • 您应该提供一些代码,以便我们可以看到您在宏中所做的事情。您还应该提供有关 MS access 数据库查询的更具体信息 - 您在 Access 中运行了哪些查询 - 您是否尝试过对查询的性能进行基准测试?您怎么知道 VBA 宏是导致性能不佳的原因?
  • 您确实应该在问题标题中使用 Excel,因为我必须阅读整个问题才能理解您的问题仅与 Access 相关。

标签: performance ms-access vba excel


【解决方案1】:

你的意思是

Application.ScreenUpdating = False

除此之外,您还可以在宏运行时禁用工作簿的重新计算,看看是否有影响。这当然是假设瓶颈在于流程的电子表格部分,如果它需要很长时间才能从可能是需要查看的区域的访问中获取数据

【讨论】:

  • 你能解释清楚 Application.ScreenUpdating = False。如果我把它改成 false 会有什么不同
  • 通过将ScreenUpdating 设置为 False,您是在告诉 Excel 在您告诉它您想查看任何更改之前不要更新屏幕。 Application.ScreenUpdating = True 是 Excel 运行的正常状态,因此在您的代码中使用它不会有任何作用,除非您之前已禁用它。
  • 感谢您的建议,如果我更改 Application.ScreenUpdating = false 我认为循环 stmt 需要更多时间。有什么办法可以减少循环时间。
  • 大声笑,当我读到我喜欢的 OP 问题时,你想让它慢一点吗?但我并不是要批评,我们都是学习者。使用 Now() 函数添加大量调试语句来记录事情花费了多长时间@Meena
【解决方案2】:

获取一份Professional Excel Development 的副本,其中包括一个名为 PerfMon 的出色分析实用程序。它可以让您查看报告的哪些部分一直在占用,以便您分析和重写

【讨论】:

    【解决方案3】:

    您可以尝试将计算设置为手动并禁用 ScreenUpdating 的常用 vba 优化方法。

    Dim calc As XlCalculation
    calc = Application.Calculation
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    
    Application.ScreenUpdating = True
    Application.Calculation = calc
    

    将您的代码或函数调用放在Application.Calculation = xlCalculationManualApplication.ScreenUpdating = True 之间。

    This is from my previous Post

    注意:我找不到天气信息,或者您是否从 Access 或 Excel 中运行代码。如果您从 Access 创建 Excel 工作簿,您可能有一些类似这样的代码:

    Dim xlApp As Excel.Application
    Set xlApp = new Excel.Application
    

    在这种情况下,您必须将上面代码中的Application 更改为xlApp。例如:

    xlApp.Calculation = xlCalculationManual
    

    【讨论】:

    • 是的,我试过了,处理时间仍然没有变化是否有任何代码可以减少循环时间
    【解决方案4】:

    我会尝试在数据库方面做更多的工作。在数据库端生成您想要的报告,然后将结果导出到 Excel。

    Access 在自动生成报告方面比 Excel 好得多。

    【讨论】:

    • +1 以获得真正常识性的答案。但是,我们大多数人都遇到过需要类似电子表格的报告的情况,而 Access 报告有时并不适合这种情况。
    【解决方案5】:

    这个话题有一些讨论here

    编辑: 好的,那么下一步就是确定代码的哪些部分花费的时间最长。最简单的方法是复制您的代码,然后像这样开始测量各个部分:

    Private Declare Function GetTickCount Lib "kernel32.dll" () As Long
    Private mlngStrt As Long
    Private mlngEnd As Long
    
    Private Const u As Long = 10000000
    
    Public Sub Example()
        Dim i As Long
    
        mlngStrt = GetTickCount
        For i = 0 To u
        Next
        mlngEnd = GetTickCount
        Debug.Print "Section1", mlngEnd - mlngStrt
    
        mlngStrt = GetTickCount
        ExampleSubCall
        mlngEnd = GetTickCount
        Debug.Print "ExampleSubCall", mlngEnd - mlngStrt
    
        mlngStrt = GetTickCount
        For i = 0 To (u * 1.5)
        Next
        mlngEnd = GetTickCount
        Debug.Print "Section2", mlngEnd - mlngStrt
        Debug.Print "Example Complete"
    End Sub
    
    Private Sub ExampleSubCall()
        Dim i As Long
        For i = 0 To (u * 0.75)
        Next
    End Sub
    

    这种方法相当简单。这里的缺点是你需要插入所有的时序语句,然后转身将它们删除。这就是我要制作副本的原因。

    一旦您知道哪些部分花费的时间最长,您就知道将注意力集中在哪里以及寻求帮助的地方。

    【讨论】:

    • 这是一个很好的链接,确实是它的工作。但是我的宏代码包含超过 1000 行,完全需要一小时我遵循链接中给出的所有建议仍然至少需要一小时。有没有其他方法可以减少宏运行时间
    【解决方案6】:

    看看 Chris cmets。我们认为,您的性能瓶颈可能在于您查询数据库的方式,而不是在将数据应用到工作表的 VBA 代码中。

    关于 Access 性能的简单问题: - 你的表有索引吗? - 您是否使用任何类型的表连接? - Access 数据库是在您的计算机上本地访问还是被远程访问?

    再一次,我只是在强调 Chris 已经评论过的内容。

    【讨论】:

      【解决方案7】:

      是的,在 Access 中创建一个表格来保存您的客户 ID。然后在此处创建查询并使用外部数据连接器连接到它。之后手动刷新或使用 VBA 在准备好时刷新连接。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-07
        • 2018-04-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多