Как решить проблему с ограничением объема данных при генерации QR-кода в 1С 7.7?

Программист 1С v7.7 Управленческий учет IT и автоматизация бизнеса
← На главную

При автоматизации складского учета и организации процессов сверки документов в среде 1С:Предприятие 7.7 разработчики часто сталкиваются с необходимостью вывода двумерных штрихкодов (QR-кодов) на печатные формы. Двумерный код позволяет закодировать существенно больше информации, чем стандартный линейный штрихкод (1D). Однако при попытке упаковать в QR-код спецификацию документа (например, табличную часть накладной) многие сталкиваются с неприятным поведением системы: код либо перестает отображаться вовсе, либо выводится некорректно.

В этой статье мы подробно проанализируем причины возникновения этой проблемы при использовании популярной компоненты OcvitaBarcode, рассмотрим альтернативные методы генерации QR-кодов с помощью внешней библиотеки FormEx.dll, а также разберем архитектурно правильные подходы к решению задачи сверки документов без перегрузки печатных форм избыточными данными.

Выясняем причины сбоя OcvitaBarcode при генерации плотных QR-кодов

Компонента OcvitaBarcode.ocx представляет собой специализированный ActiveX-элемент управления, созданный на базе открытой библиотеки генерации штрихкодов Zint. Из-за этого архитектурного наследия компонента имеет ряд ограничений и специфических особенностей, о которых необходимо знать разработчику:

  1. Зависимость плотности кода от физического размера контейнера. QR-код имеет разные версии (от 1 до 40), каждая из которых определяет количество информационных ячеек (модулей). Чем больше данных мы пытаемся передать, тем более высокую версию QR-кода пытается построить библиотека. Если размер элемента управления (картинки) в макете 1С задан жестко и имеет небольшие геометрические размеры (например, менее 20х20 мм), компоненте физически не хватает экранных пикселей для отрисовки высокоплотной матрицы. В результате генерация аварийно прерывается, и на печать выводится пустая область, черный квадрат либо красный перечеркнутый прямоугольник.
  2. Чувствительность к спецсимволам. OcvitaBarcode некорректно обрабатывает некоторые служебные знаки. Например, наличие символа амперсанда (&) в строке данных может приводить к преждевременной обрезке кодируемого текста, а использование спецсимволов разделителей (таких как символ с кодом ASCII 29) в некоторых версиях вызывает падение платформы 1С 7.7.
  3. Отсутствие информативных кодов возврата. В штатном режиме ActiveX-компонента в 1С 7.7 не возвращает подробных текстовых описаний ошибок компиляции штрихкода в программный стек, из-за чего разработчику сложно оперативно перехватить исключение превышения лимита символов в коде 1С.

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

Способ 1. Оптимизация структуры данных (Решение «в лоб»)

Самый простой и быстрый способ вернуть работоспособность генерации QR-кода — это сокращение объема кодируемых данных. Зачастую разработчики пытаются поместить в строку QR-кода полную текстовую информацию: наименования номенклатуры, единицы измерения, ставки НДС и текстовые представления контрагентов. Это избыточно и непрактично.

Проанализируем ситуацию: для однозначной сверки позиций накладной на складе достаточно идентифицировать товары по их внутренним кодам или артикулам и сопоставить их с количеством. Исключив текстовые наименования позиций, мы резко сокращаем длину результирующей строки.

Вместо передачи структуры вида:

"Товар: Лопата штыковая титановая; Кол-во: 10; Цена: 1500"

Мы формируем компактный и строго типизированный формат обмена данными:

"12345:10;67890:5;11223:1" (где разделение идет двоеточием и точкой с запятой).

Такой подход позволяет без труда уместить информацию о 10–20 позициях накладной в лимиты даже простейших версий QR-кода, не увеличивая геометрические размеры картинки на печатной форме.

Способ 2. Использование компоненты FormEx.dll

Если оптимизации данных недостаточно или требуется повышенная надежность и масштабируемость системы генерации, отличной альтернативой является использование популярной внешней библиотеки 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.

Способ 3. Использование контрольных сумм (Хеширование данных)

Рассмотрим ситуацию с точки зрения архитектуры базы данных и оптимизации бизнес-процессов. Изначальная задача, описанная на форуме: автоматизировать сверку бумажных копий документов, находящихся на руках у материально ответственного лица (МОЛ), с измененными или закрытыми документами в базе 1С на следующий день.

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

Оптимальное решение: использование алгоритмов хеширования (например, MD5 или SHA-1).

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

  1. При печати документа в 1С мы собираем все данные табличной части (коды товаров, их количество и цены) в единую длинную текстовую строку.
  2. Для полученной строки рассчитываем контрольную сумму по алгоритму MD5. Длина полученного хеша всегда фиксирована и составляет всего 32 символа (например: 8b1a9953c4611296a827abf8c47804d7).
  3. В QR-код на печатной форме мы помещаем только ключевые метаданные: уникальный идентификатор документа (GUID или связку Номер+Дата) и вычисленный хеш.

    Пример строки в QR-коде: "Накл-00432;21.10.2023;8b1a9953c4611296a827abf8c47804d7"

  4. При сканировании бумажной копии на следующий день специализированная обработка в 1С выполняет следующие действия:
    • Считывает QR-код и мгновенно находит документ в базе данных по его номеру и дате.
    • Программным путем повторно формирует текстовую строку из текущей табличной части найденного документа в БД и рассчитывает ее MD5-хеш.
    • Сравнивает полученный свежий хеш с хешем, считанным со сканера из QR-кода.
    • Если хеши абсолютно идентичны — документ гарантированно не подвергался изменениям, сверка пройдена успешно в один клик.
    • Если хеши различаются — система мгновенно сигнализирует о расхождении и открывает детальный отчет (например, через механизм сравнения версий или лог регистрации), показывая пользователю, какие именно позиции были отредактированы, удалены или добавлены.

Этот подход полностью снимает проблему ограничения размера QR-кода, гарантирует 100% читаемость штрихкода даже на старых принтерах и обеспечивает мгновенный автоматизированный контроль неизменности документов.

← На главную