Недостаточно памяти для макроса

Обновлено: 05.07.2024

  1. Загрузите DriverFix (проверенный файл загрузки).
  2. Нажмите «Начать сканирование», чтобы найти все проблемные драйверы.
  3. Нажмите «Обновить драйверы», чтобы получить новые версии и избежать сбоев в работе системы.
  • DriverFix в этом месяце скачали 502 786 читателей.

Если вы работаете в организации, на вашем компьютере, скорее всего, установлена ​​последняя версия пакета Microsoft Office или Office 365. Даже если вы этого не сделаете, маловероятно, что вы никогда раньше не слышали о Microsoft Excel.

1 Проверьте содержимое таблицы

  • Вставка строки или столбца
  • Выполнение расчетов
  • Копирование и вставка
  • Сортировка
  • Открытие или закрытие книги
  • Запуск VBA
  • Перепроверьте формулы
  • Перепроверьте расчеты
  • Избегайте использования лишних форм
  • Избегайте использования сложных сводных таблиц
  • Старайтесь не использовать макросы и сложные диаграммы с большим количеством точек данных.

2 Проверьте свои надстройки Excel

Если вы считаете, что надстройка Excel вызывает ошибку, попробуйте отключить ее, а затем проверьте, появляется ли ошибка снова.

3 Проверьте Excel или установите последние обновления

  1. Щелкните правой кнопкой мыши кнопку Пуск
  2. Во всплывающем меню выберите «Приложения и функции».
  3. Выберите Microsoft Excel и выберите Изменить.

В зависимости от того, является ли ваша копия Office «нажми и работай» или установлена ​​на основе MSI, следующие шаги могут немного отличаться.

3.1. Нажми и работай

Появится окно с названием Как вы хотите восстановить свои программы Office.

  1. Выберите Online Repair
  2. Выберите «Восстановить», чтобы убедиться, что все исправлено.
    • Вариант быстрого восстановления работает быстрее, но он только обнаруживает, а затем заменяет поврежденные файлы

ИСПРАВЛЕНИЕ: Microsoft Excel ошибки нехватки памяти

3.2. На базе MSI

  1. В разделе “Изменить установку” выберите ” Восстановить”.
  2. Нажмите ” Продолжить”.
  3. Следуйте данной инструкции, чтобы завершить процесс

4 Отключите антивирус

Отключите антивирусную программу и посмотрите, продолжает ли Excel обнаруживать эту ошибку. Помните, что каждая антивирусная программа отключается по-разному, поэтому дополнительную информацию можно найти в документации на веб-сайте разработчика.

1000) выделенных документов или несколько раз запускаем макрос для обработки небольшого количества документов, может переполниться память. Зависают приложения. Приходится перезагружать компьютер.
В макросе после работы с очередным объектом выполняю
SET имя=Nothing.
Что Вы порекомендуете использовать в скрипте для очистки памяти?

