Страницы: 1 2 3 4 5 След.
RSS
RunTime Error 7 - Out of Memory
 
Добрый день!

Проблема в следующем: все данные с листа помещаю в массив, чтобы их быстрее обработать. На малых объемах все работает хорошо. На больших, близких к граничным, вылезает ошибка "RunTime Error 7 - Out of Memory".

Она вылезает или на ReDim массива, или на присвоении массиву диапазона с листа.

Что странно, так это ошибка не вылезает, если использую константу в 1 500 000 (строк), а если через переменную передаю 1048574 (строк), то вылезает. Это и взрывает мне мозг.

Запускаю функцию Sub StartTransferData() в модуле m2_Main2 в файле (48 Мб):
https://docs.google.com/file/d/0B_GHN7yiYuxELWVSSmJIM3VUczg/edit?usp=sharing

весит много, поэтому через гугл драйв.
Также прикладываю скриншот экрана после нажатия на Debug

Подскажите, пожалуйста, в чем может быть дело и как бороться.

Спасибо
Изменено: axtrace - 01.02.2013 18:08:48
 
LastRow=1'048'574, LastCol=16'384 всего 17'179'836'416 ячеек; даже всего по одному байту на ячейку - нужно не менее 16Г памяти только на массив.
Изменено: Михаил С. - 01.02.2013 18:54:26
 
Возможно, дело и не в объёме памяти, требуемой для массива,
а где-то в объявлении переменных.

Цитата
использую константу в 1 500 000 (строк)
А в коде написано 150 000
150 тыс - это совсем другое, нежели 1500 000


PS: Через Redim можно изменять только верхнюю размерность массива
А зачем вам 2 строки с Redim?
Уберите первую строку - и всё заработает
Изменено: EducatedFool - 01.02.2013 19:01:17
 
Цитата
EducatedFool пишет:
Через Redim можно изменять только верхнюю размерность массива
а что такое верхняя размерность массива?

Цитата
EducatedFool пишет:
А зачем вам 2 строки с Redim?
Уберите первую строку - и всё заработает
нет, не заработает. я ее специально добавил, чтобы показать, что если указывать размеры как числа, то все ок.
А если брать их из переменной, то вылетает ошибка.
 
Цитата
EducatedFool пишет:
PS: Через Redim можно изменять только верхнюю размерность массива
поправка.
с опцией Preserve.
да и то - не верхнюю, а самую последнюю.
здесь Preserve нет.
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
Цитата
axtrace пишет:
я ее специально добавил, чтобы показать, что если указывать размеры как числа, то все ок.
А Вы попробуйте присвоить LastRow значение = 1048574. И LastColumn = 15. Первую строку с ReDim Отключите. Что получится?
 
имхо, 48мб качать никто не будет.
предыдущая строка кода с 150000 строк в массиве - не "доказательство".
чему равно LastCol - тоже неизвестно.

кстати, размеры массива вообще нет нужды определять явно.
попробуйте так:
Код
Dim arr
arr = range(...).value
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
Цитата
Юрий М пишет:
А Вы попробуйте присвоить LastRow значение = 1048574. И LastColumn = 15. Первую строку с ReDim Отключите. Что получится?
Получилось, что при первом вызове функции getArrayFromSheet - той, в которой этот ReDim содержиться - проходит все успешно, но во втором вызове - я несколько массивов формирую с разных листов - опять вылетает та же ошибка. Хотя там точно также присваивается LastRow значение = 1048574. И LastColumn = 15
 
Цитата
ikki пишет: чему равно LastCol - тоже неизвестно.
Известно - число столбцов на листе
 
Цитата
Михаил С. пишет: Известно - число столбцов на листе
нет.
в приведенном фрагменте - зависит от данных во второй строке.
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
Утечка памяти? Попробуйте убить массив.
 
Цитата
Михаил С. пишет: Известно - число столбцов на листе
Михаил, не совсем так: это последняя ячейка (номер столбца) по второй строке.
 
Цитата
Юрий М пишет: Утечка памяти? Попробуйте убить массив.
может быть. а как убивают массивы?
только если утечка, после перезагрузки и запуска только excel, все должно было быть чисто и хотя бы раз отработать нормально, но нет - все-равно ошибка. Правда, она то на ReDim, а то на следующей строчке с присваиванием:

nArray = tSheet.Range(tSheet.Cells(1, 1), tSheet.Cells(LastRow, LastCol))
 
Вы сначала объясните - зачем дважды ReDim с одним и тем же nArray?
 
