【问题标题】:VBA subroutine slows down a lot after first executionVBA 子程序在第一次执行后速度变慢了很多
【发布时间】:2014-05-22 18:52:50
【问题描述】:

我有一个子程序,可以生成 5 个系列中不同投资组合的业绩报告。问题是,有问题的投资组合永远不会相同,每个家庭的金额也不相同。因此,我复制粘贴了一个模板(即格式化和...),并将格式化行(包含公式和...)添加到报告中每个投资组合的正确系列中。一切都很好,代码当然不是最佳和完美的,但它可以很好地满足我们的需要。问题不在于代码本身,而是当我第一次执行代码时,它运行得非常快(比如 1 秒)......但是从第二次开始,代码速度显着变慢(基本的 30 秒任务与第一个相同)。我尝试了所有手动计算,没有刷新屏幕......但这确实不是问题所在。对我来说,这看起来像是内存泄漏,但我找不到问题出在哪里!为什么代码运行得非常快,但之后却慢得多……无论报告的长度和文件的内容如何,​​我都需要关闭 excel 并为每个报告重新打开它。

**不确定我是否清楚,但这不是因为代码使excel文件变大或什么,因为在第一次(快速)执行后,如果我保存工作簿,关闭并重新打开它,(新) 第一次执行将再次非常快,但如果我会在不关闭和重新打开的情况下执行相同的 excat 操作,它会非常慢...^!^!

Dim Family As String
Dim FamilyN As String
Dim FamilyP As String
Dim NumberOfFamily As Integer
Dim i As Integer
Dim zone As Integer


Sheets("RapportTemplate").Cells.Copy Destination:=Sheets("Rapport").Cells
Sheets("Rapport").Activate

i = 3
NumberOfFamily = 0
FamilyP = Sheets("RawDataMV").Cells(i, 4)
While (Sheets("RawDataMV").Cells(i, 3) <> "") And (i < 100)

    Family = Sheets("RawDataMV").Cells(i, 4)
    FamilyN = Sheets("RawDataMV").Cells(i + 1, 4)

    If (Sheets("RawDataMV").Cells(i, 3) <> "TOTAL") And _
    (Sheets("RawDataMV").Cells(i, 2) <> "Total") Then

        If (Family <> FamilyP) Then
            NumberOfFamily = NumberOfFamily + 1
        End If
        With Sheets("Rapport")
            .Rows(i + 8 + (NumberOfFamily * 3)).EntireRow.Insert
            .Rows(1).Copy Destination:=Sheets("Rapport").Rows(i + 8 + (NumberOfFamily * 3))
            .Cells(i + 8 + (NumberOfFamily * 3), 6).Value = Sheets("RawDataMV").Cells(i, 2).Value
            .Cells(i + 8 + (NumberOfFamily * 3), 7).Value = Sheets("RawDataMV").Cells(i, 3).Value
        End With
    End If
    i = i + 1
    FamilyP = Family
Wend

For i = 2 To 10
    If Sheets("Controle").Cells(16, i).Value = "" Then
        Sheets("Rapport").Cells(1, i + 11).EntireColumn.Hidden = True
    Else
        Sheets("Rapport").Cells(1, i + 11).EntireColumn.Hidden = False
    End If
Next i
Sheets("Rapport").Cells(1, 1).EntireRow.Hidden = True

'Define printing area
zone = Sheets("Rapport").Cells(4, 3).End(xlDown).Row
Sheets("Rapport").PageSetup.PrintArea = "$D$4:$Y$" & zone


Sheets("Rapport").Calculate
Sheets("RANK").Calculate
Sheets("SommaireGroupeMV").Calculate
Sheets("SommaireGroupeAlpha").Calculate
Application.CutCopyMode = False

结束子

【问题讨论】:

    标签: excel performance vba memory-leaks slowdown


    【解决方案1】:

    我目前没有笔记本电脑,但您可以尝试以下几种方法:

    1. 使用显式选项确保在使用之前声明所有变量;
    2. 据我所知,数字的原生 vba 类型不是 integer 而是 long,并且整数被转换为 long,为了节省计算时间,请使用 long 而不是整数;
    3. 您的 Family 变量被定义为字符串,但您在其中存储整个单元格而不是它们的值,即 =cells() 而不是 =cells().value
    4. 经验法则是使用cells(rows.count, 4).end(xlup).row 而不是cells(3, 4).end(xldown).row.
    5. 条件格式可能会大大降低处理速度;
    6. 如果可能,在范围上使用 for each 循环而不是 while,甚至将范围复制到变体数组并对其进行迭代(这是最快的解决方案);
    7. 使用早期绑定而不是后期绑定,即尽快以适当的类型定义对象;
    8. 不显示打印区域(分页符等);
    9. 尝试做一些分析并寻找瓶颈 - 请参阅 finding excel vba bottlenecks
    10. 如果不需要格式,请仅粘贴值;
    11. 每次复制/粘贴后清除剪贴板;
    12. 使用完对象后将其设置为Nothing
    13. 使用 Value2 而不是 Value - 这将忽略格式并仅采用数值而不是格式化值;
    14. 使用工作表对象并引用它们,例如

      将 sh_raw 设置为表单,将 sh_rap 设置为表单 设置 sh_raw = Sheets("RawDataMV") 设置 sh_rap = Sheets("Rapport")

    然后在任何地方都使用sh_raw 而不是Sheets("RawDataMV")

    【讨论】:

    • 感谢您的帮助.... 1) 显式选项已打开,2) 感谢您,很高兴知道 3) 再次感谢 4) 另一个好消息!但是,仍然没有任何变化... 您是否知道有任何方法可以重新启动 excel 内存,就好像我们要重新打开工作簿一样? 因为我真的不明白的是即使我运行相同的初始情况,第二次也将花费 100 倍以上的时间......
    • 没有办法重新启动 Excel 的内存。 VBA 不是 C,您无法影响 Excel 的内存占用。一般来说,Excel 会使用一定数量的内存,然后停留在那里。要使其尽可能小,只需将所有不使用的大对象设置为 Nothing。
    【解决方案2】:

    我有同样的问题,但我终于想通了。这听起来很荒谬,但它与打印页面设置有关。显然,每次更新单元格时 Excel 都会重新计算它,这就是导致速度变慢的原因。

    尝试使用

    Sheets("Rapport").DisplayPageBreaks = False
    

    在您的例行程序开始时,在任何计算和之前

    Sheets("Rapport").DisplayPageBreaks = True
    

    在它的最后。

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题。我远非专家级程序员。以上答案对我的程序有所帮​​助,但没有解决问题。我在 5 岁的笔记本电脑上运行 excel 2013。打开程序而不运行它,转到文件>选项高级,向下滚动到数据并取消选中“禁用撤消大型数据透视表刷新......”和“禁用撤消大型数据模型操作”。您也可以尝试让它们处于选中状态,但降低它们的价值。其中一个或两个似乎正在创建一个不断增加的文件,该文件会减慢宏并最终使其停止。我假设关闭 excel 会清除他们创建的文件,这就是为什么当 excel 关闭并重新打开至少一段时间时它运行得很快。有更多知识的人将不得不解释这些更改将做什么以及取消选中它们的后果是什么。这些更改似乎将应用于您创建的任何新电子表格。如果我有一台更新更强大的计算机,也许这些更改就没有必要了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-03
        • 1970-01-01
        • 2018-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-29
        相关资源
        最近更新 更多