Вывод штрихкодов в печатные формы — классическая задача при автоматизации складского учета, логистики и розничной торговли. Традиционно для этого использовались внешние компоненты (в формате .ocx или современные Native API от 1С). Однако в последнее время все большую популярность приобретает альтернативный метод — генерация штрихкода с помощью специализированных TrueType шрифтов (TTF). Этот способ отличается высокой скоростью работы, полной кроссплатформенностью и отсутствием проблем с регистрацией внешних библиотек в операционной системе.
В этой статье мы подробно разберем, как устроен штрихкод стандарта Code 128, опровергнем популярные заблуждения разработчиков, рассмотрим математическую модель расчета контрольного числа по модулю 103 и напишем готовый компактный алгоритм на языке 1С для работы с популярным шрифтом Grand Zebu.
Очень часто на форумах можно встретить утверждение, что алгоритм преобразования строки в штрихкод универсален и не зависит от выбранного файла шрифта. Это критическая ошибка.
Хотя сам стандарт Code 128 жестко регламентирован международным стандартом ГОСТ ISO/IEC 15417-2013 (в плане чередования черных и белых полос различной ширины), отображение этих полос через символы шрифта TrueType целиком и полностью зависит от его создателя. Каждый автор сопоставляет определенные кодовые комбинации штрихов своим символам в таблице шрифта (character mapping). Если вы возьмете алгоритм, написанный под один шрифт, и примените его к другому, сканер считает некорректные данные или вообще откажется распознавать штрихкод.
В мировой практике разработки выделяют три основные группы раскладок для шрифтов Code 128:
code128.ttf версии 2.0). Он исторически наиболее распространен в русскоязычном сегменте интернета. У него своя специфическая логика сопоставления управляющих и контрольных символов.В рамках данной статьи мы спроектируем и реализуем алгоритм 1С именно под шрифт Grand Zebu (code128.ttf), так как он бесплатен, стабилен и поддерживается абсолютным большинством сканеров.
Штрихкод Code 128 уникален тем, что позволяет кодировать не только цифры, но и буквы латиницы (как верхнего, так и нижнего регистра), а также управляющие символы ASCII. Для достижения максимальной плотности (компактности) штрихкода стандарт разделен на три набора символов:
Чтобы штрихкод получался максимально компактным, профессиональные алгоритмы должны динамически анализировать исходную строку. Если в строке встречается непрерывная последовательность из 4 или более цифр, алгоритм должен переключить режим шифрования на Subset C, а при появлении букв — вернуться на Subset B.
Для простоты понимания и надежности мы разберем базовый компактный алгоритм, работающий в пространстве Subset B, который идеально подходит для кодирования артикулов, серийных номеров и смешанных буквенно-цифровых кодов. В конце мы также затронем правила перехода на Subset C.
Сканер штрихкодов не поверит прочитанным данным, если в конце последовательности не будет корректного контрольного знака. В Code 128 для этого применяется алгоритм расчета остатка от деления на 103. Разберем его по шагам:
Перейдем к практике. Ниже представлен готовый код функции на языке 1С, которая принимает на вход исходную строку (например, "1С-CODE-128") и возвращает закодированную строку символов. Применив к этой строке шрифт code128.ttf (Grand Zebu) в макете печатной формы, вы получите валидный штрихкод.
Функция СформироватьСтрокуCode128(Знач ИсходнаяСтрока) Экспорт
// Проверим входные данные
Если ПустаяСтрока(ИсходнаяСтрока) Тогда
Возврат "";
КонецЕсли;
// Инициализируем переменные для расчета контрольного числа
// Для Subset B стартовый код имеет внутреннее значение 104
ВнутреннееЗначениеСтарта = 104;
КонтрольнаяСумма = ВнутреннееЗначениеСтарта;
// Результат начнется со стартового символа Start B.
// Для шрифта Grand Zebu внутренний код 104 соответствует символу с ASCII-кодом 209
Результат = Символ(209);
// Цикл по всем символам исходной строки
Для Позиция = 1 По СтрДлина(ИсходнаяСтрока) Цикл
ТекущийСимвол = Сред(ИсходнаяСтрока, Позиция, 1);
КодASCII = КодСимвола(ТекущийСимвол);
// Определяем внутреннее значение символа по стандарту Code 128
// Для печатных символов ASCII (коды 32-126) внутреннее значение равно (КодASCII - 32)
Если КодASCII >= 32 И КодASCII <= 126 Тогда
ВнутреннееЗначение = КодASCII - 32;
Иначе
// Если встретился недопустимый символ, заменяем его пробелом (значение 0)
ВнутреннееЗначение = 0;
КонецЕсли;
// Добавляем к контрольной сумме произведение значения на позицию символа
КонтрольнаяСумма = КонтрольнаяСумма + (ВнутреннееЗначение * Позиция);
// Переводим внутреннее значение в символ шрифта Grand Zebu
Если ВнутреннееЗначение <= 94 Тогда
// Для значений 0..94 прибавляем 32
СимволШрифта = Символ(ВнутреннееЗначение + 32);
Иначе
// Для значений 95..102 прибавляем 100
СимволШрифта = Символ(ВнутреннееЗначение + 100);
КонецЕсли;
Результат = Результат + СимволШрифта;
КонецЦикла;
// Находим остаток от деления контрольной суммы на 103
ЗначениеКонтрольногоСимвола = КонтрольнаяСумма % 103;
// Переводим контрольный символ в символ шрифта Grand Zebu
Если ЗначениеКонтрольногоСимвола = 0 Тогда
// Особенность шрифта Grand Zebu: во избежание проблем с отображением пробела
// в качестве контрольного символа на конце строки, значение 0 заменяется символом с кодом 212
КонтрольныйСимвол = Символ(212);
ИначеЕсли ЗначениеКонтрольногоСимвола <= 94 Тогда
КонтрольныйСимвол = Символ(ЗначениеКонтрольногоСимвола + 32);
Иначе
КонтрольныйСимвол = Символ(ЗначениеКонтрольногоСимвола + 100);
КонецЕсли;
// Добавляем контрольный символ к результату
Результат = Результат + КонтрольныйСимвол;
// В конец штрихкода добавляем стоп-символ Stop.
// Для шрифта Grand Zebu внутренний код 106 соответствует символу с ASCII-кодом 211
Результат = Результат + Символ(211);
Возврат Результат;
КонецФункции
Рассмотрим подробнее преобразование строки "1C" с помощью нашей функции:
Start B (значение 104) преобразуется в Символ(209), что отображается как символ Ñ. Контрольная сумма изначально равна 104.49 - 32 = 17. Прибавляем к контрольной сумме: 104 + (17 * 1) = 121. Символ шрифта: Символ(17 + 32) = Символ(49), то есть та же единица "1".67 - 32 = 35. Прибавляем к контрольной сумме: 121 + (35 * 2) = 191. Символ шрифта: Символ(35 + 32) = Символ(67), то есть буква "C".191 % 103 = 88.Символ(88 + 32) = Символ(120), что соответствует строчной латинской букве "x".Stop (внутреннее значение 106), который в шрифте Grand Zebu соответствует коду 211, визуально это символ Ó.На выходе нашей функции мы получим текстовую строку: "Ñ1CxÓ". Если вывести эту строку в ячейку табличного документа 1С и установить для этой ячейки шрифт Code 128, визуально отобразится красивый и полностью валидный штрихкод, который мгновенно считается любым сканером.
Если вам требуется выводить длинные цифровые последовательности (например, коды маркировки, штрихкоды EAN-13, EAN-128 или номера накладных), настоятельно рекомендуется использовать подмножество Subset C. Логика переключения выглядит так:
Start C (внутреннее значение 105, символ с кодом 210).Такой подход экономит до 40% ширины печатного поля, что критически важно при печати на маленьких термоэтикетках (например, 58х40 или 30х20 мм). При необходимости можно воспользоваться готовым решением для печати этикеток и ценников с генератором штрихкодов.
Выясним причины, почему связка «1С + TTF-шрифт» в современных реалиях часто превосходит классические внешние компоненты:
1CBarCode) жестко привязаны к Windows и 32-разрядной архитектуре. В эпоху массового перехода серверов 1С на Linux, а рабочих мест — на тонкие клиенты под macOS и Web-клиенты в браузерах, шрифты остаются универсальным решением. Шрифт достаточно один раз установить в операционную систему сервера (для генерации PDF/табличных документов на сервере) или на клиентские машины.Чтобы штрихкод отображался корректно, необходимо правильно подготовить рабочую среду:
code128.ttf и выберите пункт "Установить для всех пользователей"./usr/share/fonts/truetype/ (или ~/.fonts/) и обновите кэш шрифтов операционной системы с помощью команды fc-cache -f -v из терминала. После этого перезапустите службу сервера 1С:Предприятия.Используя предложенный алгоритм, вы сможете быстро и надежно внедрить печать высококачественных штрихкодов в любые печатные формы вашей конфигурации 1С. Для комплексной автоматизации этого процесса подойдёт подсистема настройки отображения штрихкодов в печатных формах и этикетках.