Здравствуйте. Ох уж эта память. Сложно рекомендовать, так как рекомендации иногда понимаются неправильно, потом получается только хуже :(.

А большой скрипт? Оптимизировать и ускорить можно значительно. Щас темку кину по оптимизации (ну это по скорости). Нужно простой примерчик который вызывает проблемы, мы попробуем показать как его можно оптимизировать.

И еще по памяти. Часто бывает что это в TechnologiCS проблема, при обычной работе вы этого не заметите, а при использовании в АПИ многие вещи вылезти могут. Так что тут не всегда оптимизация поможет. И нужно на каждой версии смотреть.

Да получил. Посмотрим, точную версию TechnologiCS скажите пожалуйста.

TCS 5.0.2.0(9328)
Спасибо за примеры оптимизации

Ну в вашем случае все просто.

Объекты, которые создаются от Application как правило глобальные, и создаются один раз на весь сеанс работы программы. Таким образом мы можем безопасно писать такой код

так как в течении всей работы объект TCSApp.DocParams будет один и тот же.

тоже самое относится и к строке (которая у вас выполняется в цикле)


Set DOC_module=TCSApp.SingleDoc( CSDN_ … sInteger)

Это объект полученный от Application, и он тоже создается один раз (но один раз для каждого документа). При интенсивной работе это может вызвать проблемы с памятью.

Для того чтобы управлять данным поведением, предназначены методы

IModule2.UniqueUserModuleName Получить уникальное значение для UserModuleName

IOcs_Application2.DeleteModuleByUserModuleName Удалить модуль по пользовательскому уникальному имени

IOcs_Application2.ModuleByUserModuleName Получить модуль по пользовательскому уникальному имени

Таким образом, с помощью данных методов мы можем управлять временем жизни нужны нам объектов (НО!! не надо пользоваться этим повсеместно, могут быть другие побочные эффекты, которые вместо контроля над объектами дадут серьезные проблемы)

Если ваш код переписать вот к таком виду

вы будете уничтожать созданные вами объекты.
Или еще лучше вот к такому виду, чтобы еще меньше сделать вероятность влияния ошибки ( поскольку UniqueUserModuleName создаст уникальное имя, которое никому не будет известно).

надеюсь это поможет.

Спасибо!
Добавила к каждому
SET имя= объект
предложенные методы.

НО!! не надо пользоваться этим повсеместно, могут быть другие побочные эффекты, которые вместо контроля над объектами дадут серьезные проблемы

Хочу уточнить, во избежание побочных эффектов, где этого делать не следует?

И ещё надо ли использовать в данном случае SET имя=Nothing?

По желанию. Скриптовый движок сам отлично отслеживает все ссылки, так что особого смысла в таком коде нет, кроме может красоты. Бывает правда необходимо уничтожить объект в определенном месте программы, или просто ссылку убить дабы исключить последующее использование, тогда конечно требуется подобный код. Или скажем после вот такого кода

обращение к DOC_module после вызова DeleteModuleByUserModuleName вызовет ошибку, так как DOC_module в скрипте существует и валиден, а внутренний объект TechnologiCS уже уничтожен. В этом случае сброс DOC_module может быть и полезен, хотя система все равно отслеживает это.

не надо пользоваться этим повсеместно

скажем так. Как я говорил выше, объекты, которые создаются от Application как правило глобальные, и создаются один раз на весь сеанс работы программы. Остальные объекты, полученные через Properties, ChildModules и пр. уничтожаются автоматически, и никаких дополнительных действий с ними не требуется. Если же начать пользоваться приведенными выше функциями, то наоборот мы получим кучу глобальных объектов, да еще и с уникальным именем, до которых потом вы уже вряд ли достучитесь, а автоматически они уже не уничтожатся.

Вообще смысл вышеприведенных методов не столько для того, чтобы делать удаление, а для того чтобы можно было создавать свои собственные глобальные настройки и хранить их между запусками скриптов. Способы применения зависят от конкретных задач.
Пример. Запускается скрипт, который просит пользователя сделать кучу настроек, или выбрать что либо. Затем пользователь запускает другой скрипт, которому тоже нужны эти же самые настройки. Мы можем через глобальные объекты создать (или запомнить уже существующий) некий нужный нам модуль и на старте скрипта попытаться найти его, если не нашли, то запустить выбор/создание настроек.

Поэтому и рекомендации по использованию дать сложно, но главное не считать DeleteModuleByUserModuleName панацеей от проблем с памятью и усложнять код постоянными его вызовами.

Доброго времени суток!
Столкнулся с проблемой при работе макроса - выходит ошибка "недостаточно оперативной памяти Excel". Пробовали запускать на трех ноутбуках - на двух подвисает, но все-таки работает (примерно 7 минут), на третьем, для которого написан макрос, и выходит эта ошибка. Установлен 10 офис, 32-разрядная версия, все лицензионное. Поискал в интернете - советуют поменять железо. Пробовал запустить макрос дома (комп мощный и 64-разрядная версия Excel), отчет формировался 20 минут.
Суть работы проблемной части макроса - имеется таблица с данными по ЗП сотрудников (4000 строк), эта таблица копируется и вставляется на 12 новых листов (12 филиалов) , далее с этих 12 листов удаляются лишние данные по другим филиалам.

Пробовал чистить буфер памяти - Application.CutCopyMode = False , не помогло

Возможно, кто-то уже сталкивался с такой проблемы и нашел решение, буду признателен за совет!

Суть работы проблемной части макроса - имеется таблица с данными по ЗП сотрудников (4000 строк), эта таблица копируется и вставляется на 12 новых листов (12 филиалов) , далее с этих 12 листов удаляются лишние данные по другим филиалам. Спасибо за ответ!
Буду пробовать оптимизировать - это уже 4 вариант макроса

Вы бы выложили файл, - тогда и советы были бы более конкретные

PS: для обработки 4 тыс строк, обычно более чем достаточно 1-2 секунд.
(если макрос правильно написан)

Файл, к сожалению выложить не могу, т.к. он содержит конфеденциальную информацию. И вопрос был не по оптимизации кода VBA, а по настройкам Excel.
Вообще вроде бы решил вопрос копированием только нужной мне части листа
' копирование данных
lLastRow = Worksheets("Выгрузка").Cells(Rows.C ount, 1).End(xlUp).Row ' Счетчик номера последней строки
Sheets("Выгрузка").Select
Range(Cells(1, 1), Cells(lLastRow, 25)).Select
Selection.Copy
' вставка на листы
For i = 3 To ThisWorkbook.Sheets.Count 'номер последнего листа в книге
Sheets(i).Select
Range("A1").Select
ActiveSheet.Paste

вопрос был не по оптимизации кода VBA, а по настройкам Excel

а причём тут настройки Excel ?

макрос тормозит по одной единственной причине, - он так написан
настройки Excel тут ни при чём
если нормально написать макрос (без использования слова Select, например), - макрос отработает за секунду, - и, разумеется, с нехваткой памяти никаких проблем не будет
(такому макросу надо очень мало памяти)

PS: проще переписать весь код «с нуля»

Я использую код VBA в большой электронной таблице. Как очистить память между процедурами /вызовами, чтобы предотвратить возникновение проблемы «недостаточно памяти»?

Лучший способ освободить память - обнулить большие объекты:

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

Однако это не поможет, если:

  • вам нужен объект после процедуры (очевидно)
  • ваш объект не помещается в памяти

Еще одна возможность - перейти на 64-разрядную версию Excel, которая должна иметь возможность использовать больше оперативной памяти перед сбоем (32-разрядные версии обычно ограничены объемом около 1,3 ГБ).

Я нашел обходной путь. Сначала казалось, что это займет больше времени, но на самом деле все работает плавнее и быстрее из-за меньшего количества перестановок и большего объема доступной памяти. Это не научный подход, и он требует некоторого тестирования, прежде чем он заработает.

В коде заставьте Excel время от времени сохранять книгу. Мне пришлось перебрать лист с 360 000 строк, и он сильно задохнулся. После каждых 10 000 я заставлял код сохранять рабочую книгу, и теперь он работает как прелесть даже в 32-разрядной версии Excel.

Если вы одновременно запустите диспетчер задач, вы увидите, что использование памяти резко снижается после каждого сохранения.

Ответ - вы не можете явно, но вы должны освободить память в своих подпрограммах.

Несколько советов, чтобы помочь памяти

  • Убедитесь, что для объекта задано значение NULL, прежде чем выходить из процедуры.
  • Убедитесь, что вы вызываете Close для объектов, если они этого требуют.
  • Не используйте глобальные переменные без крайней необходимости

Я бы порекомендовал проверить использование памяти после повторного выполнения процедуры, и снова может возникнуть утечка памяти.

Если вы работаете с большим набором данных, вполне возможно, что будут использоваться массивы. Для меня создание нескольких массивов из 500 000 строк и 30 столбцов рабочего листа вызвало эту ошибку. Я решил это, просто используя строку ниже, чтобы избавиться от массива, который мне больше не нужен, перед созданием другого:

Также, если используются только 2 столбца из 30, рекомендуется создать два массива из 1 столбца вместо одного с 30 столбцами. Это не влияет на скорость, но будет разница в использовании памяти.

У меня была похожая проблема, которую я решил сам . Я думаю, что это был частично мой код слишком много памяти, в то время как слишком много "больших вещей"

в моем приложении - рабочая книга выходит и забирает у других отделов «ежедневный отчет» . и я извлекаю всю информацию, которая нужна нашей команде (чтобы минимизировать ошибки и ввод данных).

Я загружаю их листы напрямую . но я ненавижу тот факт, что они используют объединенные ячейки . от которых я избавляюсь (то есть, объединяю, затем нахожу получающиеся пустые ячейки и заполняю значениями сверху)

Я заставил мою проблему уйти

а) объединение только «использованных ячеек», а не просто попытка сделать весь столбец . то есть поиск последней использованной строки в столбце и объединение только этого диапазона (буквально тысячи строк на каждом из лист я хватаю)

б) Зная, что отмена присматривает только за последними

16 событиями . между каждым "unmerge" - я поместила 15 событий, которые очищают то, что хранится в "отмене", чтобы минимизировать количество удерживаемой памяти ( то есть перейдите к какой-либо ячейке с данными в ней . и скопируйте //вставьте специальное значение . Я УГАДАЛ, что накопленная сумма в 30 листов каждый с данными в 3 столбца может облагать налогом память, установленную в качестве стороны для удаления

Да, это не дает никаких шансов на отмену . но вся цель состоит в том, чтобы очистить старую информацию и извлечь новые данные, чувствительные ко времени, для анализа, чтобы это не было проблемой

Читайте также: