Ana*_*a 秀 4 excel optimization performance vba excel-vba
我很想知道在双循环中执行一组指令的最快方法,以循环遍历二维范围的单元格.我的代码将是这样的:
Sub Test()
For i = 1 To 1000000
For j = 1 To 10 'It can be more than 10
'I put a set of instructions here
Next j
Next i
End Sub
Run Code Online (Sandbox Code Playgroud)
例如,假设我编写了一个简单的代码来实现以下任务:
Sub Test1()
T0 = Timer
For i = 1 To 1000000
For j = 1 To 10
Cells(i, j) = j + Rnd()
Next j
Next i
InputBox "The runtime of this program is ", "Runtime", Timer - T0
End Sub
Run Code Online (Sandbox Code Playgroud)
我在我的机器上运行了程序Test1,完成了179.6406秒.由于我没有声明变量(i和j),因此Test1正在运行,这些变量默认为Variant类型.然后我向Test1添加一行以将变量声明为Longs,因为VBA针对Longs进行了优化.新程序Test2将我的机器上的运行时间降低到168.7539秒(快了大约11秒).
为了提高Test2的性能,我关闭了Test2代码运行时不需要的Excel功能.
Sub Test3()
Dim i As Long, j As Long
T0 = Timer
ScreenUpdateState = Application.ScreenUpdating
StatusBarState = Application.DisplayStatusBar
CalcState = Application.Calculation
EventsState = Application.EnableEvents
DisplayPageBreakState = ActiveSheet.DisplayPageBreaks
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
ActiveSheet.DisplayPageBreaks = False
For i = 1 To 1000000
For j = 1 To 10
Cells(i, j) = j + Rnd()
Next j
Next i
Application.ScreenUpdating = ScreenUpdateState
Application.DisplayStatusBar = StatusBarState
Application.Calculation = CalcState
Application.EnableEvents = EventsState
ActiveSheet.DisplayPageBreaks = DisplayPageBreaksState
InputBox "The runtime of this program is ", "Runtime", Timer - T0
End Sub
Run Code Online (Sandbox Code Playgroud)
上述方法有助于提高性能的Test2和Test3的在96.13672秒完成我的机器上.所以我想知道是否有更有效的方法来做到这一点.任何人都可以提出更快的版本吗?如果可能,甚至避免双循环程序.
我使用了一个内部VBA数组,这在10秒内运行:
Sub QuickTest()
Dim v(1 To 1000000, 1 To 10) As Double
For i = 1 To 1000000
For j = 1 To 10
v(i, j) = j + Rnd
Next j
Next i
Range("A1:J1000000") = v
End Sub
Run Code Online (Sandbox Code Playgroud)
注意:
编辑#1:
考虑这个续集:
Sub QuickTest2_The_Sequel()
Dim i As Long, j As Long, m As Long, n As Long
Range("K1") = Evaluate("Now()")
m = 10
n = 1000000
ReDim v(1 To n, 1 To m) As Double
For i = 1 To n
For j = 1 To m
v(i, j) = j + Rnd
Next j
Next i
Range("A1:J" & n) = v
Range("K2") = Evaluate("Now()")
End Sub
Run Code Online (Sandbox Code Playgroud)
在这里,我们使用单元格K1和K2来记录开始和停止时间.我们也使用ReDim而不是Dim"限制"极限:
| 归档时间: |
|
| 查看次数: |
2298 次 |
| 最近记录: |