我有一个使用几乎所有UDF的Excel模型。有说,120列和400多行。计算是垂直完成的,然后是水平的 - 首先完成第1列的所有计算,然后第1列的最终输出是第2列的输入,等等。在每一列中,我调用大约六个或七个UDF。调用其他UDF。 UDF经常输出一个数组。
每个UDF的输入是许多变量,一些范围变量,一些双精度变量。范围变量在访问其内容之前在内部转换为数组。
我的问题如下,我可以在没有UDF的情况下构建Excel模型,当我运行模拟时,我可以在X小时内完成所有计算。当我使用UDF时,模拟时间为3X小时或更长。 (为了回答这个显而易见的问题,是的,我需要使用UDF,因为如果我想对模型做一些小改动(比如说添加另一种资产类型(它是一个财务模型)),需要将近一天的时间重建模型没有UDF以适应新的法律/财务结构,使用UDF需要大约20分钟才能适应不同的财务结构。)
在任何情况下,我都关闭了屏幕更新,在函数中没有复制和粘贴,Variant类型的使用是最小的,所有数据都包含在一个工作表中,我将所有范围类型变量转换为数组之前得到内容。
除了获得更快的计算机或同等程序以使VBA代码/ Excel文件运行得更快之外,我还能做什么?如果需要进一步澄清,请告诉我。
谢谢!
答案 0 :(得分:4)
一些一般提示。
掌握你的功能,找出瓶颈所在的位置。请参阅此问题,了解excel中的use of timer。我确定那里有VBA个人资料......但你可能不需要那么远。 (注意:首先使用一个数据单元执行此操作...)
想想你的设计... 400x120的数据单元格不很多。因为花费数小时必须是痛苦的。 (过去我在等待了一千分钟的VLOOKUPS()
返回之后我已经破解了它)无论如何也许没有拥有一堆UDF,为什么没有一个简单的子程序{ {1}}通过范围并完成您需要它做的事情。 48,000个细胞可能需要几秒钟或几分钟。然后,您可以将子例程与用户的按钮或菜单项相关联。
出于兴趣,我快速浏览了选项2并创建了MyUDF(),使用子for..each
来调用它,因为活动选择对我来说比在每个单元格中使用UDF快10倍
DoMyUDF()
如果用你的UDF替换Option Explicit
Function MyUDF(myVar As Variant) As Variant
MyUDF = myVar * 10
End Function
Sub DoMyUDF()
Dim r As Range
Dim c As Variant
Dim t As Single
t = Timer
If TypeName(Selection) <> "Range" Then
Exit Sub
End If
Set r = Selection.Cells
Application.DisplayStatusBar = True
For Each c In r
c.Value = MyUDF(c.Value)
Application.StatusBar = "DoMyUDF(): " & Format(Timer - t, "#0.0000ms")
Next
Debug.Print "DoMyUDF(): " & Format(Timer - t, "#0.0000ms")
End Sub
,这可能只能节省4.5分钟......但是你可以建立一些其他经济体。特别是如果你一遍又一遍地重复相同的计算。
答案 1 :(得分:3)
Excel处理UDF的方式存在一个减速错误。每次计算UDF时,Excel都会刷新VBE标题栏(您可以看到它闪烁)。对于大量UDF,这非常慢。 在手动计算模式下,旁路非常简单:只需使用Application.Calculate(您可以使用OnKey捕获F9等)从VBA启动计算。
答案 2 :(得分:3)
您是否考虑过使用宏替换UDF(每个输出单元调用一次),该宏可以在循环中的一系列单元格上运行?
UDF设置/拆除非常慢,并且每个UDF调用的任何与其他UDF(例如从重叠输入读取)共同变得额外费力。
我已经能够提高性能10-50倍 - 这种情况不到一个月前涉及一个带有4000-30000 UDF调用的电子表格,用一个在一些命名范围上运行的宏替换它们。
答案 3 :(得分:2)
使用
控制并最小化重新计算wks.EnableCalculation = False
或
Application.Calculation = xlCalculationManual
此外,最小化VBA和工作簿之间的交换。一次读取和写入一组单元格到阵列
更快MyArray = range("B2:B20000")
而不是逐个单元格(对于每个......)。
答案 4 :(得分:2)
确保您从VBA而非电子表格中启动重新计算,请参阅http://msdn.microsoft.com/en-us/library/aa730921.aspx#Office2007excelPerf_Overview 以及关于更快的VBA用户定义函数的部分。 那是 Application.Calculate 比在电子表格中按F9要快得多(在我的测试案例中为100次)。