Почему при печати чека с маркированным товаром в 1С возникает ошибка "отсутствует полный код маркировки"?

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

При работе с маркированными товарами в 1С:Бухгалтерии 3.0 и интеграции с системой "Честный ЗНАК" нередко возникают специфические ошибки, одной из которых является сообщение "отсутствует полный код маркировки" при попытке печати чека. Давайте подробно разберем, почему это происходит и как устранить данную проблему, основываясь на практическом опыте и примерах кода.

Что такое полный код маркировки и почему он важен?

Прежде всего, давайте выясним, что представляет собой полный код маркировки (КМ) и почему его корректная передача критически важна для успешной реализации маркированной продукции. Полный код маркировки — это уникальная последовательность символов, наносимая на каждую единицу товара, подлежащего обязательной маркировке. Он состоит из нескольких ключевых частей:

  1. GTIN (Global Trade Item Number): Глобальный номер товара, обычно 14 цифр.
  2. Серийный номер: Индивидуальный номер экземпляра товара, до 13 символов.
  3. Ключ проверки: 4 символа.
  4. Код проверки (криптохвост): Последовательность из 44 или 88 символов, обеспечивающая криптографическую защиту.

Ошибка "отсутствует полный код маркировки" чаще всего возникает, когда в учетную систему 1С передается или сохраняется код маркировки без этой самой криптографической части, то есть без "криптохвоста". В некоторых случаях, особенно при получении кодов из внешних источников (например, из PDF-файлов, от типографий или когда требуется загрузка списка товаров из Excel), может быть передан только код идентификации (КИ), состоящий из GTIN и серийного номера (около 31 символа). Однако для операций на кассе и проверки в "Честном ЗНАКе" требуется именно полный код маркировки, содержащий все компоненты.

Также важно отметить, что в коде маркировки присутствует специальный непечатаемый ASCII-символ-разделитель "GS" (29 символ таблицы ASCII), который может вызывать проблемы, если он не сохраняется или некорректно обрабатывается системой. Если этот символ отсутствует или введен с клавиатуры в текстовом формате, система не распознает код правильно.

Анализ некорректных подходов к загрузке кодов маркировки

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

Изначально был предложен следующий код для заполнения данных о штрихкодах:


спрШУТ = Справочники.ШтрихкодыУпаковокТоваров;
...
//заполнение кодов ЧЗ
Шк64 = РезультатЗаполнения[Количество-1].Штрихкод;
Шк32 = ШтрихкодированиеИСКлиентСервер.ШтрихкодВФорматеGS1(ШтрихкодированиеОбщегоНазначенияИСКлиентСервер.Base64ВШтрихкод(Шк64));
//Шк28 = Лев(Шк32,28);
НовСтр.Штрихкод = Шк32;
НовСтр.КодАкцизнойМарки = Шк32;//Шк64;
ссСпрШУТ = СпрШУТ.ПолучитьПоЗначениюШтрихкода(Шк32);//(Шк28);
Если ссСпрШУТ = Неопределено Тогда
    ДанныеШтрихкода = СпрШУТ.СтруктураСозданияШтрихкодаУпаковки();
    ДанныеШтрихкода.ТипУпаковки = Перечисления.ТипыУпаковок.МаркированныйТовар;
    ДанныеШтрихкода.Номенклатура = НовСтр.Номенклатура;
    ДанныеШтрихкода.Количество = 1;
    ДанныеШтрихкода.ТипШтрихкода = Перечисления.ТипыШтрихкодов.GS1_DataMatrix;
    ДанныеШтрихкода.Штрихкод = Шк32;
    //ДанныеШтрихкода.ХешСуммаНормализации = ИнтеграцияИС.ХешированиеДанныхSHA256(ШтрихкодыУпаковокКлиентСервер.ШтрихкодGS1(Шк32));
        
    НовСтр.АкцизнаяМарка = СпрШУТ.СоздатьШтрихкодУпаковки(ДанныеШтрихкода);
    сообщить("создан штрихкод"+Шк32+".");
Иначе
    НовСтр.АкцизнаяМарка = ссСпрШУТ;
КонецЕсли;

В этом фрагменте мы видим попытку преобразования Base64-кода (Шк64) в формат GS1 DataMatrix (Шк32). Однако, ключевая проблема часто заключается в том, что Шк64, приходящий из внешней программы, может изначально не содержать криптохвоста или быть некорректно сформированным. Если Base64ВШтрихкод получает неполный код, то и ШтрихкодВФорматеGS1 не сможет создать корректный полный GS1-код.

