2015-02-12 78 views
2

我第一次使用VBA。直到现在,我成功地建立了一个模型。但是,我仍然想加快计算(我已经关闭了ScreenUpdating,EnableEvents,xlCalculationAutomatic,DisplayPageBreaks)。我已经在互联网上看到,for-loops非常耗时。不幸的是,我真的有很多。因此,我的问题:VBA Excel避免与可变列循环

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

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

我的第一个问题:这是否为环真正减慢运行时间?第二个问题:我如何重写它,从而加速计算?

我一直在尝试以下操作:

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

但不幸的是,这似乎并没有工作。我已经Google了这个,但我似乎没有找到答案。

非常感谢您的帮助!

回答

0

这不是需要花时间的For循环,而是你在里面做的事情。使用Excel VBA,您可以做的最慢的事情之一是与工作表交互。你可以考虑

一个快速变化是这样的:

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

......这意味着你的代码知道它总是在处理同一个工作表,并没有每次来查找正确的你绕过循环。您可能不会注意到很多差异,但是您已经从每个时期的一个工作表查找到每个运行一个工作表。尽管如此,你仍然有一个单元格查找每个时期。

可以到工作表一个电话,但:得到一个呼叫中的所有值,并完全避免循环:

​​

那将让你在Demand一个1个周期阵列。试试吧 - 使用“查看...本地窗口”来查看你有什么。

+0

非常感谢您的帮助。快速变化已经是一个巨大的改进。但是,我尝试单一呼叫时遇到一些问题。我得到这个错误:“运行时错误'13':类型不匹配”。你有什么想法可能出错的地方? – Ann 2015-02-12 14:00:25

+0

您需要发布更多的代码。 – 2015-02-12 14:21:21

+0

你是在声明'Demand'吗?像'昏暗的需求(1到期)'?如果是这样,请尝试删除类型声明“Dim Demand”或明确将其变为“Variant”:Dim Demand As Variant。否则,正如已经指出的那样,我们需要看到更多的代码,特别是导致问题行发生的情况。 – 2015-02-12 14:42:44

0

它实际上取决于你的结束计数器多大,你的步数是多少。如果您的最终计数器大于500K(真的很大),您可能会经历明显的减速。

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

优化环路

你的速度是更容易被循环内的指令影响里面的说明。你最好优化它们,然后担心你是否应该使用For eachFor 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执行你的指令,并在这样做时,它会调用周期时间 WorkSheets("Sheet1")

然而 ​​