Как сформировать штрихкод Code 128 в 1С с помощью TTF-шрифта?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Вывод штрихкодов в печатные формы — классическая задача при автоматизации складского учета, логистики и розничной торговли. Традиционно для этого использовались внешние компоненты (в формате .ocx или современные Native API от 1С). Однако в последнее время все большую популярность приобретает альтернативный метод — генерация штрихкода с помощью специализированных TrueType шрифтов (TTF). Этот способ отличается высокой скоростью работы, полной кроссплатформенностью и отсутствием проблем с регистрацией внешних библиотек в операционной системе.

В этой статье мы подробно разберем, как устроен штрихкод стандарта Code 128, опровергнем популярные заблуждения разработчиков, рассмотрим математическую модель расчета контрольного числа по модулю 103 и напишем готовый компактный алгоритм на языке 1С для работы с популярным шрифтом Grand Zebu.

Главное заблуждение: «Все шрифты Code 128 одинаковы»

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

Хотя сам стандарт Code 128 жестко регламентирован международным стандартом ГОСТ ISO/IEC 15417-2013 (в плане чередования черных и белых полос различной ширины), отображение этих полос через символы шрифта TrueType целиком и полностью зависит от его создателя. Каждый автор сопоставляет определенные кодовые комбинации штрихов своим символам в таблице шрифта (character mapping). Если вы возьмете алгоритм, написанный под один шрифт, и примените его к другому, сканер считает некорректные данные или вообще откажется распознавать штрихкод.

В мировой практике разработки выделяют три основные группы раскладок для шрифтов Code 128:

В рамках данной статьи мы спроектируем и реализуем алгоритм 1С именно под шрифт Grand Zebu (code128.ttf), так как он бесплатен, стабилен и поддерживается абсолютным большинством сканеров.

Архитектура Code 128 и выбор подмножеств (Subset)

Штрихкод Code 128 уникален тем, что позволяет кодировать не только цифры, но и буквы латиницы (как верхнего, так и нижнего регистра), а также управляющие символы ASCII. Для достижения максимальной плотности (компактности) штрихкода стандарт разделен на три набора символов:

  1. Subset A: Включает заглавные буквы, цифры и управляющие символы (ACK, CR, LF и т.д.).
  2. Subset B: Включает все печатные символы латиницы (заглавные и строчные буквы), цифры и стандартные знаки пунктуации. Это наиболее универсальный набор.
  3. Subset C: Разработан специально для оптимизации кодирования цифровых данных. В этом режиме каждые две цифры упаковываются в один символ штрихкода. Это позволяет сократить физическую ширину штрихкода почти в два раза!

Чтобы штрихкод получался максимально компактным, профессиональные алгоритмы должны динамически анализировать исходную строку. Если в строке встречается непрерывная последовательность из 4 или более цифр, алгоритм должен переключить режим шифрования на Subset C, а при появлении букв — вернуться на Subset B.

Для простоты понимания и надежности мы разберем базовый компактный алгоритм, работающий в пространстве Subset B, который идеально подходит для кодирования артикулов, серийных номеров и смешанных буквенно-цифровых кодов. В конце мы также затронем правила перехода на Subset C.

Математика расчета контрольной суммы Modulo 103

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

  1. Каждому символу в зависимости от выбранного подмножества присваивается его внутреннее числовое значение (от 0 до 102).
  2. Вычисляется стартовое значение, равное коду старт-символа (для Start B это значение всегда равно 104).
  3. Каждому последующему символу данных присваивается весовой коэффициент, равный его порядковому номеру в строке (начиная с 1).
  4. Значение каждого символа умножается на его весовой коэффициент, и результаты суммируются.
  5. Полученная общая сумма делится на 103. Остаток от этого деления и является значением контрольного символа.
  6. В конец строки добавляется контрольный символ и спецсимвол Stop (значение 106).

Реализация алгоритма на языке 1С

Перейдем к практике. Ниже представлен готовый код функции на языке 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" с помощью нашей функции:

  1. Стартовый символ Start B (значение 104) преобразуется в Символ(209), что отображается как символ Ñ. Контрольная сумма изначально равна 104.
  2. Первый символ строки — "1" (ASCII код 49). Внутреннее значение: 49 - 32 = 17. Прибавляем к контрольной сумме: 104 + (17 * 1) = 121. Символ шрифта: Символ(17 + 32) = Символ(49), то есть та же единица "1".
  3. Второй символ строки — "C" (ASCII код 67). Внутреннее значение: 67 - 32 = 35. Прибавляем к контрольной сумме: 121 + (35 * 2) = 191. Символ шрифта: Символ(35 + 32) = Символ(67), то есть буква "C".
  4. Вычисляем остаток от деления контрольной суммы на 103: 191 % 103 = 88.
  5. Контрольный символ со значением 88 переводится в символ шрифта: Символ(88 + 32) = Символ(120), что соответствует строчной латинской букве "x".
  6. Добавляем стоп-символ Stop (внутреннее значение 106), который в шрифте Grand Zebu соответствует коду 211, визуально это символ Ó.

На выходе нашей функции мы получим текстовую строку: "Ñ1CxÓ". Если вывести эту строку в ячейку табличного документа 1С и установить для этой ячейки шрифт Code 128, визуально отобразится красивый и полностью валидный штрихкод, который мгновенно считается любым сканером.

Оптимизация подмножества Subset C для чисто цифровых кодов

Если вам требуется выводить длинные цифровые последовательности (например, коды маркировки, штрихкоды EAN-13, EAN-128 или номера накладных), настоятельно рекомендуется использовать подмножество Subset C. Логика переключения выглядит так:

Такой подход экономит до 40% ширины печатного поля, что критически важно при печати на маленьких термоэтикетках (например, 58х40 или 30х20 мм). При необходимости можно воспользоваться готовым решением для печати этикеток и ценников с генератором штрихкодов.

Преимущества использования TTF-шрифтов перед компонентами

Выясним причины, почему связка «1С + TTF-шрифт» в современных реалиях часто превосходит классические внешние компоненты:

Правила установки и настройки шрифта в системе

Чтобы штрихкод отображался корректно, необходимо правильно подготовить рабочую среду:

  1. Установка в Windows: Нажмите правой кнопкой мыши на файл code128.ttf и выберите пункт "Установить для всех пользователей".
  2. Установка в Linux (сервер 1С): Скопируйте файл шрифта в директорию /usr/share/fonts/truetype/ (или ~/.fonts/) и обновите кэш шрифтов операционной системы с помощью команды fc-cache -f -v из терминала. После этого перезапустите службу сервера 1С:Предприятия.
  3. Настройка ячейки в 1С: В свойствах ячейки табличного документа, куда выводится закодированная строка, выберите шрифт Code 128 (или Grand Zebu, в зависимости от имени шрифта в системе). Установите достаточный размер шрифта (рекомендуется от 26 до 36 пунктов) и обязательно включите свойство Автовысота строки, чтобы штрихкод не обрезался сверху или снизу.

Используя предложенный алгоритм, вы сможете быстро и надежно внедрить печать высококачественных штрихкодов в любые печатные формы вашей конфигурации 1С. Для комплексной автоматизации этого процесса подойдёт подсистема настройки отображения штрихкодов в печатных формах и этикетках.

← На главную