Друзья, по этому коду видно, что ReDim Preserve может менять верхнюю границу последней размерности многомерных размеров, но не может менять первую размерность.
Sub Test() Dim a() As Byte ReDim a(10, 20) ReDim Preserve a(10, 30) 'работает
ReDim a(10, 20) ReDim Preserve a(30, 30) 'не работает End Sub
Я немного изменил код того файла, чтобы он заработал в VBA, но не могу понять его логику
Public Type tArr a() As Long End Type
Dim a() As tArr Dim ArrX As Long, ArrY As Long
Sub Test() Dim X As Long, Y As Long, ArrTest() ReDim ArrTest(1 To 3, 1 To 5) ReDimArr UBound(ArrTest, 1), UBound(ArrTest, 2) 'передаём в функцю ReDimArr размерность нашего массива Randomize For Y = 0 To ArrY For X = 0 To ArrX a(X).a(Y) = Int(Rnd() * 100) Cells(Cells(Rows.Count, 1).End(xlUp).Row + 1, 1) = a(X).a(Y) Next X Next Y End Sub
Function ReDimArr(NewX As Long, NewY As Long) Dim i As Long ReDim Preserve a(0 To NewX) As tArr For i = 0 To NewX ReDim Preserve a(i).a(0 To NewY) As Long Next i ArrX = NewX ArrY = NewY End Function
Вопросов много 1) что делает функция ReDimArr 2) что за написание a(X).a(Y), которое нормально работает под VBA 3) если я передаю в функцию числа 3, 5, то почему на листе появляются 18 чисел.
Может быть есть функция или ещё что, чтобы можно было менять размер первой размерности массива?
Паш, на листе появляется 24 числа(4 х 6). Почему так? Массив а, это массив массивов а. В пошаговом режиме в макросе тест выдели а и занеси ее в Wathes. Получился массив размерностью 0 то 3(4) массивов размерностью 0 то 5(6).
но я тоже пытался таким же образом преодолеть след ситуацию:
обрабатывается некий массив в N столбцов и переменное количество( и очень большое) строк. результатом обработки является некая выборка из тех же N столбцов и неизвестного заранее количества строк..
лучше добавлять строки по мере необходимости, но это первая размерность, кот нельзя менять оператором redim preserve ( транспонировать тоже нельзя, так как операция transpose имеет ограничения)
вот тут и является выходом объявить одномерный массив из N элементов, но каждый элемент тоже является одномерным массивом.
но.. появляется N операций redim и результирующий массив нельзя просто выгрузить на лист.. а только поэлементно..
поэтому я пришел к другому решению:
объявляется индексный одномерный массив, в который записываются номера позиций, подлежащих выборке. Этот массив по мере необходимости наращивается redim preserve. по окончании обработки объявляем новый массив в N столбцов и количеством строк равным размерности индексного массива. и туда переписываем нужные позиции( можно не создавать нового массива, а писать прямо в старый, если он больше не потребуется, а на лист выводить только нужную часть этого массива)
слэн, так для такой задачи можно без redim preserve обойтись - используя словарь как индексный массив. Из практики помню, что redim preserve на больших объёмах работает небыстро, т.к. похоже что переписывает все данные в новый массив, а не дописывает новые данные в старый. Словарь думаю будет побыстрее.