При формировании массовых документов, таких как квитанции на оплату коммунальных услуг или налоговые уведомления, разработчики часто сталкиваются с критической проблемой производительности платформы 1С 7.7. Стандартные методы работы с QR-кодами через ActiveX-компоненты (например, ocvitabarcode) приводят к тому, что при выводе более 100 объектов метод Показать() начинает работать крайне медленно, иногда затягивая процесс на часы. В этой статье мы подробно разберем причины такого поведения системы и рассмотрим несколько эффективных способов решения проблемы: от простых программных «хитростей» до использования продвинутых внешних компонент.
Проанализируем ситуацию: платформа 1С:Предприятие 7.7 изначально не проектировалась для обработки сотен графических OLE-объектов в одной печатной форме. Когда мы вставляем QR-код через ocvitabarcode, каждый такой код является отдельным экземпляром ActiveX-объекта. При вызове метода Показать() система пытается инициализировать, отрисовать и управлять памятью для каждого объекта одновременно. Это создает колоссальную нагрузку на графическую подсистему Windows и менеджер памяти 1С. Выясним, как обойти это ограничение.
Самый простой способ, не требующий установки дополнительных компонент, — это разбиение одной огромной таблицы на несколько мелких. Как показывает практика, 1С стабильно обрабатывает до 100 сложных объектов в одной форме. Если нам нужно напечатать 1000 квитанций, мы можем выводить их пачками по 50–100 штук.
Рассмотрим пример кода, который реализует этот подход:
// Создаем объект таблицы
Таб = СоздатьОбъект("Таблица");
Таб.ИсходнаяТаблица("Квитанция");
КолвоВыведенных = 0;
ВыбратьСтроки();
Пока ПолучитьСтроку() = 1 Цикл
// Логика заполнения секции с QR-кодом
Таб.ВывестиСекцию("Данные");
КолвоВыведенных = КолвоВыведенных + 1;
// Проверяем лимит
Если КолвоВыведенных >= 100 Тогда
Таб.Показать("Печать квитанций (часть)");
// Обнуляем таблицу для следующей порции
Таб = СоздатьОбъект("Таблица");
Таб.ИсходнаяТаблица("Квитанция");
КолвоВыведенных = 0;
КонецЕсли;
КонецЦикла;
// Выводим остаток, если он есть
Если КолвоВыведенных > 0 Тогда
Таб.Показать("Печать квитанций (завершение)");
КонецЕсли;
Этот метод значительно ускоряет работу Показать(), так как оперативная память освобождается после закрытия каждого окна просмотра. Однако у него есть минус: пользователю придется отправлять на печать несколько разных документов вместо одного.
Проанализируем более профессиональный подход. Популярная библиотека FormEx позволяет реализовать отрисовку QR-кода непосредственно на контексте устройства (Canvas) ячейки таблицы. Это избавляет систему от необходимости создавать тяжеловесные OLE-объекты.
При использовании FormEx мы можем задействовать событие ПослеОтрисовкиЯчейки. Вместо вставки объекта в шаблон, мы оставляем пустую ячейку с определенным идентификатором. В момент формирования отчета компонента «рисует» пиксели QR-кода прямо в памяти. Скорость вывода при этом возрастает в десятки раз: сотни секций могут отрисовываться за считанные секунды.
Алгоритм работы выглядит так:
FormEx.dll через ЗагрузитьВнешнююКомпоненту().Если мы хотим избежать использования ActiveX внутри таблицы, но нам нужен один общий документ, разберем метод работы через временные файлы картинок. 1С 7.7 гораздо быстрее обрабатывает обычный объект типа «Картинка», чем активный элемент управления.
Для этого можно использовать консольные генераторы, например Zint Barcode Generator или специализированные библиотеки типа StQR.dll. Процесс выглядит следующим образом:
qr_temp.bmp на диск.Посмотрим на пример реализации:
// Пример использования внешнего генератора
ОбъектКартинка = Таб.ТекущийОбъект; // Получаем ссылку на картинку в секции
ПутьКФайлу = "C:\Temp\qr_code.bmp";
// Вызов внешней компоненты или скрипта для генерации файла
Генератор.СоздатьQR(СтрокаДанных, ПутьКФайлу);
// Загружаем картинку в объект таблицы
Таб.ВывестиСекцию("Квитанция");
Таб.Рисунок(1).Загрузить(ПутьКФайлу);
Этот способ позволяет сформировать документ на любое количество страниц без существенной деградации производительности, так как статические изображения не требуют сложного взаимодействия через OLE-интерфейсы.
Разберем важный технический момент, о котором часто забывают программисты 1С 7.7. Поскольку платформа работает в кодировке Windows-1251, а большинство банковских приложений и стандартов (ГОСТ Р 56042-2014) требуют кодировку UTF-8, перед передачей данных генератору QR-кода строку необходимо перекодировать.
Для этого удобно использовать объект ADODB.Stream:
Функция ПеревестиВUTF8(Текст)
Стрим = СоздатьОбъект("ADODB.Stream");
Стрим.Type = 2; // Text
Стрим.Charset = "windows-1251";
Стрим.Open();
Стрим.WriteText(Текст);
Стрим.Position = 0;
Стрим.Charset = "utf-8";
Результат = Стрим.ReadText();
Возврат Результат;
КонецФункции
Без этой предварительной обработки QR-код будет содержать «кракозябры» вместо русских букв (ФИО, назначение платежа), и платежные терминалы не смогут его распознать.
Подведем итог. Если вам нужно быстро вывести несколько сотен QR-кодов в 1С 7.7, забудьте об использовании ocvitabarcode в цикле напрямую. Наилучшим решением будет использование компоненты FormEx для прямой отрисовки или генерация временных BMP-файлов с их последующей загрузкой в объект «Картинка». Если же установка внешних библиотек запрещена политикой безопасности, используйте порционный вывод таблицы по 50–100 экземпляров, чтобы избежать зависания системы.