【问题标题】:VBA Excel avoiding for loops with variable columnVBA Excel避免带有变量列的循环
【发布时间】:2015-04-12 22:26:30
【问题描述】:

我是第一次使用 VBA。到目前为止,我成功地建立了一个模型。但是,我仍然想加快计算速度(我已经关闭了 ScreenUpdating、EnableEvents、xlCalculationAutomatic、DisplayPageBreaks)。我在互联网上读到 for 循环非常耗时。不幸的是,我真的有很多。因此,我的问题:

假设我有这种类型的代码:

 For p = 1 To Periods
 Demand(p) = Worksheets("Sheet1").Cells(3, 1 + p)
 Next p

我的第一个问题:这个 for 循环真的会减慢运行时间吗? 第二个问题:如何重写,从而加快计算速度?

我一直在尝试以下方法:

 Demand = Worksheets("Sheet1").Range(Worksheets("Sheet1").Cells(3, 2), Worksheets("Sheet1").Cells(3, 1 + Periods))

但不幸的是,这似乎不起作用。我已经用谷歌搜索过了,但我似乎没有找到答案。

非常感谢您的帮助!

【问题讨论】:

    标签: excel vba for-loop


    【解决方案1】:

    这实际上取决于你的终端计数器有多大以及你的步数有多小。如果您的终端计数器大于 500K(非常大),您可能会遇到明显的减速。

    但是,您应该考虑以下几点:

    优化循环内的指令

    您的速度更有可能受到循环内指令的影响。您最好先优化它们,然后再担心应该使用For each 还是For Loop

    示例:在循环中使用 .Rows().EntireRow 属性通常会降低代码的速度,因为 Excel 会将一行视为可能包含一两百万个单元格的范围。这正是会减慢您的代码完成速度的原因。

    避免使用重复引用

    With 语句是提高代码速度的好方法。只需确保您的循环嵌套在 With 语句中即可。这样,VBA 就不必多次检查父引用。

    @Mike Woodhouse 的回答是一个很好的例子,说明了如何使用 With 语句来提高代码速度。

    VBA 将通过引用Worksheets("Sheet1") 来执行您的指令周期时间:

    With Worksheets("Sheet1")
        For p = 1 To Periods
            Demand(p) = .Cells(3, 1 + p)
        Next p
    End With
    

    但是,在您的旧代码(如下)中,VBA 执行您的指令,并在此过程中调用 Periods time WorkSheets("Sheet1")

    For p = 1 To Periods
     Demand(p) = Worksheets("Sheet1").Cells(3, 1 + p)
     Next p
    

    【讨论】:

      【解决方案2】:

      花时间的不是For 循环,而是你在其中所做的事情。使用 Excel VBA,您可以做的最慢的事情之一就是与工作表交互。

      您可以考虑的一个快速更改是:

      With Worksheets("Sheet1")
          For p = 1 To Periods
              Demand(p) = .Cells(3, 1 + p)
          Next p
      End With
      

      ... 这意味着您的代码知道它总是在处理同一个工作表,并且每次循环时都不必查找正确的工作表。您可能不会注意到太大的差异,但是您已经从每个周期查找一个工作表变成了每次运行一个。不过,您仍然可以在每个期间进行一次单元格查找。

      可以只调用一次工作表:一次调用获取所有值并完全避免循环:

      Demand = Worksheets("Sheet1").Cells(3, 2).Resize(1, Periods).Value
      

      这将在Demand 中为您提供一个 1 x Periods 数组。试试看 - 使用“查看...本地窗口”来查看您所拥有的。

      【讨论】:

      • 非常感谢您的帮助。快速的变化已经是一个巨大的进步。但是,我在尝试单次通话时遇到了一些问题。我收到此错误:“运行时错误'13':类型不匹配”。你知道哪里出了问题吗?
      • 你是在声明Demand吗?像Dim Demand(1 To Periods) 这样的东西?如果是这样,请尝试删除类型声明 Dim Demand 或明确将其设为 Variant: Dim Demand As Variant。否则,如前所述,我们需要查看更多代码,尤其是导致出现问题的代码...
      • 再次感谢。我确实宣布了需求。现在一切正常。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      相关资源
      最近更新 更多