Как сформировать и записать тег 1162 для табачной продукции из 1С

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

При реализации механизмов маркировки в 1С программисты часто сталкиваются с необходимостью ручного формирования тега 1162 (код товара). Особенно это актуально для работы с кассовым оборудованием по форматам фискальных данных (ФФД) 1.05 и 1.1. В этой статье мы подробно разберем, как правильно преобразовать данные кода маркировки табачной продукции в требуемый бинарный формат, объединить их и подготовить для передачи в драйвер ККТ.

Структура тега 1162 для табака

Для начала проанализируем структуру данных. Согласно требованиям ЦРПТ и спецификациям ФНС, тег 1162 для табачной продукции должен состоять ровно из 15 байт. Рассмотрим подробнее распределение этих байтов:

  1. Байты 1-2 (Идентификатор типа): Постоянное значение для табака — 00 05 (в HEX-представлении).
  2. Байты 3-8 (GTIN): 14-значный номер GTIN, преобразованный в 6-байтовое целое число.
  3. Байты 9-15 (Серийный номер): 7 символов индивидуального серийного номера упаковки, представленные в виде ASCII-кодов (7 байт).

Важный нюанс: Криптографический хвост (идентификаторы применения 91 и 92) в тег 1162 не включается. Попытка записать в тег полную строку Data Matrix приведет к ошибке драйвера или некорректной передаче данных в ОФД.

Шаг 1: Преобразование GTIN в бинарный вид

Выясним причину трудностей при работе с GTIN. В 1С GTIN обычно хранится как строка из 14 цифр, например, 00000046210654. Для тега 1162 нам нужно преобразовать это значение в число, а затем — в массив из 6 байт.

Разберем, как получить шестнадцатеричное представление числа. Для этого можно использовать вспомогательную функцию перевода систем исчисления:


Функция DecToHex(Знач ЧислоЗначение)
    Результат = "";
    Основание = 16;
    Алфавит = "0123456789ABCDEF";
    
    Пока ЧислоЗначение > 0 Цикл
        Остаток = ЧислоЗначение % Основание;
        Результат = Сред(Алфавит, Остаток + 1, 1) + Результат;
        ЧислоЗначение = Цел(ЧислоЗначение / Основание);
    КонецЦикла;
    
    Возврат Результат;
КонецФункции

Вызов DecToHex(Число("00000046210654")) вернет нам строку 2C11E5E. Однако для корректной записи нам нужно дополнить это значение нулями слева до 6 байт (12 символов HEX): 000002C11E5E.

Шаг 2: Работа с серийным номером

Серийный номер (например, ADgopSq) преобразуется проще — каждый символ заменяется его байтовым кодом. Рассмотрим пример, как в 1С 8.3 получить двоичные данные из строки серийного номера:


ПотокСерии = Новый ПотокВПамяти; 
ЗаписьТекста = Новый ЗаписьТекста(ПотокСерии, КодировкаТекста.ANSI); // ASCII
ЗаписьТекста.Записать("ADgopSq");
ЗаписьТекста.Закрыть();
СерияДвоичныеДанные = ПотокСерии.ЗакрытьИПолучитьДвоичныеДанные();

Шаг 3: Сборка итогового массива (Base64)

Проанализируем финальный этап. Нам нужно объединить все части в один объект ДвоичныеДанные. Наиболее надежный способ сделать это в современных версиях платформы 1С — использовать ПотокВПамяти и ЗаписьДанных. Это позволит избежать ошибок с кодировками и типами данных.

Рассмотрим пошаговый пример сборки тега:


// Исходные данные
GTIN_Числом = Число("00000046210654");
СерийныйНомер = "ADgopSq";

ПотокРезультата = Новый ПотокВПамяти;
ЗаписьД = Новый ЗаписьДанных(ПотокРезультата);

// 1. Записываем тип маркировки (00 05)
ЗаписьД.ЗаписатьБайт(0);
ЗаписьД.ЗаписатьБайт(5);

// 2. Записываем GTIN как 6 байт (Big-endian)
// Вычисляем байты последовательным делением
МассивБайтовGTIN = Новый Массив;
ВремGTIN = GTIN_Числом;
Для Счетчик = 1 По 6 Цикл
    МассивБайтовGTIN.Вставить(0, ВремGTIN % 256);
    ВремGTIN = Цел(ВремGTIN / 256);
КонецЦикла;

Для Каждого ТекущийБайт Из МассивБайтовGTIN Цикл
    ЗаписьД.ЗаписатьБайт(ТекущийБайт);
КонецЦикла;

// 3. Записываем Серийный номер (7 символов)
Для Индекс = 1 По 7 Цикл
    Символ = Сред(СерийныйНомер, Индекс, 1);
    ЗаписьД.ЗаписатьБайт(КодСимвола(Символ));
КонецЦикла;

ЗаписьД.Закрыть();
ИтоговыеДанные = ПотокРезультата.ЗакрытьИПолучитьДвоичныеДанные();

// 4. Кодируем в Base64 для передачи в драйвер
РезультатBase64 = Base64Строка(ИтоговыеДанные);
// Ожидаемый результат: AAUAAALBHl5BRGdvcFNx

Особенности реализации для разных ФФД

Посмотрим на ситуацию шире. Если вы используете оборудование, поддерживающее ФФД 1.2, ручное формирование тега 1162 может не потребоваться. В ФФД 1.2 используется тег 1163, и драйверы ККТ (например, АТОЛ 10-й версии) чаще всего принимают полную считанную строку кода маркировки. ККТ самостоятельно парсит строку, выделяет GTIN и серийный номер и отправляет запрос о проверке кода в систему "Честный Знак".

Однако, если ваша система работает в режиме ФФД 1.05 или 1.1 (что до сих пор встречается в автономных режимах или при использовании старых фискальных накопителей), описанный выше алгоритм является единственно верным способом корректной передачи кода товара в чеке.

Резюмируем важные моменты:

  1. Всегда проверяйте длину GTIN: он должен быть дополнен нулями до 14 цифр перед конвертацией.
  2. Следите за порядком байтов (Big-endian) при записи GTIN в поток.
  3. Для записи 00 05 используйте метод ЗаписатьБайт, чтобы гарантировать правильный размер данных.
  4. Итоговая строка Base64 должна иметь длину 20 символов (после кодирования 15 байт данных).

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

← На главную