Поле НовСтр.КодАкцизнойМарки, которое является полем табличной части документа "Розничная продажа", должно содержать полный Base64-код маркировки. Присвоение ему Шк32 (GS1-формата) вместо Шк64 (Base64) также могло быть причиной проблемы, так как система ожидает определенный формат в каждом поле.

В другой попытке автор использовал функцию ИнтерфейсИСМП.РазобратьИНормализоватьКодМаркировки:


//Шк32 = ШтрихкодированиеИСКлиентСервер.ШтрихкодВФорматеGS1(ШтрихкодированиеОбщегоНазначенияИСКлиентСервер.Base64ВШтрихкод(Шк64));
Шк32 = ИнтерфейсИСМП.РазобратьИНормализоватьКодМаркировки(ШтрихкодированиеОбщегоНазначенияИСКлиентСервер.Base64ВШтрихкод(Шк64));

Эта функция предназначена для правильного разбора и нормализации кода маркировки, но если исходный Base64-код (Шк64) был неполным, она также не сможет его восстановить. Кроме того, возникшая ошибка с "непечатаемым символом" при открытии списка СпрШУТ указывает на возможные проблемы с кодировкой или наличием некорректных символов в сохраненных штрихкодах.

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


//заполнение кодов ЧЗ
Шк64 = РезультатЗаполнения[Количество-1].Штрихкод;
Шк32 = ШтрихкодированиеИСКлиентСервер.ШтрихкодВФорматеGS1(ШтрихкодированиеОбщегоНазначенияИСКлиентСервер.Base64ВШтрихкод(Шк64));
НовСтр.Штрихкод = Шк32;
НовСтр.КодАкцизнойМарки = Шк32;
ссСпрШУТ = СпрШУТ.ПолучитьПоЗначениюШтрихкода(Шк32);
Если ссСпрШУТ = Неопределено Тогда
    ДанныеШтрихкода = СпрШУТ.СтруктураСозданияШтрихкодаУпаковки();
    ДанныеШтрихкода.ТипУпаковки = Перечисления.ТипыУпаковок.МонотоварнаяУпаковка;
    ДанныеШтрихкода.Номенклатура = НовСтр.Номенклатура;
    ДанныеШтрихкода.Количество = 1;
    ДанныеШтрихкода.ДатаУпаковки = Док.Дата;
    ДанныеШтрихкода.ТипШтрихкода = Перечисления.ТипыШтрихкодов.GS1_128;
    ДанныеШтрихкода.Штрихкод = Шк32;
        
    НовСтр.АкцизнаяМарка = СпрШУТ.СоздатьШтрихкодУпаковки(ДанныеШтрихкода);
    сообщить("создан штрихкод"+Шк32+".");
Иначе
    НовСтр.АкцизнаяМарка = ссСпрШУТ;
КонецЕсли;

Здесь автор изменил ТипУпаковки на Перечисления.ТипыУпаковок.МонотоварнаяУпаковка и ТипШтрихкода на Перечисления.ТипыШтрихкодов.GS1_128. Хотя для некоторых типов маркировки это может быть корректно, для большинства маркированных товаров, использующих Data Matrix, правильным типом является Перечисления.ТипыШтрихкодов.GS1_DataMatrix, а тип упаковки чаще всего МаркированныйТовар. Несоответствие этих параметров типу фактически используемого кода также может приводить к ошибкам или игнорированию команды печати, как это произошло в данном случае.

Корректное создание записи в справочнике "ШтрихкодыУпаковокТоваров"

Для правильной работы с маркировкой критически важно корректно создавать и хранить штрихкоды упаковок (в ряде случаев может потребоваться запрос остатков из системы «Честный знак» для выравнивания данных). Мы используем справочник Справочники.ШтрихкодыУпаковокТоваров.

