【问题标题】:How do I set up a "jagged array" in VBA?如何在 VBA 中设置“锯齿状数组”?
【发布时间】:2012-03-15 04:33:29
【问题描述】:

我的教室里挤满了孩子,每个人都必须列出他们最喜欢的玩具来完成作业。有些孩子只列出 1 个玩具,而其他孩子列出更多。

如何创建一个锯齿状数组,使得 Kids(x)(y)...其中 x 是我班上孩子的数量,y 是他们最喜欢的玩具列表?

【问题讨论】:

标签: arrays vba jagged-arrays


【解决方案1】:

“Jagged array”是数组数组的俚语。 VBA 的Variant 数据类型可以包含几乎任何东西*,包括数组。因此,您创建了一个Variant 类型的数组,并为其每个元素分配一个任意长度的数组(即并非所有元素都必须具有相同的长度)。

这是一个例子:

Dim nStudents As Long
Dim iStudent As Long
Dim toys() As Variant
Dim nToys As Long
Dim thisStudentsToys() As Variant

nStudents = 5 ' or whatever

ReDim toys(1 To nStudents) ' this will be your jagged array

For iStudent = 1 To nStudents
    'give a random number of toys to this student (e.g. up to 10)
    nToys = Int((10 * Rnd) + 1)
    ReDim thisStudentsToys(1 To nToys)

    'code goes here to fill thisStudentsToys()
    'with their actual toys

    toys(iStudent) = thisStudentsToys
Next iStudent

' toys array is now jagged.

' To get student #3's toy #7:
MsgBox toys(3)(7)
'will throw an error if student #3 has less than 7 toys

* 一个值得注意的例外是用户定义类型。变体不能包含这些。

【讨论】:

  • 当您重新调整thisStudentsToys 时,是否创建了一个新的内存位置?我认为 VBA 中的数组是引用。我只是想仔细检查一下:在 for 循环的第二次迭代中,重写 thisStudentsToys 数组不会改变 toys 的第一个索引?如果我没有说清楚,请告诉我。谢谢
【解决方案2】:

你可以使用集合的集合

Public Sub Test()

    Dim list As New Collection
    Dim i As Integer, j As Integer
    Dim item As Collection
    For i = 1 To 10
        Set item = New Collection
        For j = 1 To i
            item.Add "Kid" & CStr(i) & "Toy" & CStr(j)
        Next j
        list.Add item
    Next i

    Debug.Print "Kid 4, Toy 2 = " & list(4)(2)
End Sub

哪个输出Kid 4, Toy 2 = Kid4Toy2

【讨论】:

  • 我不熟悉的集合集合与数组数组或锯齿数组有何不同?
  • 您可以从集合中添加和删除项目,但不能从数组中添加和删除项目。如果需要,除了索引之外,您还可以使用键访问项目。也许您使用孩子的姓名或 ID 作为集合的键。
【解决方案3】:

Jean-Francois 指出,每个元素都可以是一个可变长度的数组。我要补充一点,每个元素也可以是其他类型,不必是数组。例如:

Dim c as New Collection
Dim a(1 to 5) as Variant

c.Add "a","a"
c.Add "b","b"
a(1) = 5
a(2) = Array(2,3,4)
set a(3) = c
a(4) = "abcd"
a(5) = Range("A1:A4").Value

然后可以根据每个子元素的隐式类型来引用各种子元素:

a(2)(1) = 3

a(3)(1) = "a"

a(5)(2,1) = 单元格 A2 中的任何内容。

【讨论】:

    【解决方案4】:

    您还可以将玩具列表连接成例如管道分隔的字符串,然后在需要时使用 Split 将字符串转换为数组:

    Sub UntangleTheString()
    
    Dim sToys As String
    Dim aToys() As String
    Dim x As Long
    
    sToys = "baseball|doll|yoyo"
    
    aToys = Split(sToys, "|")
    
    For x = LBound(aToys) To UBound(aToys)
        Debug.Print aToys(x)
    Next
    
    End Sub
    

    【讨论】:

      【解决方案5】:

      您不一定需要锯齿状数组来处理您的场景,因为 2D 数组 (r, c) 也可以。每个孩子一行,每个礼物一列。数组维度将是(# of children, MAX # of present),它只是意味着一些插槽将为空或 0(取决于您的数据类型)。但至少这样你就不需要在每次为孩子添加礼物时重新调整数组了。

      【讨论】:

        猜你喜欢
        • 2015-05-06
        • 2013-04-21
        • 2021-05-04
        • 1970-01-01
        • 2017-05-06
        • 2013-04-04
        • 2016-06-17
        • 2019-06-12
        • 1970-01-01
        相关资源
        最近更新 更多