Как решить проблему высокого потребления ОЗУ при формировании больших табличных документов с этикетками в 1С?

Программист 1С v8.3 (Управляемые формы) Промышленность, строительство и АПК
← На главную

При работе с крупными объемами данных в 1С:Предприятие, особенно при массовой печати этикеток (от 30 000 штук и выше), разработчики часто сталкиваются с критической нехваткой оперативной памяти. Объект ТабличныйДокумент при выводе большого количества областей с картинками или сложным форматированием начинает потреблять ресурсы в геометрической прогрессии. Это приводит к падению рабочего процесса rphost, особенно на серверах с лицензией уровня ПРОФ, где действуют жесткие ограничения на использование ОЗУ.

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

Причина избыточного потребления памяти

Выясним причину: объект ТабличныйДокумент в памяти 1С представляет собой не просто текст, а сложную структуру метаданных. Каждая ячейка, каждая граница и, тем более, каждый объект типа Рисунок (в котором часто передаются штрихкоды DataMatrix) являются тяжеловесными объектами. При попытке объединить 30 000 этикеток в один документ платформа вынуждена держать в оперативной памяти миллионы таких микро-объектов одновременно. Ситуация усугубляется, если используются картинки, так как 1С хранит их в памяти в несжатом или частично подготовленном для отрисовки виде.

Решение 1: Использование шрифтов вместо картинок

Одним из самых эффективных способов снижения нагрузки на ОЗУ является отказ от использования графических объектов для формирования штрихкодов. Рассмотрим подробнее: вместо того чтобы генерировать картинку DataMatrix для каждой этикетки, можно использовать специализированные шрифты.

Разберем, как это работает: вы устанавливаете на сервере и клиентских машинах шрифт (например, DataMatrix Font), и вместо вывода картинки просто записываете в ячейку текстовую строку, которая при использовании этого шрифта превращается в штрихкод. Это снижает потребление памяти в десятки раз, так как 1С работает с обычными текстовыми данными.

Решение 2: Разбиение процесса на части с использованием фоновых заданий

Поскольку процесс rphost имеет лимиты памяти, мы можем распределить нагрузку. Разберем этот метод по шагам:

  1. Разделим общий массив данных на порции (например, по 1000 этикеток).
  2. Для каждой порции запустим отдельное фоновое задание, которое сформирует свой ТабличныйДокумент.
  3. Каждое фоновое задание запишет свой результат во временный файл MXL или PDF на диске.
  4. После завершения всех заданий мы получим набор файлов, которые можно объединить внешними средствами.

Проанализируем пример кода для запуска такой обработки порциями:


// Пример логики разбиения на порции
РазмерПорции = 1000;
ВсегоЭтикеток = Объект.СписокЭтикеток.Количество();
ТекущийИндекс = 0;

Пока ТекущийИндекс < ВсегоЭтикеток Цикл
    ПараметрыЗадания = Новый Структура("Начало, Конец", ТекущийИндекс, ТекущийИндекс + РазмерПорции);
    ФоновыеЗадания.Выполнить("ВашМодуль.СформироватьЧастьДокумента", ПараметрыЗадания);
    ТекущийИндекс = ТекущийИндекс + РазмерПорции;
КонецЦикла;

Решение 3: Программное объединение PDF файлов

Если завод-изготовитель требует единый файл, а 1С не может его создать из-за нехватки памяти, мы можем использовать стратегию "сохраняй и объединяй". Рассмотрим, как это реализовать:

Вместо вывода всех областей в один объект ТабличныйДокумент, мы выводим порцию этикеток, сохраняем её в PDF методом Записать(), а затем очищаем документ методом Очистить(). Это принудительно освобождает занятую память внутри одного сеанса.

Для последующего слияния PDF-файлов можно использовать бесплатные консольные утилиты, такие как pdftk или Ghostscript, вызывая их из 1С с помощью команды ЗапуститьПриложение().


// Сохранение части документа
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.PDF);
ТабДок.Очистить(); // Критически важно для освобождения ОЗУ

Решение 4: Переход на низкоуровневые протоколы печати (ZPL/EPL)

Посмотрим на ситуацию с точки зрения промышленного производства. Профессиональные принтеры этикеток (Zebra, Honeywell) поддерживают языки управления, такие как ZPL (Zebra Programming Language). Вместо того чтобы мучиться с визуальным макетом 1С, мы можем генерировать обычный текстовый файл с командами ZPL.

Проанализируем преимущества:

Пример формирования команды ZPL в коде 1С:


ТекстZPL = "^XA" + Символы.ПС;
ТекстZPL = ТекстZPL + "^FO50,50^BXN,10,200^FD" + ЗначениеКодаМаркировки + "^FS" + Символы.ПС;
ТекстZPL = ТекстZPL + "^XZ";
// Далее запись строки в текстовый файл

Рекомендации по настройке сервера

Если возможности изменить бюджет на ОЗУ нет, проанализируем настройки сервера 1С. Для лицензий ПРОФ важно учитывать параметр "Максимальный объем памяти рабочих процессов". Не рекомендуется оставлять его в значении "-1", если вы сталкиваетесь с падениями. Лучше установить лимит чуть ниже физически доступной памяти, чтобы операционная система не уходила в бесконечный своп (swap), что только замедляет процесс.

Также стоит проверить интервал проверки памяти в настройках кластера. Если формирование документа происходит слишком быстро и "взрывно", 1С может не успеть штатно завершить сеанс по превышению лимита, что и приводит к аварийному завершению rphost.

Подведем итог: для успешной печати огромных тиражей этикеток в 1С следует комбинировать методы. Оптимальным вариантом будет использование шрифтов для снижения веса каждой этикетки и порционный вывод данных с очисткой объекта ТабличныйДокумент после каждой итерации. Если же требования позволяют, переход на прямую генерацию ZPL станет самым стабильным и масштабируемым решением.

← На главную