VBA:使用多个For循环,还是一个大循环?
VBA: using multiple For loops, or one big?
我最近一直在想,哪个在效率方面更好:使用多个 For 循环,还是一个包含许多操作的大循环?
我使用 SQL 数据库中 17 列的 50k-100k 行。
现在,代码示例:
z = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To z
If Cells(i, 15) <> 0 Then Cells(i, 19) = 1 Else Cells(i, 19) = 0
Next i
For i = 2 To z
Cells(i, 20) = Val(Left(Cells(i, 2), 2))
Next i
For i = 2 To z
Select Case Cells(i, 18).Value
Case Is = 1
Cells(i, 29).Value = 1
Case Is = 2
Cells(i, 29).Value = 1.6
Case Is = 3
Cells(i, 29).Value = 2.8
End Select
Next i
For i = 2 To z
Cells(i, 30) = Val(Right(Cells(i, 14), 1))
Next i
For i = 2 To z
Cells(i, 31) = ((Cells(i, 18) + 1) * Cells(i, 16) * Cells(i, 17)) / 1000000
Cells(i, 31).NumberFormat = "0.00"
Next i
我的问题是:按列(每列单独的 For 循环)或按行(一个包含每条记录的所有操作的大循环)执行这些操作是否更明智?
从整体上看,性能瓶颈在于数据记录的获取,而不在于循环的结构。
您最好以可读性为目标,而不是试图过度优化代码,因为代码对执行时间的贡献可以忽略不计。
如果您要用数据库中的记录验证 excel 中的记录,那么您可以应用大循环;但如果循环内有循环,我什至可以建议使用 find() 方法。
(Find() 方法可以提高性能)
您的代码会非常慢,因为您要对对象模型进行大量调用以从单个单元格中检索值。每次调用都会产生很大的开销。
将所有必需的值读入变体数组会更快:
dim vArr as variant
vArr=Range("A1").resize(z,31).value2
然后在将处理后的数组返回到工作表之前处理生成的二维数组
我支持 Bathsheba 关于瓶颈操作将会是什么。
但是,每当你有一个插入大量数据的长宏时,你可能希望将这段代码放在 Before 你的第一个循环中:
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
而这个在您的操作结束时:
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
它将首先禁用屏幕更新、事件和公式重新计算,并在完成操作后重新启用它。
根据您正在进行的操作类型,我发现这可以将宏的速度优化高达 75%。
我最近一直在想,哪个在效率方面更好:使用多个 For 循环,还是一个包含许多操作的大循环?
我使用 SQL 数据库中 17 列的 50k-100k 行。
现在,代码示例:
z = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To z
If Cells(i, 15) <> 0 Then Cells(i, 19) = 1 Else Cells(i, 19) = 0
Next i
For i = 2 To z
Cells(i, 20) = Val(Left(Cells(i, 2), 2))
Next i
For i = 2 To z
Select Case Cells(i, 18).Value
Case Is = 1
Cells(i, 29).Value = 1
Case Is = 2
Cells(i, 29).Value = 1.6
Case Is = 3
Cells(i, 29).Value = 2.8
End Select
Next i
For i = 2 To z
Cells(i, 30) = Val(Right(Cells(i, 14), 1))
Next i
For i = 2 To z
Cells(i, 31) = ((Cells(i, 18) + 1) * Cells(i, 16) * Cells(i, 17)) / 1000000
Cells(i, 31).NumberFormat = "0.00"
Next i
我的问题是:按列(每列单独的 For 循环)或按行(一个包含每条记录的所有操作的大循环)执行这些操作是否更明智?
从整体上看,性能瓶颈在于数据记录的获取,而不在于循环的结构。
您最好以可读性为目标,而不是试图过度优化代码,因为代码对执行时间的贡献可以忽略不计。
如果您要用数据库中的记录验证 excel 中的记录,那么您可以应用大循环;但如果循环内有循环,我什至可以建议使用 find() 方法。 (Find() 方法可以提高性能)
您的代码会非常慢,因为您要对对象模型进行大量调用以从单个单元格中检索值。每次调用都会产生很大的开销。
将所有必需的值读入变体数组会更快:
dim vArr as variant
vArr=Range("A1").resize(z,31).value2
然后在将处理后的数组返回到工作表之前处理生成的二维数组
我支持 Bathsheba 关于瓶颈操作将会是什么。 但是,每当你有一个插入大量数据的长宏时,你可能希望将这段代码放在 Before 你的第一个循环中:
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
而这个在您的操作结束时:
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
它将首先禁用屏幕更新、事件和公式重新计算,并在完成操作后重新启用它。
根据您正在进行的操作类型,我发现这可以将宏的速度优化高达 75%。