Впервые столкнулся с таким сообщением, и не знаю, как решить проблему.
Итак, задача: сформировать всевозможные комбинации для лотереи "6 из 45", и вывести на листы Excel (не спрашивайте зачем это необходимо, не говорите, что это проанализировать невозможно, - ну надо человеку так...)
Всего комбинаций около 8 миллионов (в Excel 2007 - 8 листов, в Excel 2003 - 125 листов)
Увы, в 2003-м фокус не удался - макрос вылетает на создании 12-го листа (из 125!), говоря, что ресурсов недостаточно.
Вопрос: Как макросом в Excel 2003 создать файл из 125 листов, на каждом из которых будут полностью заполнены числами первые 6 столбов? (как не переполнить память?)
PS: Пробовал после создания каждого листа сохранять файл - эффекта не даёт.
Открыл (при помощи конвертера) в 2003. Сообщение получил при создании 16-го листа. Многократное дальнейшее нажатие на ОК в сообщении и все 125 листов созданы.
Не знаю, мож поможет. У меня такое было, когда я в цикле присваивал листы объектной переменной: For Each c In r.Cells Set sh = Worksheets(c.Value) ... обработка ... и не выполнял в конце: Set sh = Nothing Next Причем началось не сразу. Заказчик позвонил, что Экс вылетает с ошибкой. Начал гонять и у себя того же добился. Как только добавил: Set sh = Nothing все стало Ок.
Игорь, я думаю тут главная штука это оператива..., у меня объем потребленной оперативы приблизился к 1,5 гига вместе с своими ресурсами , и это в 2010 офисе, в формате xlsb, который как известно самый компактный.
> Сообщение получил при создании 16-го листа. Многократное дальнейшее нажатие на ОК в сообщении и все 125 листов созданы
Согласен, листы создаются (после 16-го), но пустые. (поскольку я поставил On Error Resume Next)
Если убрать игнорирование ошибок, макрос вылетает с ошибкой при попытке заполнения очередного листа. Так что вариант с нажатием OK на сообщении, увы, не подходит (т.е. пощелкать-то не проблема, но листы должны создаваться заполненные, а не пустые)
> Игорь, я думаю тут главная штука это оператива... Может быть, но сомневаюсь. Смотрел расходование ресурсов - Excel 2003 при выполнении этого макроса занимает совсем немного памяти, свободной ещё предостаточно. (хоть у меня на компе её всего 2 гига) Скорее всего, что-то внутри Excel переполняется. Проц, конечно, грузит (одно ядро занято полностью), но это не повод для Excel 2003 выдавать сообщение о нехватке ресурсов...
Есть предположение, что Excel запоминает историю изменений (чтобы там всякие Undo работали) Кто подскажет, как отключить это сохранение истории, или высвободить память.
Все варианты с Set sh = Nothing и подобным пробовал сразу же - не помогает. Да и не нужно обычно это всё - объект sh уничтожается при выходе из процедуры.
Если заказчика не устроит вариант под Excel 2007 (и с меня потребуют обязательное решение под 2003), попробую создавать в цикле новый файл из одного листа, заполнять его, и копировать заполненный лист в текущую книгу. Но сомневаюсь, что это сработает.
Касательно очистки внутренней памяти Excel из VBA - может кто что посоветует? (я ни разу с этим не сталкивался, поэтому даже не представляю, по каким запросам искать решение в гугле...)
У меня подобное случается с другим узкоспециализированным приложением. Там жесткая зависимость от оперативной памяти. С одним гигом ошибка выскакивает а с двумя гигами нет. И пишет мне эта сволочь, что недостаточно системных ресурсов для выполнения данной задачи
Я так понимаю все комбинации пишутся в столбик, почему бы не попробовать писать комбинации по всей пощаде листа, тогда вы не достигните критической отметки по количеству листов
{quote}{login=EducatedFool}{date=12.01.2012 10:25}{thema=}{post}Если всё на одном листе - то в Excel 2003 всё не влезет на лист Но, похоже, так и придётся сделать.
Пробовал заполненные листы копировать из других книг - не помогло, тоже на 16 листов хватило.{/post}{/quote}
на один не влезет, а на 3-4 листа влезет, это не 16 листов
Сергей, Игорь не может быть что бы у Вас не съедалась оператива ???? мои тесты: xlsb офис 2010 ОП до начала выполнения 842 мб , после завершения выполнения 1,55 гб , excel ~~ 700 mb так что я думаю связь очевидна........ 2003 нет возможности протестить, попозже попробую протестировать на сервере, где оперативы 32г хотя не знаю дадут ли sysadmin зверь :)
Доброе утро(день). Юр, тогда почему у всех валится на 16 листе? У Игоря 2г, у меня 4. И с ядрами то же. Больше похоже на заполнение какого-нить стека самого Экса.
Чтобы проверить источник ограничения, сам ли это Excel или код, можно создать один лист и вручную копировать его, пока не сбойнет (значит в Excel больше не влезает), или пока нужное количество листов не будет создано (значит нужно что-то менять в коде)
1. Если причина в Excel
1.1. Выводить результат не в 5 столбцов, а в один текстовый столбец, если Заказчик не против. По идее, 18 символов 6 групп по 2 символа с 5 пробелами должно быть экономнее с т.з. памяти, но это нужно проверить. Так как VarType(Range("A1")) выдает vbDouble при A1=1 а это 8 байт только на значение одной ячейки, и 48 байт на 6 ячеек плюс адрес и структура ячейки.
1.2. Если же Заказчик против, то он же не станет смотреть сразу 2 листа, поэтому можно заполнять только один лист данными при активации листа, в остальные листы очищать (возможны вариации).
1.3. Если п.1.2 медленный, то можно результат записывать в MDB, а при активации листа запросом считывать данные на активный лист, остальные очищать. Заказчик может и не заметить такой подмены.
2. Если причина в коде
2.1. Форму с прогресс-баром я бы на время тестирование все же отключил.
2.2. Можно сначала понасоздавать пустые листы, а затем их заполнять. Возможно, есть разница.
2.3. Можно кодом создать несколько листов, а затем по OnTime Now перезапускать код создания очередной порции листов, это позволит внутреннему менеджеру памяти Excel периодически убирать мусор.
Владимир, я это все пробовал, кроме п.1,1.1,1.2,1.3. Сократил к-во строк в arr до 100. Листы создал заранее. Выгружаю так: sh.[a1].Resize(UBound(arr), UBound(arr, 2)).Value = arr Все равно сыпется на 33 листе. Ну уж 100 строк * 6 столбцов - это пустяк для машины. Похоже это глюк версии.
{quote}{login=KukLP}{date=12.01.2012 12:57}{thema=}{post}Владимир, я это все пробовал, кроме п.1,1.1,1.2,1.3. Сократил к-во строк в arr до 100. Листы создал заранее. Выгружаю так: sh.[a1].Resize(UBound(arr), UBound(arr, 2)).Value = arr Все равно сыпется на 33 листе. Ну уж 100 строк * 6 столбцов - это пустяк для машины. Похоже это глюк версии.{/post}{/quote} Сергей, а копирование вручную получается? Если да, то форма, надеюсь, была отключена? Если еще раз да, то пункт 2.3 пробовали и не помогло? Если тоже да, по остается только п.1.2 - 1.3 Может, конечно, еще что-нибудь придумается :-)
Я уже изуродовал тот файл, он теперь при 60000 на первых листах валится:-) Вручную тоже "недостаточно...". В breakmode у него есть время подумать. Сейчас остановил макрос полностью и на попытку копировать 60000, тоже "недостаточно...". При этом ни память ни процессор не заняты.
Если увеличить количество заполняемых столбцов то все влезет :) мой потолок Sub test() For i = 1 To 14 Sheets.Add Range("a1:bz65536") = 11 Next End Sub 78*14*65536=71 565 312 ------------ если уменьшать кол-во столбцом (так на порядок), то добавляется и 15 страница
Вот еще заметил странный факт ?? при различных прогонах с различным вариантов столбцов, несколько раз кол-во заполненных столбцов равнялось 1024, при чем заполняло часть предложенного диапазона, но столбцы полностью. закономерности такой ситуции не нашел... больше чем 78 столбцов не заполнял.