VBA Excel:哪个更好更快:对一个范围使用一个变体矩阵还是对每一列使用多个数组?

VBA Excel: which one is better and faster: using one variant matrix for a range or several arrays for each column?

我需要使用基于行值的多个列中的值。创建变体矩阵数组并将所有列存储在该数组中然后从该数组中搜索和部署值,或者为每一列创建一个数组是否更好更快,考虑到可能有几千行并且值被多次使用?

示例:我们有以下数据:

如果此人在 2013 年 1 月 1 日之前加入,我想从股权中扣除到期金额。声明一个像

这样的变体数组更好吗?
Dim matrix() as Variant
Dim ws as Worksheet
Dim cols(4) as String: cols(0) = "A': cols(1) = "B": cols(2) = "C": cols(3) = "D"
Dim i as Integer
Dim b as Integer: b = 2 'beginning row
Dim j as Integer: j = 4 'number of lines

Set ws = Worksheets("Sheet1")

For i = 0 to UBound(cols)
  matrix(i) = Range(cols(i) & b & ":" & cols(i) & (b + j)).value2
End if

分别声明四个数组,如

Dim arr1() as String
Dim arr2() as Date
Dim arr3() as Integer
Dim arr4() as Integer

当然我也可以通过直接引用单元格来直接使用单元格中的数据,但是当我多次使用这个几千行数据时,将它们存储在数组中更有意义。

如果有很多列,一次将所有数据读入一个矩阵可能会明显更快。 Excel 和 VBA 之间的每次数据传输都会产生很大的开销。较大的数据传输并不比小数据传输慢多少,但是很多数据传输比单个传输慢很多。

这里有一个很好的细节来源:

Data transfer between worksheet cells and VBA variables is an expensive operation that should be kept to a minimum. You can considerably increase the performance of your Excel application by passing arrays of data to the worksheet, and vice versa, in a single operation rather than one cell at a time. If you need to do extensive calculations on data in VBA, you should transfer all the values from the worksheet to an array, do the calculations on the array, and then, possibly, write the array back to the worksheet. This keeps the number of times data is transferred between the worksheet and VBA to a minimum. It is far more efficient to transfer one array of 100 values to the worksheet than to transfer 100 items at a time.

http://www.cpearson.com/excel/ArraysAndRanges.aspx

将范围复制到数组,反之亦然

Option Explicit

Sub DeductDue()
    
    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    Dim ws As Worksheet: Set ws = wb.Worksheets("Sheet1")
    
    ' Reference the data (no headers) range ('rg').
    Dim rg As Range
    With ws.Range("A1").CurrentRegion
        Set rg = .Resize(.Rows.Count - 1).Offset(1)
    End With
    
    ' Write the values from columns 2-4 ('Date' to 'Due') to an array ('sData').
    Dim sData As Variant: sData = rg.Columns(2).Resize(, 3).Value
    
    ' Wrtie the values from column 6 ('Equity') column to an array ('dData').
    Dim dData As Variant: dData = rg.Columns(6).Value
    
    ' Loop through the rows of the arrays and calculate...
    Dim r As Long
    For r = 1 To rg.Rows.Count
        If Year(sData(r, 1)) < 2013 Then
            dData(r, 1) = dData(r, 1) - sData(r, 3)
        End If
    Next r
    
    ' Write the result to a column range, e.g.:
    rg.Columns(6).Value = dData ' overwrite Equity with the deducted values
    
End Sub