【问题标题】:How to create multi-dimensional array of unknown size?如何创建未知大小的多维数组?
【发布时间】:2019-08-17 05:07:47
【问题描述】:

我有一个简单的问题:

  • 我有一组数据,我正在筛选并在条件匹配时添加到数组中
  • 问题是,我不知道可能有多少匹配,所以我需要数组的大小未指定。
  • 数组的第二个索引是静态的。

在一个(伪语言)示例中:

if <matched criteria> = True {
    i = i + 1
    array( i,  1 ) => "John Doe" ' name
    array( i,  2 ) => "New York" ' location
    array( i,  3 ) => "02. 08. 1992" ' birthdate
}

问题是,在 中,您必须预先声明数组(尤其是在启用Option Explicit 的情况下)。我的想法是声明一个数组,它会从0 的第一个索引开始,我会根据需要逐渐ReDim

这是我的代码的简化示例:

Dim cell as Range
Dim arr(0, 1 to 3) as String
Dim i As Integer: i = 0

For each cell in Range("A1:A100")
  If criteria_match(cell) = True Then
      arr(i, 1) = Cells(cell.row, 4)
      arr(i, 2) = Cells(cell.row, 5)
      arr(i, 3) = Year(Cells(cell.row, 6))
      i = i + 1
      ReDim Preserve arr(i, 1 to 3)
  End If
Next cell

问题是,这会引发异常:

有没有什么办法,我可以根据需要稳步增加第一个数组索引的大小?

【问题讨论】:

  • 我建议使用嵌套的一维数组结构,如果需要,可以使用Denestify()将其转换为二维数组

标签: vba arrays excel vba multidimensional-array resize


【解决方案1】:

不要在变量声明语句中调整数组大小。

变化:

Dim arr(0, 1 to 3) as String

到:

Dim arr() as String
ReDim arr(1 to 3, i)

根据需要重新调整它。

编辑: 欲了解更多信息,请参阅此链接:https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/array-already-dimensioned

简单总结一下,当您在声明语句中调整数组大小时,它会创建一个静态数组(无法调整大小)。当你不声明一个大小时,它就变成了一个动态数组,可以调整大小。


需要注意的重要一点:ReDim Preserve 只能应用于数组的最后一维

例如。 ReDim Preserve arr(1 to 3, i) 会起作用。
同时,ReDim Preserve arr (i, 1 to 3) 不会。

【讨论】:

  • 啊,是的。有趣的是,我实际上浏览了文档,甚至已经找到了这个链接,但我认为Dim arr() As String 仅代表一维数组的动态定义。我试过arr( , ) As String 但这导致了错误。不管怎样,现在明白了,谢谢
  • 请注意,您只能 Redim 保留数组的最后一维:因此您必须转置数组以使 i 成为最后一维
  • 嗯,是的,我只是根据评论将数组移动到其他位置并且它可以工作,但也许它会好奇地调查一下,如果有可能以某种方式确定数组的尺寸,所以第一个索引是动态的,第二个是静态的
  • 我猜,最简单的方法就是直接Transpose
  • @Rawrplus WorksheetFunction.Transpose 一直工作到数组长度为 2^16,然后只能通过循环转置,这要慢得多。
【解决方案2】:

根据类型对数据使用类型,对变量使用集合。

Class Person

Public Name As String
Public Location As String
Public DoB As Date

在一个模块中

Sub Test()

    Dim this_person As Person
    Dim Persons As Collection
    Dim my_cell                 As Excel.Range
    Set Persons = New Collection

    For Each my_cell In Range("A1:A100")

      If Criteria_Match(my_cell) Then

        Set this_person = New Person
        With this_person

            .Name = ActiveWorkbook.ActiveWorksheet.Cells(my_cell.Row, 4).Value2
            .Location = ActiveWorkbook.ActiveWorksheet.Cells(my_cell.Row, 5).Value2
            .DoB = Year(ActiveWorkbook.ActiveWorksheet.Cells(my_cell.Row, 6).Value2)

        End With

        Persons.Add this_person

      End If

    Next

End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-06
    • 2019-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-20
    相关资源
    最近更新 更多