Как настроить "зубчатый массив" в VBA?
У меня есть класс, полный детей, каждый из которых должен перечислить свои любимые игрушки для задания. Некоторые дети перечисляют только одну игрушку, тогда как другие перечисляют больше.
Как создать зубчатый массив, так что Kids (x) (y)... где x - количество детей в моем классе, а y - список игрушек, которые они перечисляют в качестве избранных?
Ответы
Ответ 1
"Jagged array" - это сленг для массива массивов. Тип данных Variant
VBA может содержать только что-нибудь *, включая массив. Таким образом, вы создаете массив типа 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 toy #7:
MsgBox toys(3)(7)
'will throw an error if student #3 has less than 7 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
Ответ 3
Жан-Франсуа отметил, что каждый элемент может быть массивом различной длины. Я бы добавил, что каждый элемент также может быть другого типа и не должен быть массивом. Например:
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) также будет работать. Одна строка для каждого ребенка и один столбец для каждого присутствующего. Размеры массива будут (# детей, MAX # из подарков), и это просто означает, что некоторые из слотов будут пустыми или 0 (в зависимости от вашего типа данных). Но по крайней мере таким образом вам не нужно будет переустанавливать массив каждый раз, когда вы добавляете подарок для ребенка.