在for循环或数组中处理Range值是否更为理想

时间:2017-01-09 23:51:30

标签: excel vba excel-vba loops for-loop

我想知道在Range中填充单元格有什么好处:

  • 检查我要填充的行数和列数,并使用For..Next循环访问单元格(请参阅下面的代码)或
  • 执行相同操作,但加载了单元格数据的Variant数组,或
  • 其他一些方法?

这是我的代码:

' Count number of rows and columns we have
rowCounter = CountRowsFunction
colCounter = CountColsFunction

' Do operations needed
For i = 2 To rowCounter
    originalSheet.Cells(i, colCounter + 1).Value = Round(DateDiff("n", originalSheet.Cells(i, ColumnsIndex(2)).Value, originalSheet.Cells(i, ColumnsIndex(3)).Value) / 60, 2)
Next i

在这种情况下,我直接访问单元格。但是,我相信这可能会导致不必要的传播。感谢

2 个答案:

答案 0 :(得分:3)

使用数组来设置多个单元格值非常优越。在下面的示例中,范围A1:MZ390(152100个单元格)使用两种方法设置:

  1. 将所有单元格设置为1;迭代单元格并将每个单元格值设置为2
  2. 将所有单元格设置为1;将范围分配给数组;迭代数组并将所有数组值设置为2;分配回范围
  3. 方法2花费不到一秒钟,方法1花费不到一秒钟。在我的电脑上4秒。

    在示例中,它迭代数组,但你可以使用更少的代码行,只做varData = 2 - 但人们不太可能想要将一堆单元格值设置为常量。

    Option Explicit
    
    Sub Test()
    
        Dim dt1 As Date, dt2 As Date
        Dim lngX As Long, lngY As Long
        Dim varData As Variant
        Dim ws As Worksheet
        Dim rng As Range
    
        'set ws
        Set ws = ThisWorkbook.Worksheets("Sheet1")
    
        'for loop method - without screen updating
        Application.ScreenUpdating = False
        ws.Cells.Delete
        Set rng = ws.Range("A1:MZ390")
    
        dt1 = Now
        rng.Value = 1
        For lngY = 1 To rng.Rows.Count
            For lngX = 1 To rng.Columns.Count
                rng.Cells(lngY, lngX).Value = 2
            Next lngX
        Next lngY
        dt2 = Now
        Application.ScreenUpdating = True
        Debug.Print "For loop (without screen updating) took: " & Format(dt2 - dt1, "s") & " seconds"
    
        'array method
        ws.Cells.Delete
        Set rng = ws.Range("A1:MZ390")
    
        dt1 = Now
        rng.Value = 1
        varData = rng.Value
        For lngX = 1 To UBound(varData, 1)
            For lngY = 1 To UBound(varData, 2)
                varData(lngX, lngY) = 2
            Next lngY
        Next lngX
        rng.Value = varData
        dt2 = Now
        Debug.Print "Array method took: " & Format(dt2 - dt1, "s") & " seconds"
    
    End Sub
    

答案 1 :(得分:1)

我认为数组效率更高,我在使用大量数据时会使用它们。

你可以使用这样的东西,在循环开始时添加一个断点,并使用locals窗口来查看数组a。

Dim a() As Variant
a = Range("a1:a10").Value

For i = 1 To UBound(a)

Next i