Проблема в следующем: все данные с листа помещаю в массив, чтобы их быстрее обработать. На малых объемах все работает хорошо. На больших, близких к граничным, вылезает ошибка "RunTime Error 7 - Out of Memory".
Она вылезает или на ReDim массива, или на присвоении массиву диапазона с листа.
Что странно, так это ошибка не вылезает, если использую константу в 1 500 000 (строк), а если через переменную передаю 1048574 (строк), то вылезает. Это и взрывает мне мозг.
EducatedFool пишет: Через Redim можно изменять только верхнюю размерность массива
а что такое верхняя размерность массива?
Цитата
EducatedFool пишет: А зачем вам 2 строки с Redim? Уберите первую строку - и всё заработает
нет, не заработает. я ее специально добавил, чтобы показать, что если указывать размеры как числа, то все ок. А если брать их из переменной, то вылетает ошибка.
Юрий М пишет: А Вы попробуйте присвоить LastRow значение = 1048574. И LastColumn = 15. Первую строку с ReDim Отключите. Что получится?
Получилось, что при первом вызове функции getArrayFromSheet - той, в которой этот ReDim содержиться - проходит все успешно, но во втором вызове - я несколько массивов формирую с разных листов - опять вылетает та же ошибка. Хотя там точно также присваивается LastRow значение = 1048574. И LastColumn = 15
Юрий М пишет: Утечка памяти? Попробуйте убить массив.
может быть. а как убивают массивы? только если утечка, после перезагрузки и запуска только excel, все должно было быть чисто и хотя бы раз отработать нормально, но нет - все-равно ошибка. Правда, она то на ReDim, а то на следующей строчке с присваиванием:
вообще-то странно вот у меня winXP, Excel 2003, RAM 3Gb, доступно чуть более 2Gb массив из 10млн элементов типа Variant занимает ок. 153 Mb вот такой код отрабатывает:
Код
Sub t()
Const m& = 500000
Dim a, b, c, d, e, f
ReDim a(1 To m, 1 To 20) As Variant
ReDim b(1 To m, 1 To 20) As Variant
ReDim c(1 To m, 1 To 20) As Variant
ReDim d(1 To m, 1 To 20) As Variant
ReDim e(1 To m, 1 To 20) As Variant
ReDim f(1 To m, 1 To 20) As Variant
End Sub
вполне штатно - в диспетчере задач при пошаговом режиме выделение памяти увеличивается по 150+ метров... по завершении процедуры - всё самоубивается (массив локальный). но если я меняю константу m на 600000 - то уже при создании 3-го массива вылетает out of memory при этом "выделенная память" выросла от 620М до примерно 1Г а в первый раз - благополучно до 1,6Г
фрилансер Excel, VBA - контакты в профиле "Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
Юрий М пишет: Вы сначала объясните - зачем дважды ReDim с одним и тем же nArray?
Код
'этот ReDim, чтобы показать что на таких же размерах все работает. Он не нужен в программе, просто показываю, что если так указать, то все ок. Его я удалю. Поставил его после обнаружения ошибки. На нем ошибки нет
ReDim nArray(1 To 1500000, 1 To 15) As Variant
'это основной ReDim, он будет и дальше. Он динамически расширяет массив в зависимост от размеров данных на листе, которые туда будут помещаться.
ReDim nArray(1 To LastRow, 1 To LastCol) As Variant
Первый - для примера. На нем не вылезает ошибка. А вот на втором - вылезает, даже если первый закомментен. Может быть это поможет локализовать проблему.
Юрий М пишет: Dim nArray() nArray = Range(Cells(1, 1), Cells(lastrow, lastcolumn)).Value
то есть просто убрать ReDim? Я так сделал, у меня в массив записалось <Out of memory>, программа благополучно продолжила работать, но вылезла ошибка о несуществовании объекта в дальнейшем, при попытке перенести данные из этого массива в другой
Объявите массив, как указано, и присвойте ему значения из диапазона листа - никакой ошибки быть не должно. Не "просто убрать RedIm", а записать: массив = ...
Я полагаю проблема в том, что массив передается в процедуру ссылкой. А в этом случае память не высвобождается - VBA считает, что мы вроде как далее будем использовать переменную. И при повторном обращении с передачей ссылки у нас выделенный размер памяти может "слегка" увеличиватся. В общем попробуйте объявить массив глобально и в процедуре просто переназначать ему значения.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
The_Prist пишет: И при повторном обращении с передачей ссылки у нас выделенный размер памяти может "слегка" увеличиватся
там же только адрес, откуда вызывается и адреса памяти массивов (по ссылке передаются параметры функции). это вроде бы немного. я попробовал, не помогло Все работает так же, как раньше.
попробую я, в общем, делать кусками. Брать массив тысяч в 100 строк, преобразовывать его, записывать на новый лист, переходить к следующим 100 тыс. строк... Время, конечно, увеличится. Но хоть какое-то решение у меня будет.
все большое спасибо за идеи! Надеюсь, вам пригодится где-нибудь когда-нибудь