При автоматизации складского учета и организации процессов сверки документов в среде 1С:Предприятие 7.7 разработчики часто сталкиваются с необходимостью вывода двумерных штрихкодов (QR-кодов) на печатные формы. Двумерный код позволяет закодировать существенно больше информации, чем стандартный линейный штрихкод (1D). Однако при попытке упаковать в QR-код спецификацию документа (например, табличную часть накладной) многие сталкиваются с неприятным поведением системы: код либо перестает отображаться вовсе, либо выводится некорректно.
В этой статье мы подробно проанализируем причины возникновения этой проблемы при использовании популярной компоненты OcvitaBarcode, рассмотрим альтернативные методы генерации QR-кодов с помощью внешней библиотеки FormEx.dll, а также разберем архитектурно правильные подходы к решению задачи сверки документов без перегрузки печатных форм избыточными данными.
Компонента OcvitaBarcode.ocx представляет собой специализированный ActiveX-элемент управления, созданный на базе открытой библиотеки генерации штрихкодов Zint. Из-за этого архитектурного наследия компонента имеет ряд ограничений и специфических особенностей, о которых необходимо знать разработчику:
&) в строке данных может приводить к преждевременной обрезке кодируемого текста, а использование спецсимволов разделителей (таких как символ с кодом ASCII 29) в некоторых версиях вызывает падение платформы 1С 7.7.Рассмотрим по шагам основные способы решения этой проблемы, начиная с оптимизации структуры данных и заканчивая переходом на альтернативные инструменты.
Самый простой и быстрый способ вернуть работоспособность генерации QR-кода — это сокращение объема кодируемых данных. Зачастую разработчики пытаются поместить в строку QR-кода полную текстовую информацию: наименования номенклатуры, единицы измерения, ставки НДС и текстовые представления контрагентов. Это избыточно и непрактично.
Проанализируем ситуацию: для однозначной сверки позиций накладной на складе достаточно идентифицировать товары по их внутренним кодам или артикулам и сопоставить их с количеством. Исключив текстовые наименования позиций, мы резко сокращаем длину результирующей строки.
Вместо передачи структуры вида:
"Товар: Лопата штыковая титановая; Кол-во: 10; Цена: 1500"
Мы формируем компактный и строго типизированный формат обмена данными:
"12345:10;67890:5;11223:1" (где разделение идет двоеточием и точкой с запятой).
Такой подход позволяет без труда уместить информацию о 10–20 позициях накладной в лимиты даже простейших версий QR-кода, не увеличивая геометрические размеры картинки на печатной форме.
Если оптимизации данных недостаточно или требуется повышенная надежность и масштабируемость системы генерации, отличной альтернативой является использование популярной внешней библиотеки FormEx.dll (версии не ниже 2.0.5.131). В этой компоненте генератор штрихкодов Zint встроен непосредственно в ядро библиотеки, что избавляет от необходимости регистрировать в реестре операционной системы Windows сторонние ActiveX-компоненты типа OcvitaBarcode.ocx. Это критически важно при работе в терминальных сессиях и на современных 64-битных ОС.
Разберем детально процесс вывода QR-кода на печатную форму с помощью FormEx.dll.
Для начала добавим в таблицу макета объект «Картинка». В свойствах созданной картинки (вкладка «Свойства», поле «Формула») пропишем вызов функции вывода:
ВыводШтрихкодаВТаблицу(Таблица.ТекущийОбъект(), 58, СтрокаДанных)
Обратите внимание, что число 58 определяет тип штрихкода (для QR-кода в библиотеке Zint/FormEx зарезервирован данный идентификатор).
Теперь рассмотрим шаблон программного кода в модуле отчета или обработки, который выполняет генерацию:
// ==========================================
Процедура ВыводШтрихкодаВТаблицу(КонтейнерКартинки, ТипШК, ДанныеДляКода)
Попытка
// Метод отрисовывает QR-код непосредственно внутри графического объекта таблицы
Сервис.НарисоватьШтрихкод(КонтейнерКартинки, ТипШК, СокрЛП(ДанныеДляКода), 0);
// Задаем режим рисования (3 - масштабирование с сохранением пропорций)
КонтейнерКартинки.РежимРисования(3);
Исключение
Сообщить("Ошибка отрисовки штрихкода: " + ОписаниеОшибки(), "!");
КонецПопытки;
КонецПроцедуры
// ==========================================
Процедура Сформировать()
Таб = СоздатьОбъект("Таблица");
// Инициализируем внешнюю компоненту FormEx
Попытка
Сервис = СоздатьОбъект("Сервис");
Исключение
Предупреждение("Компонента FormEx.dll не зарегистрирована в системе!", 5);
Возврат;
КонецПопытки;
// Проверяем версию библиотеки для исключения проблем с чтением QR-кодов
ВерсияСтрокой = "";
ВерсияЧислом = Сервис.Версия(ВерсияСтрокой);
// Версия должна быть не ниже 2.0.5.131 (внутреннее представление версии >= 33555843)
Если ВерсияЧислом < 33555843 Тогда
Предупреждение("Установлена устаревшая версия FormEx.dll (" + ВерсияСтрокой + ").
|Для стабильной работы и корректного сканирования QR-кодов
|обновите компоненту до версии не ниже 2.0.5.131!", 10);
Возврат;
КонецЕсли;
// Подготавливаем данные для кодирования
СтрокаДанных = "DOC;12345;21.10.2023;";
// Обходим строки табличной части документа
ВыбратьСтроки();
Пока ПолучитьСтроку() = 1 Цикл
// Добавляем к кодируемой строке только ИД товара и количество
СтрокаДанных = СтрокаДанных + СокрЛП(ТекущийЭлемент().Код) + ":" + Строка(Количество) + ";";
КонецЦикла;
// Выводим секцию печатной формы, содержащую настроенную картинку
Таб.ВывестиСекцию("Шапка");
Таб.Показать("Печать документа с QR-кодом", "");
КонецПроцедуры
Внедрение FormEx позволяет динамически и очень качественно масштабировать плотную матрицу QR-кода даже на небольших участках печатной формы, значительно превосходя по надежности OcvitaBarcode.
Рассмотрим ситуацию с точки зрения архитектуры базы данных и оптимизации бизнес-процессов. Изначальная задача, описанная на форуме: автоматизировать сверку бумажных копий документов, находящихся на руках у материально ответственного лица (МОЛ), с измененными или закрытыми документами в базе 1С на следующий день.
Попытка записать абсолютно всю спецификацию накладной в QR-код — это избыточный и тупиковый путь. При росте позиций в документе (например, от 50 строк и выше) физический размер QR-кода станет слишком огромным, требования к качеству печати принтера станут запредельными (малейшая полоса картриджа сделает код нечитаемым), а процесс сканирования превратится в мучение.
Оптимальное решение: использование алгоритмов хеширования (например, MD5 или SHA-1).
Вместо того чтобы хранить состав накладной в QR-коде, мы вычисляем уникальный цифровой отпечаток (хеш-сумму) этого состава. Проанализируем алгоритм этого процесса:
8b1a9953c4611296a827abf8c47804d7).Пример строки в QR-коде: "Накл-00432;21.10.2023;8b1a9953c4611296a827abf8c47804d7"
Этот подход полностью снимает проблему ограничения размера QR-кода, гарантирует 100% читаемость штрихкода даже на старых принтерах и обеспечивает мгновенный автоматизированный контроль неизменности документов.