避免带有variables列的循环的VBA Excel
我第一次使用VBA。 到目前为止,我成功地build立了一个模型。 但是,我仍然想加快计算(我已经closuresScreenUpdating,EnableEvents,xlCalculationAutomatic,DisplayPageBreaks)。 我已经在互联网上看到,for循环是非常耗时的。 不幸的是,我真的有很多。 所以,我的问题是:
假设我有这种types的代码:
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))
但不幸的是,这似乎并不奏效。 我已经Google了这个,但我似乎没有find答案。
非常感谢您的帮助!
花时间不是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周期数组。 试试看 – 使用“查看…本地窗口”看看你有什么。
这实际上取决于你的terminal计数器有多大以及你的步数是多less。 如果您的最终计数器大于500K(真的很大),您可能会遇到明显的减速。
但是,您应该考虑以下几点:
优化循环内部的指令
你的速度更可能受循环内指令的影响。 你最好优化它们,然后担心你是否应该使用For each
或For Loop
。
例如:使用.Rows().EntireRow
循环内的.Rows().EntireRow
属性通常会降低代码的速度,因为Excel会考虑.Rows().EntireRow
可能为一百二十万个单元格的行。 这正是会减慢你的代码。
避免使用重复的引用
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