【问题标题】:VBA: using multiple For loops, or one big?VBA:使用多个 For 循环,还是一个大循环?
【发布时间】:2015-01-29 03:21:42
【问题描述】:

我最近一直想知道哪个在效率方面更好:使用多个 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 循环)还是按行(一个包含每条记录的所有操作的大循环)执行这些操作更明智?

【问题讨论】:

    标签: vba excel for-loop


    【解决方案1】:

    从整体上看,性能瓶颈在于数据记录的获取,而不是循环的结构。

    您最好以可读性为目标,而不是试图过度优化对执行时间的影响可以忽略不计的代码。

    【讨论】:

    • 感谢您的意见!我同意可读性实际上是一个重要的问题,我只是想知道性能改进是否足够显着以牺牲前者。据我了解,答案是“不”,所以我将保持我的代码不变:)
    【解决方案2】:

    您的代码会非常慢,因为您要对对象模型进行大量调用以从各个单元格中检索值。每次调用都会产生大量开销。

    将所有需要的值读入变量数组会更快:

    dim vArr as variant
    vArr=Range("A1").resize(z,31).value2
    

    然后在将处理后的数组返回到工作表之前处理生成的二维数组

    【讨论】:

      【解决方案3】:

      如果您正在使用数据库中的记录验证 excel 中的记录,那么您可以应用大 for 循环;但如果循环内有循环,我什至可以建议使用 find() 方法。 (Find() 方法可以提高性能)

      【讨论】:

      • 一点也不,初始数据保持不变,我将这些循环的输出用于以后生成的数据透视表。如果我发现自己需要验证,我会记住这一点:)
      【解决方案4】:

      我第二次 Bathsheba 关于瓶颈操作将是什么。 但是,每当您有一个插入大量数据的长宏时,您可能希望将这段代码放在您的第一个循环之前:

      Application.ScreenUpdating = False 
      Application.Calculation = xlCalculationManual
      Application.EnableEvents = False
      

      在您的操作结束时

      Application.ScreenUpdating = True
      Application.Calculation = xlCalculationAutomatic
      Application.EnableEvents = True
      

      它将首先禁用屏幕更新、事件和公式重新计算,并在完成操作后重新启用。

      根据您正在执行的操作类型,我发现这可以将宏的速度优化高达 75%。

      【讨论】:

      • 我在宏的开头有这个:Application.ScreenUpdating=FalseApplication.DisplayAlerts=False(用于自动删除临时工作表)。我不使用表格内的公式,我猜这是 Application.Calculation 负责的?
      猜你喜欢
      • 2021-02-13
      • 1970-01-01
      • 2021-07-17
      • 2013-08-07
      • 2023-03-18
      • 2013-10-24
      • 2018-08-24
      • 2017-02-10
      • 2020-07-22
      相关资源
      最近更新 更多