Попробуйте объявлять процедуру так:
Код
getArrayFromSheet(tSheet As Worksheet)

и раскомментируйте строки с объявлением массива и назначением его через функцию. Или массив объявите глобально.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
вообще-то странно  :(
вот у меня 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 - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
Саш, да вообще нужно, как ты советовал:
Код
Dim nArray()
nArray = Range(Cells(1, 1), Cells(lastrow, lastcolumn)).Value
 
Цитата
Юрий М пишет: Вы сначала объясните - зачем дважды ReDim с одним и тем же nArray?
   
Код
'этот ReDim, чтобы показать что на таких же размерах все работает. Он не нужен в программе, просто показываю, что если так указать, то все ок. Его я удалю. Поставил его после обнаружения ошибки. На нем ошибки нет
   ReDim nArray(1 To 1500000, 1 To 15) As Variant
    
'это основной ReDim, он будет и дальше. Он динамически расширяет массив в зависимост от размеров данных на листе, которые туда будут помещаться. 
       ReDim nArray(1 To LastRow, 1 To LastCol) As Variant
Первый - для примера. На нем не вылезает ошибка.
А вот на втором - вылезает, даже если первый закомментен. Может быть это поможет локализовать проблему.
 
Цитата
axtrace пишет:
Он динамически расширяет массив в зависимост от размеров данных на листе, которые туда будут помещаться.
Так и объявляйте сразу динамический массив (см. мой пост выше) - и ReDim'мить не придётся.
 
Цитата
axtrace пишет: этот ReDim, чтобы показать что на таких же размерах все работает.
Неправда - совсем разные размеры.
 
Цитата
Юрий М пишет:
Dim nArray()
nArray = Range(Cells(1, 1), Cells(lastrow, lastcolumn)).Value
то есть просто убрать ReDim? Я так сделал, у меня в массив записалось <Out of memory>, программа благополучно продолжила работать, но вылезла ошибка о несуществовании объекта в дальнейшем, при попытке перенести данные из этого массива в другой
 
Цитата
Юрий М пишет: Неправда - совсем разные размеры.
я опечатался, вместо 1 500 000 указал 150 000. В файле уже исправил, все равно этот ReDim берет, на втором - ошибка
 
Цитата
axtrace пишет: то есть просто убрать ReDim?
Объявите массив, как указано, и присвойте ему значения из диапазона листа - никакой ошибки быть не должно. Не "просто убрать RedIm", а записать: массив = ...
 
Цитата
ikki пишет: но если я меняю константу m на 600000 - то уже при создании 3-го массива вылетает out of memory
может быть это ограничение разметки памяти в vba?
 
Я полагаю проблема в том, что массив передается в процедуру ссылкой. А в этом случае память не высвобождается - VBA считает, что мы вроде как далее будем использовать переменную. И при повторном обращении с передачей ссылки у нас выделенный размер памяти может "слегка" увеличиватся.
В общем попробуйте объявить массив глобально и в процедуре просто переназначать ему значения.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
А мне кажется, дело в простой нехватке физической памяти. Например, такой массив
Код
Sub test()
ReDim a(1000000, 30) As Byte
End Sub
на моем компе (win7, off 2010, 2 G) срабатывает, а такой
Код
Sub test()
ReDim a(1000000, 30) 
End Sub
-  "RunTime Error 7 - Out of Memory"
 
Цитата
The_Prist пишет: И при повторном обращении с передачей ссылки у нас выделенный размер памяти может "слегка" увеличиватся
там же только адрес, откуда вызывается и адреса памяти массивов (по ссылке передаются параметры функции). это вроде бы немного.
я попробовал, не помогло  :(  Все работает так же, как раньше.
 
Цитата
Михаил С. пишет:  моем компе (win7, off 2010, 2 G)
странно. у меня win7, off2010, 4Gb
файл подкачки - 3,6 Gb
 
попробую я, в общем, делать кусками. Брать массив тысяч в 100 строк, преобразовывать его, записывать на новый лист, переходить к следующим 100 тыс. строк... Время, конечно, увеличится. Но хоть какое-то решение у меня будет.

все большое спасибо за идеи! Надеюсь, вам пригодится где-нибудь когда-нибудь :)
 
Добрый День!
Помогите пожалуйста. У меня тоже эта  проблема но Excel 2016 ошибку тоже даёт Redim
на  111 533 строках и 1635 столбцах
Код
Dim text_word2() As Variant
x=1635
 ReDim text_word2(0 To kki, 0 To x)

Как решили прошлую проблему?
одинокий странник
Страницы: 1 2 3 4 5 След.
Наверх