Разберем основные принципы:

  1. Получение GS1-кода: Убедитесь, что Шк32, который вы получаете после преобразования из Base64 (Шк64), действительно является полным кодом маркировки в формате GS1 DataMatrix, включая непечатаемый разделитель GS (ASCII 29) и криптохвост. Если Шк64 приходит из внешней системы, убедитесь, что она передает полный код маркировки.
  2. Структура создания штрихкода: Для создания нового элемента справочника используем типовую структуру СпрШУТ.СтруктураСозданияШтрихкодаУпаковки().
  3. Заполнение полей:
    • ДанныеШтрихкода.ТипУпаковки: Для большинства маркированных товаров это Перечисления.ТипыУпаковок.МаркированныйТовар.
    • ДанныеШтрихкода.Номенклатура: Ссылка на элемент номенклатуры, к которой относится марка.
    • ДанныеШтрихкода.Количество: Обычно 1 для единичного маркированного товара.
    • ДанныеШтрихкода.ТипШтрихкода: Для Data Matrix это Перечисления.ТипыШтрихкодов.GS1_DataMatrix.
    • ДанныеШтрихкода.Штрихкод: Сюда записываем Шк32 – полный код маркировки в формате GS1 DataMatrix (с AI, скобками и разделителями).
  4. Присвоение в документе: Поле НовСтр.АкцизнаяМарка в табличной части документа РозничнаяПродажа должно ссылаться на созданный или найденный элемент справочника Справочники.ШтрихкодыУпаковокТоваров. Поле НовСтр.КодАкцизнойМарки в табличной части документа РозничнаяПродажа должно содержать Base64-код (Шк64), так как именно он используется для отправки в Честный ЗНАК.

Интеграция с регистром "Пул кодов маркировки СУЗ" для разрешительного режима

Для корректной работы разрешительного режима, который требует онлайн-проверки кода маркировки в системе "Честный ЗНАК" перед продажей, необходимо не только создать запись в справочнике ШтрихкодыУпаковокТоваров, но и заполнить регистр сведений РегистрыСведений.ПулКодовМаркировкиСУЗ. Этот регистр хранит подробные данные о статусе кодов маркировки и используется для взаимодействия с ГИС МТ.

Давайте рассмотрим расширенный фрагмент кода, который включает заполнение этого регистра:


//заполнение кодов ЧЗ
Шк64 = РезультатЗаполнения[Количество-1].Штрихкод;
Шк32 = ШтрихкодированиеИСКлиентСервер.ШтрихкодВФорматеGS1(ШтрихкодированиеОбщегоНазначенияИСКлиентСервер.Base64ВШтрихкод(Шк64));
//Шк32 = ИнтерфейсИСМП.РазобратьИНормализоватьКодМаркировки(ШтрихкодированиеОбщегоНазначенияИСКлиентСервер.Base64ВШтрихкод(Шк64));// может так...
НовСтр.Штрихкод = Шк32;
НовСтр.КодАкцизнойМарки = Шк64; // Важно: здесь должен быть Шк64 (Base64)
ссСпрШУТ = СпрШУТ.ПолучитьПоЗначениюШтрихкода(Шк32);
Если ссСпрШУТ = Неопределено Тогда
    ДанныеШтрихкода = СпрШУТ.СтруктураСозданияШтрихкодаУпаковки();
    ДанныеШтрихкода.ТипУпаковки = Перечисления.ТипыУпаковок.МаркированныйТовар;
    ДанныеШтрихкода.Номенклатура = НовСтр.Номенклатура;
    ДанныеШтрихкода.Количество = 1;
    ДанныеШтрихкода.ДатаУпаковки = Док.Дата;
    ДанныеШтрихкода.ТипШтрихкода = Перечисления.ТипыШтрихкодов.GS1_DataMatrix;
    ДанныеШтрихкода.Штрихкод = Шк32;
        
    НовСтр.АкцизнаяМарка = СпрШУТ.СоздатьШтрихкодУпаковки(ДанныеШтрихкода);
    сообщить("создан штрихкод"+Шк32+".");
        
    //пул СУЗ
    ПараметрыСканирования = ШтрихкодированиеОбщегоНазначенияИСКлиентСервер.БазовыеПараметрыСканирования();
    ШтрихкодированиеОбщегоНазначенияИСКлиентСервер.ЗаполнитьБазовыеПараметрыСканирования(ПараметрыСканирования, Док);
    ШтрихкодированиеОбщегоНазначенияИСМПКлиентСервер.ЗаполнитьПараметрыСканирования(Док,Перечисления.ВидыПродукцииИС.ПустаяСсылка(),ПараметрыСканирования,Неопределено);
        
    ДанныеШтрихкодаПолные = ШтрихкодированиеОбщегоНазначенияИС.ИнициализироватьДанныеШтрихкода(ПараметрыСканирования);
    ДанныеШтрихкодаПолные.Штрихкод       = Шк32;
    ДанныеШтрихкодаПолные.ШтрихкодBase64 = Шк64;
    ДанныеШтрихкодаПолные.МаркируемаяПродукция = Истина;
    ДанныеШтрихкодаПолные.ТипУпаковки = Перечисления.ТипыУпаковок.МаркированныйТовар;
    ДанныеШтрихкодаПолные.ТипШтрихкода = Перечисления.ТипыШтрихкодов.GS1_DataMatrix;
    ДанныеШтрихкодаПолные.Номенклатура = НовСтр.Номенклатура;
    ДанныеШтрихкодаПолные.Вставить("ЕстьВПулеКодовМаркировки", Ложь); //иначе ошибка...
    ДанныеШтрихкодаПолные.Вставить("ПолныйКодМаркировки", ""); //иначе ошибка...
        
    РегистрыСведений.ПулКодовМаркировкиСУЗ.ЗаписатьДанныеКодаМаркировки(ДанныеШтрихкодаПолные,ПараметрыСканирования);
        
