Почему коды маркировки в чеке дублируются или привязываются к немаркированным товарам в 1С 7.7

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

При внедрении обязательной маркировки товаров пользователи часто сталкиваются с ситуацией, когда данные в Личном кабинете Честного знака (ЧЗ) не соответствуют фактическим продажам. Типичный сценарий: вы продаете в одном чеке маркированный товар (например, обувь или одежду) и обычный сопутствующий товар (носки, аксессуары). В итоге в системе мониторинга код маркировки первого товара внезапно «приклеивается» ко всем последующим позициям чека, даже если они не подлежат маркировке. Рассмотрим подробно, почему это происходит и как исправить эту проблему в программном коде 1С 7.7.

Анализируем цепочку передачи данных

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

  1. Программист в 1С 7.7 считывает марку и передает ее в объект драйвера ККТ.
  2. Драйвер (например, АТОЛ или Штрих-М) формирует команду для фискального регистратора (ФР).
  3. ФР записывает данные в фискальный накопитель (ФН) и печатает чек, отправляя электронную копию оператору фискальных данных (ОФД).
  4. ОФД транслирует полученные теги (в частности, тег 1162 или 1163) в систему «Честный знак».

Если в ОФД чек выглядит корректно, а в Честном знаке позиции путаются или маркировка дублируется, это означает, что ошибка закралась на этапе формирования электронного чека внутри кассы. Как выясняется на практике, проблема чаще всего кроется в логике взаимодействия 1С с драйвером кассового аппарата.

Выясняем причину: эффект «залипания» буфера

Разберем техническую суть проблемы. В старых конфигурациях 1С 7.7 взаимодействие с ККТ происходит через последовательный вызов свойств и методов COM-объекта драйвера. Когда мы регистрируем позицию чека, мы передаем наименование, цену, количество и, если товар маркированный, код маркировки (ControlUnit или MarkingCode).

Основная «ловушка» заключается в том, что драйвер кассы — это объект, который сохраняет состояние своих свойств до тех пор, пока они не будут явно изменены или обнулены. Рассмотрим ситуацию: в чеке три позиции:

  1. Свитер (Маркированный)
  2. Носки (Немаркированный)
  3. Перчатки (Немаркированный)

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

Решение проблемы: принудительное обнуление параметров

Чтобы устранить эту «шляпу», как выразился автор темы, необходимо внести изменения в обработку обслуживания ККТ или непосредственно в код Глобального модуля (или документа Чек), где происходит формирование строк фискального чека. Нам нужно гарантировать, что для каждой новой позиции параметры маркировки будут очищены.

Проанализируем пример правильной логики в цикле обхода строк чека:


// Цикл по строкам документа
ВыбратьСтроки();
Пока ПолучитьСтроку() = 1 Цикл
    
    // ВАЖНО: Принудительно обнуляем код маркировки в драйвере перед каждой позицией
    // Это предотвратит "залипание" данных от предыдущего товара
    Драйвер.MarkingCode = ""; 
    
    // Если используется старый драйвер АТОЛ, свойство может называться иначе,
    // например, ControlUnit. Проверьте документацию к вашему драйверу.
    
    Драйвер.Name = СокрЛП(Товар.Наименование);
    Драйвер.Price = ТекущаяЦена;
    Драйвер.Quantity = ТекущееКоличество;
    
    // Проверяем, нужно ли передавать марку для текущего товара
    Если (ПустоеЗначение(ТекущийКодМаркировки) = 0) Тогда
        // Передаем считанный DataMatrix
        Драйвер.MarkingCode = ТекущийКодМаркировки;
        
        // Для ФФД 1.2 также важно указать тип маркировки
        // Драйвер.ItemType = 1; // Например, для одежды/обуви
    КонецЕсли;

    // Регистрация позиции
    Если Драйвер.Registration() <> 0 Тогда
        Сообщить("Ошибка регистрации позиции: " + Драйвер.ResultDescription);
        Возврат;
    КонецЕсли;

КонецЦикла;

Дополнительные аспекты: Тег 1212 и ФФД 1.2

При работе с маркировкой по современным протоколам (ФФД 1.2) важно не только обнулять код маркировки, но и правильно передавать Признак предмета расчета (тег 1212). Рассмотрим подробнее:

Если вы не указываете этот признак явно для каждой строки, касса может ошибочно интерпретировать немаркированный товар как маркированный, основываясь на данных предыдущей строки. Обязательно убедитесь, что в коде 1С перед методом Registration() вы задаете правильный тип предмета расчета для каждой позиции.

Рекомендации по отладке

Если после внесения изменений проблема сохраняется, выполните следующие шаги:

  1. Логирование драйвера: Включите ведение лог-файла в настройках драйвера ККТ (АТОЛ/Штрих-М). Проанализируйте лог: посмотрите, какие именно команды уходят на кассу. Ищите строки, где устанавливается параметр MarkingCode или LIBFPTR_PARAM_MARKING_CODE. Если вы видите, что код устанавливается для немаркированного товара — проблема в 1С.
  2. Версия драйвера: Убедитесь, что вы используете актуальную версию драйвера (например, АТОЛ 10.x). Старые версии драйверов 8-й и 9-й серий могут некорректно работать с очисткой атрибутов маркировки через COM-интерфейс.
  3. Проверка тега 1162: Посмотрите электронный чек в Личном кабинете ОФД. Если в JSON-структуре чека тег маркировки присутствует у позиций, где его быть не должно, значит касса сформировала его ошибочно по вине некорректных команд из 1С.

Таким образом, ключ к решению проблемы кроется в явном управлении состоянием драйвера. Никогда не полагайтесь на то, что драйвер сам «поймет», что маркировка закончилась. В 1С 7.7 каждое свойство должно быть либо заполнено актуальным значением, либо принудительно очищено перед регистрацией любой строки чека.

← На главную