#arrays #vba #multidimensional-array
#массивы #vba #многомерный-массив
Вопрос:
Как я могу добавить дополнительный элемент в 2d-массив в VBA? Рабочий пример:
sub test
Dim arr As Variant, ix as variant
arr = Array( _
Array("01probe", 1, 2, True), _
Array("02datum", 3, 4) _
)
'... lots more
' true optional, nothing or just "false" as alternative
For Each ix In arr
Debug.Print ix(3) '<---- index out of range
Next ix
end sub
Спасибо всем
Комментарии:
1. Для пояснения я не голосовал против, но могу я спросить, чего вы пытаетесь достичь? Я имею в виду, почему не пользовательский объект, где вы можете получить доступ к его свойствам по отдельности, а затем иметь массив этого объекта?
2. С
array
это может быть проще вместо объекта. В настоящее время я заполняю внутренний 4-й элементfalse
, если он не используется.
Ответ №1:
Ваш массив не относится к типу 2D. Это массив массивов (неровный массив)…
Но я не могу представить, зачем нужен необязательный параметр.
Если ваш массив объявлен As Variant
, он может содержать переменные любого типа, включая объекты. Также нет необходимости объявлять его размеры. Все можно рассмотреть Optional
…
Посмотрите следующий код, пожалуйста:
Sub testOptionalArray()
Dim arr As Variant, dbInteger As Integer, strProbeNr As Long, rng As Range
Dim rng2 As Range, dbDate As Date, dDate As Date
dbInteger = 11: strProbeNr = 1000: dbDate = Date 1: dDate = Now
Set rng = Range("A1:A2"): Set rng2 = Range("B1:B2")
arr = Array( _
Array("01probe", dbInteger, strProbeNr, rng), _
Array("02datum", dbDate, dDate, rng2))
Debug.Print arr(0)(1), arr(0)(3).cells(1, 1).value
Debug.Print arr(1)(1), arr(1)(UBound(arr(1))).cells.count, arr(1)(UBound(arr(1))).Address
End Sub
Отредактировано, после того, как вы опубликовали свой код, возвращающий ошибку:
Обсуждаемый код следует понимать следующим образом. Во-первых, было бы хорошей привычкой всегда надлежащим образом объявлять все переменные…
Sub testJaggedArray()
Dim arr As Variant, ix As Variant
arr = Array( _
Array("01probe", 1, 2, True), _
Array("02datum", 3, 4))
'The above array must be understood like an array of two arrays,
'first of them having 4 elements (ubound = 4, because it starts from 0)
' and a second one with only 3 elements.
For Each ix In arr
'When your code tries to print the fourth element of an array with only
'three elements, of course VBA return 'subscript out of range'.
Debug.Print ix(3) '<---- subscript out of range
Next ix
'You can return an element of an array inside a jagged array in this way:
Debug.Print arr(1)(ubound(arr(1)))' which means returning of the last element
' of the second array without returning an error
'You may use an array of two arrays having different number of element,
'but you cannot expect to an array to return an INEXISTENT item.
'There is no any connection between an hypothetical need of OPTIONAL element.
'It is only a matter of EXISTING element...
End Sub
Комментарии:
1. Массив объявлен как вариант. Вы не поняли мою точку зрения, я хочу исключить rng2. Причиной не заполнения необязательного параметра является лень.
Everything can be optional
: Нет, я получаюindex out of range
вforeach
.2. @Timo: Откуда берется «индекс вне диапазона»? Пытаетесь использовать мой приведенный выше код?
3. @Timo: Не стал бы я просить слишком многого, если бы предложил вам отредактировать ваш вопрос и поделиться
foreach
кодом, в котором вы получаете вышеупомянутую ошибку?4. @Timo : Спасибо! Но, возвращаясь к вашему вопросу, можете ли вы прояснить вышеупомянутые проблемы? Я могу признать, что было бы невозможно не заметить вашу точку зрения. Вот почему, не могли бы вы лучше определить это, пожалуйста? Если это не интересно, у меня тоже не будет проблем…
5. @Timo: Я не уверен, что вы понимаете значение кода, который вы запускаете… Дело не в
Optional
параметре. Вы имеете дело с неровным массивом, и ваш код пытается напечатать несуществующий элемент массива . Я отредактирую приведенный выше ответ и попытаюсь объяснить…
Ответ №2:
С помощью FaneDuru я получил решение для зацикливания массива с разными размерами внутреннего массива без ошибок:
sub test
Dim arr As Variant, i as integer
arr = Array( _
Array("01probe", 1, 2, True), _
Array("02datum", 3, 4) _
)
'... lots more
For i = LBound(arr) To UBound(arr)
Debug.Print (arr(i)(UBound(arr(i))))
Next i
end sub