Иначе
    НовСтр.АкцизнаяМарка = ссСпрШУТ;
КонецЕсли;

В этом коде мы видим, как после создания записи в справочнике ШтрихкодыУпаковокТоваров, система приступает к заполнению данных для регистра ПулКодовМаркировкиСУЗ. Разберем ключевые моменты:

  1. Инициализация параметров сканирования: Используются функции ШтрихкодированиеОбщегоНазначенияИСКлиентСервер.БазовыеПараметрыСканирования() и ЗаполнитьБазовыеПараметрыСканирования() для подготовки контекста, в котором будет обрабатываться код маркировки. Эти параметры содержат информацию о документе, организации, виде продукции и т.д.
  2. Полные данные штрихкода: Создается структура ДанныеШтрихкодаПолные с помощью ШтрихкодированиеОбщегоНазначенияИС.ИнициализироватьДанныеШтрихкода().
  3. Заполнение полей ДанныеШтрихкодаПолные:
    • ДанныеШтрихкодаПолные.Штрихкод: Должен содержать GS1-код (Шк32).
    • ДанныеШтрихкодаПолные.ШтрихкодBase64: Должен содержать Base64-код (Шк64). Критически важно, чтобы здесь был именно полный Base64-код, включая криптохвост. Если ваш внешний источник предоставляет только укороченный Base64, это и будет корневой причиной проблемы.
    • ДанныеШтрихкодаПолные.МаркируемаяПродукция: Устанавливается в Истина.
    • ДанныеШтрихкодаПолные.ТипУпаковки и ДанныеШтрихкодаПолные.ТипШтрихкода: Соответствуют ранее использованным для справочника.
    • ДанныеШтрихкодаПолные.Номенклатура: Ссылка на номенклатуру.
    • ДанныеШтрихкодаПолные.Вставить("ЕстьВПулеКодовМаркировки", Ложь) и ДанныеШтрихкодаПолные.Вставить("ПолныйКодМаркировки", ""): Эти строки были добавлены автором для обхода ошибок, что указывает на то, что типовые механизмы ожидали эти поля, но они могли отсутствовать или быть некорректно заполнены. Важно убедиться, что эти поля корректно обрабатываются в типовой конфигурации.
  4. Запись данных в регистр: Наконец, данные записываются в регистр сведений функцией РегистрыСведений.ПулКодовМаркировкиСУЗ.ЗаписатьДанныеКодаМаркировки().

Ошибка "Поле объекта не обнаружено (ИдентификаторЗапросаГИСМТ)" и разрешительный режим

После решения проблемы с "отсутствует полный код маркировки" может возникнуть новая ошибка: "Поле объекта не обнаружено (ИдентификаторЗапросаГИСМТ)". Эта ошибка напрямую связана с работой разрешительного режима и взаимодействием с Государственной информационной системой маркировки товаров (ГИС МТ).

Разрешительный режим — это механизм, который в режиме реального времени проверяет легальность каждой торговой операции с маркированными товарами. При сканировании кода Data Matrix на кассе, она отправляет запрос в ГИС МТ. Система проверяет статус товара, его принадлежность продавцу, сроки годности и другие параметры. Только после получения электронного "одобрения" от ГИС МТ продажа разрешается. Если запрос не может быть сформирован или отправлен корректно, система выдает ошибку. Для отладки таких процессов часто используется клиент API ГИС МТ, позволяющий проверять данные на стороне сервера.

Ошибка "Поле объекта не обнаружено (ИдентификаторЗапросаГИСМТ)" означает, что в какой-то момент формирования запроса к ГИС МТ или обработки его результата, система не смогла найти поле ИдентификаторЗапросаГИСМТ. Это может произойти по нескольким причинам:

  1. Неполные данные о коде маркировки: Если даже после всех манипуляций в ПулКодовМаркировкиСУЗ не попадает полный и корректный код маркировки, система не сможет сформировать валидный запрос к ГИС МТ.
  2. Устаревшая конфигурация или драйверы: Механизмы разрешительного режима постоянно обновляются. Устаревшие версии 1С, драйверов ККТ или прошивок кассы могут не поддерживать последние изменения в протоколах взаимодействия с ГИС МТ.
  3. Проблемы с настройками ККТ: Сама касса должна быть настроена для работы с ФФД 1.2 и поддерживать разрешительный режим.

