如何将Excel范围分配给2D数组?

时间:2012-12-26 03:43:44

标签: excel-vba vbscript vba excel

请问 - 如何将Excel范围(“G2:AA1000”)分配给2D阵列?如果可能的话,如何在对该2D阵列执行某些操作后将该2D阵列返回到相同的范围?将一个Range分配给2D阵列后,如何从该2D矩阵中识别每一行?

谢谢,

4 个答案:

答案 0 :(得分:3)

有一种简单的方法可以使用数组更改区域,并将其写入相同位置或其他位置。

此示例代码将使用数组将数据从一个区域复制到另一个区域:

Sub example()
Dim testdata()
testdata = Range("A1:B13")
Range("D1:E13") = testdata ' simple copy
Range("G1") = testdata ' copy only 1 cell
Range("I1:K22") = testdata 'try to copy too much
End Sub

testdata数组从 1 开始,并将扩展到范围中指定的列数和行数。在这种情况下,testdata(1,1)是指从 A1 获得的数据,testdata(1,2)是指 B1 ,最后是testdata(13,1)指的是 A13 testdata(13,2)指的是 B13

将范围设置为等于下一行中的数组会将数组复制到指定位置。

  • 如果区域小于原始数组,则只会复制足够的数组以填充该空间,因此Range("D1")=testdata只会在工作表上放置一个单元格。
  • 如果指定更大的区域,则 #N / A 将填充不在数组元素所覆盖的空间中的区域,因此Range("A1:A3")=testdata将使用数据填充A1和A2从阵列中,但A3将具有 #N / A

示例程序的结果:
注意:A1:B13是原始数据,随后的range(??)=testdata复制 Result of above code

答案 1 :(得分:1)

这是一个从工作表中读取一系列数据,在数组上运行,然后将其写回同一工作表的实例。

    Sub RangeArray()

    Dim Rng As Range
    Dim Arr()
    Dim ArrItem
    Dim i As Long, j As Long
    Dim rUB as Long, cUB as Long

     Set Rng = Worksheets("Sheet1").Range("A1:G19")
    rUB = Rng.Rows.Count    'Row upper bound
    cUB = Rng.Columns.Count  ' Column upper bound

    ReDim Arr(1 To rUB, 1 To cUB)

   'Read worksheet range into array
    For i = 1 To rUB
       For j = 1 to cUB
          Arr(i, j) = Rng.Cells(i, j).Value
       Next
    Next

   'Do something to array 
    For i = 1 To rUB
       For j = 1 To cUB
          If i <> j Then
             Arr(i, j) = Arr(i, j) / (i * j)
          End If
       Next
    Next

   'Write array back to worksheet
    Set Rng = Worksheets("Sheet1").Range("I1")
    For i = 1 To rUB
       For j = 1 To cUB
          Rng.Offset(i - 1, j - 1).Value = Arr(i, j)
       Next
    Next

    End Sub

答案 2 :(得分:1)

是的,Excel 范围可以在一次分配中分配给二维数组。在 C++/CLI 中,它看起来像这样:

cli::array^ arrData = safe_cast^>(rg->Value[Excel::XlRangeValueDataType::xlRangeValueDefault]); 在 c# 或 Visual Basic 中,它看起来要简单得多(参见此处的示例 https://www.automateexcel.com/vba/assign-range-to-array/,顺便说一下,在 dotnet 中,该对象现在扮演了变体数据类型的角色)。请注意,它必须是二维数组,并且返回的数组具有基于 1 的索引,而不是基于 0 的索引。

对于大型数据集,此方法比循环快得多。循环会生成大量 COM 对象。我将这两种方法与 33000 行 Excel 范围进行了比较,将数据导入数组几乎是即时的,而循环需要很长时间,并且会加热 CPU。

答案 3 :(得分:0)

循环范围的一种方法是使用带有Cells属性的For ... Next循环。使用Cells属性,可以将循环计数器(或其他变量或表达式)替换为单元索引号。在以下示例中,变量计数器替换行索引。程序循环通过范围C1:C20,设置为0(零)任何绝对值小于0.01的数字。

Sub RoundToZero1()
    For Counter = 1 To 20
        Set curCell = Worksheets("Sheet1").Cells(Counter, 3)
        If Abs(curCell.Value) < 0.01 Then curCell.Value = 0
    Next Counter
End Sub