Как исправить отображение русских букв в QR-коде при генерации через FormEx в 1С 7.7

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

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

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

Выясняем причину проблемы: кодировки и библиотека Zint

Прежде чем переходить к коду, давайте разберемся, почему возникает искажение русских букв. Платформа 1С 7.7 по умолчанию работает в однобайтовой кодировке Windows-1251 (ANSI). В то же время современные стандарты штрихкодирования, включая спецификацию QR-кодов, ориентированы на представление текстовых данных в многобайтовой кодировке UTF-8 или с использованием специального заголовка ECI.

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

Когда мы передаем обычную строку 1С в метод генерации штрихкода, библиотека Zint пытается интерпретировать ее «как есть». Поскольку байты кириллической кодировки Windows-1251 не соответствуют структуре UTF-8, на выходе получается некорректно закодированный массив данных. Сканирующее устройство, ожидающее стандартный UTF-8, декодирует эти байты по латинской таблице (например, ISO-8859-1), превращая русский текст в хаотичный набор символов.

Для исправления ситуации нам необходимо решить две задачи:

  1. Преобразовать исходную строку 1С из Windows-1251 в UTF-8 перед передачей в генератор штрихкода.
  2. Явно указать библиотеке Zint, что ей передаются данные в формате Юникод.

Шаг 1. Перекодирование строки в UTF-8

Для преобразования строк в компоненте FormEx предусмотрен специальный объект Сервис и его метод DecodeToUTF8(). Название метода может показаться нелогичным (буквально «декодировать в UTF-8»), но на практике он берет строку в системной кодировке 1С (Windows-1251) и возвращает ее байтовое представление в UTF-8.

Рассмотрим базовый пример перекодирования:


// Создаем объект Сервис для доступа к функциям FormEx
Сервис = СоздатьОбъект("Сервис");

// Наша исходная строка на русском языке
ИсходныйТекст = "Привет, мир! Это тестовый QR-код.";

// Преобразуем строку в UTF-8
СтрокаВUTF8 = Сервис.DecodeToUTF8(ИсходныйТекст);

Шаг 2. Использование правильных параметров метода НарисоватьШтрихкод

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

НарисоватьШтрихкод(ТабличныйДокумент, ТипШтрихкода, Данные, [Ширина], [Высота], [РежимВвода])

Разберем назначение ключевых параметров подробнее:

В зависимости от версии FormEx, этот параметр управляет интерпретацией входящей строки в библиотеке Zint. Он может принимать следующие значения:

Объединим перекодирование и вывод штрихкода в единый блок кода 1С:


// Подготовка данных и вывод QR-кода с флагом UNICODE
Сервис = СоздатьОбъект("Сервис");
СтрокаШтрихКода = Сервис.DecodeToUTF8(ШтрихКодСтрока);

// Обратите внимание на шестой параметр: передаем 1 (UNICODE_MODE)
Сервис.НарисоватьШтрихкод(ТабДок.ТекущийОбъект, 58, СтрокаШтрихКода, , , 1);

Шаг 3. Устранение проблем со сканирующими устройствами (ECI-заголовки)

Даже если мы правильно перевели строку в UTF-8 и передали параметр режима работы 1, некоторые устаревшие или ненастроенные сканеры штрихкодов всё равно могут выдавать кракозябры. Проблема кроется в том, что по умолчанию сканер может не знать, какую кодировку применить к считанному бинарному потоку.

Для решения этой проблемы в спецификацию штрихкодов внедрен механизм ECI (Extended Channel Interpretation). Это служебный заголовок внутри QR-кода, который явно сообщает сканеру: «Внимание, данные внутри записаны в кодировке UTF-8!». В последних версиях FormEx поддержка ECI интегрирована по умолчанию при включении режима Юникод, что позволяет гарантировать корректное чтение кириллицы практически на любых современных смартфонах и ТСД.

Анализируем дополнительные функции: исправление бага EncodeFromUTF8