Окончательное решение проблемы "отсутствует полный код маркировки"

Как часто бывает в мире 1С и интеграции, комплексные проблемы решаются путем обновления всех компонентов системы. В данном случае, ключевым моментом, который позволил преодолеть ошибку "отсутствует полный код маркировки" и успешно передавать данные о выбытии в "Честный ЗНАК", стало следующее:

  1. Обновление конфигурации 1С:Бухгалтерия 3.0: Необходимо обновить 1С БП 3.0 до версии 3.0.162.22 или выше. Каждое обновление 1С содержит исправления и улучшения для работы с маркировкой, включая актуализацию механизмов взаимодействия с "Честным ЗНАКом".
  2. Обновление драйвера АТОЛ: Установка актуальной версии драйвера АТОЛ, в данном случае 10.10.5.0. Драйверы ККТ играют ключевую роль в корректной передаче данных о маркировке от 1С к кассовому аппарату и далее в ОФД/ГИС МТ.
  3. Загрузка свежей компоненты в драйвер оборудования: Помимо самого драйвера, необходимо убедиться, что в драйвер оборудования загружена свежая компонента (например, из архива ATOL_KKT_10.zip, соответствующего версии 10.10.5.0). Эти компоненты содержат специфические библиотеки и настройки, необходимые для полноценной работы с маркировкой и разрешительным режимом.

После выполнения этих шагов, данные о выбытии начали успешно передаваться в "Честный ЗНАК", а статус разрешительного режима стал "Пройден", что указывает на корректную работу всей цепочки взаимодействия.

Новая проблема: ограничение количества позиций в чеке

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

Эта проблема, скорее всего, связана с:

  1. Особенностями прошивки ККТ: Некоторые прошивки могут иметь ограничения на размер пакета данных, передаваемых для печати маркированных позиций, или особенности обработки больших объемов данных.
  2. Драйверами оборудования: Несмотря на обновление, могут быть нюансы взаимодействия между версией 1С, версией драйвера и прошивкой ККТ, которые проявляются при увеличении нагрузки.
  3. Настройками взаимодействия: Возможно, таймауты или другие параметры обмена данными между 1С и ККТ настроены не оптимально для обработки длинных чеков с маркировкой.
  4. Сетевыми проблемами: В редких случаях, нестабильное сетевое соединение может приводить к сбросу связи при передаче больших объемов данных.

Для диагностики этой проблемы рекомендуется:

  1. Изучить логи ККТ и драйвера в момент сбоя для выявления конкретной ошибки.
  2. Протестировать работу кассы с другими программами или специализированными утилитами АТОЛ для исключения проблем с самим устройством.
  3. Обратиться в техническую поддержку АТОЛ или 1С для получения целевых рекомендаций.

Общие рекомендации для работы с маркировкой в 1С

Для стабильной и безошибочной работы с маркированными товарами в 1С и "Честном ЗНАКе" мы рекомендуем следовать следующим правилам:

  1. Регулярные обновления: Всегда поддерживайте актуальные версии конфигурации 1С, драйверов ККТ и компонентов, связанных с маркировкой. Производители постоянно выпускают обновления, исправляющие ошибки и адаптирующие системы под новые требования законодательства.
  2. Качественное оборудование: Используйте только 2D-сканеры, способные считывать коды Data Matrix, и убедитесь, что они настроены корректно (часто помогает режим COM-порта).
  3. Полные коды маркировки: При получении кодов из внешних систем убедитесь, что они содержат все необходимые компоненты, включая криптохвост, и имеют правильный формат GS1 DataMatrix (с непечатаемыми символами-разделителями).
  4. ФФД 1.2: Убедитесь, что ваша онлайн-касса поддерживает формат фискальных данных (ФФД) 1.2 и имеет последнюю прошивку, поддерживающую разрешительный режим.
  5. Настройка "Честного ЗНАКа": Правильно настройте доступ к "Честному ЗНАКу" в 1С, включите опцию "Продажи маркированной продукции" и укажите корректные даты начала действия разрешительного режима для разных групп товаров.
  6. Локальный модуль "Честный ЗНАК" (ЛМ ЧЗ): Рассмотрите использование локального модуля для офлайн-проверки кодов маркировки, что повысит устойчивость работы в случае проблем с интернетом или недоступностью ГИС МТ.

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

← На главную