Страницы: 1
RSS
Работа ReDim Preserve
 
Друзья, по этому коду видно, что 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  
 
 
Почитал тему http://www.vbnet.ru/forum/show.aspx?id=51884  
там в конце есть ссылка на файл с кодом для VB    
http://vbnet.ru/samples/download.aspx?id=691  
 
Я немного изменил код того файла, чтобы он заработал в 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 на больших объёмах работает небыстро, т.к. похоже что переписывает все данные в новый массив, а не дописывает новые данные в старый.  
Словарь думаю будет побыстрее.
 
можно и в словарь.. но дольше потом выборку переписывать.  
 
можно же не по одному значению массив наращивать, а по 99, например( или по 999)  
 
но лучшим арбитром, как всегда, будет практика.. надо попробовать.
Живи и дай жить..
 
да и выборка-то частенько как раз невелика - велик массив источник..
Живи и дай жить..
 
Вот за что я люблю javascript - никаких пересервов (ReDim Preserve). Изменять массив можно как угодно, вплоть до разреженности : )  
 
77144
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
это если не задумываться о фактических операциях..  
 
ну измените вы внутреннюю размерность массива, т.е. в памяти он теперь будет не сплошным полем, а фрагментировано..  
 
будете медленнее обращаться..
Живи и дай жить..
Страницы: 1
Читают тему
Наверх