В процессе интеграции обмена данными у разработчиков часто возникает и обратная задача: прочитать текстовый файл или ответ от веб-сервиса в формате UTF-8 и преобразовать его назад в стандартную кодировку 1С Windows-1251. Для этого в FormEx предусмотрен метод EncodeFromUTF8().

В ранних релизах компоненты присутствовал досадный баг: метод EncodeFromUTF8 фактически дублировал код DecodeToUTF8, из-за чего обратное преобразование не работало. В актуальных версиях FormEx эта проблема полностью устранена автором компоненты (АЛьФ). Однако при практическом использовании этой функции следует учитывать два важных нюанса:

  1. Проблема сигнатуры BOM (Byte Order Mark). Если исходные текстовые данные в формате UTF-8 начинаются со служебных байтов BOM (EF BB BF), то при чтении строки штатными средствами 1С 7.7 и последующей перекодировке через EncodeFromUTF8, в начале результирующей строки может появиться лишний нечитаемый «мусорный» символ. Рекомендуется принудительно проверять начало полученной строки и удалять BOM-символы программно в коде 1С.
  2. Спецсимволы за пределами Windows-1251. Если в QR-коде или UTF-8 файле содержатся специфические символы (например, знак евро €, некоторые виды кавычек или графические элементы), которых нет в стандартной русской таблице Windows-1251, метод перекодирования заменит их на знаки вопроса (?) или вызовет ошибку. Перед конвертацией такие символы желательно отфильтровать.

Решение проблемы с концевым нулевым символом (Null-byte)

В редких случаях при детальном техническом анализе структуры сгенерированных QR-кодов программисты сталкиваются со специфическим поведением компоненты FormEx. В конец закодированной строки может автоматически добавляться нулевой символ (терминатор строки в языке C++, байт 0x00).

Для большинства обычных потребительских сканеров и мобильных приложений этот символ незаметен, так как они интерпретируют его как окончание текста и просто игнорируют. Однако если ваш QR-код используется для интеграции со строгими государственными информационными системами, которые сверяют точную длину строки в байтах или проверяют контрольные суммы (например, при маркировке или обмене структурированными XML/JSON-пакетами), этот дополнительный нулевой байт может приводить к ошибкам валидации. Если вы столкнулись с подобной проблемой, убедитесь, что вы используете самую последнюю стабильную версию компоненты FormEx, где данная особенность была доработана разработчиками.

Готовый шаблон кода для вывода QR-кода с кириллицей

Резюмируя все вышеописанные шаги, представим готовый к использованию шаблон процедуры для вывода качественного QR-кода с поддержкой русского языка в табличный документ 1С 7.7:


Процедура СформироватьQRКод(ТабДок, ТекстДляКодирования)
    
    // Проверяем загрузку внешней компоненты FormEx
    Попытка
        Сервис = СоздатьОбъект("Сервис");
    Исключение
        Предупреждение("Внешняя компонента FormEx не загружена! Вывод QR-кода невозможен.");
        Возврат;
    КонецПопытки;
    
    // Исключаем пустые строки во избежание ошибок генерации
    Если ПустаяСтрока(ТекстДляКодирования) = 1 Тогда
        ТекстДляКодирования = " ";
    КонецЕсли;
    
    // Шаг 1: Конвертируем исходный текст Windows-1251 в кодировку UTF-8
    СтрокаВUTF8 = Сервис.DecodeToUTF8(ТекстДляКодирования);
    
    // Шаг 2: Отрисовываем QR-код в таблице
    // Используем тип штрихкода 58 (QR-код)
    // Передаем 1 в качестве шестого параметра для включения режима UNICODE_MODE
    Попытка
        Сервис.НарисоватьШтрихкод(ТабДок.ТекущийОбъект, 58, СтрокаВUTF8, , , 1);
    Исключение
        Сообщить("Ошибка при отрисовке QR-кода: " + ОписаниеОшибки(), "!");
    КонецПопытки;
    
КонецПроцедуры

Использование этого шаблона позволит вам полностью избавиться от проблемы «кракозябр» и гарантирует успешное чтение созданных QR-кодов любыми современными устройствами считывания.

← На главную