Как исправить ошибку «Некорректная операция, внутренняя ошибка ПО» в Штрих-М при ФФД 1.2

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

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

В этой статье мы подробно разберем причины возникновения этой проблемы, проанализируем код и выясним, как правильно организовать последовательность команд драйвера, чтобы избежать сбоев при регистрации маркированных товаров.

Причина 1: Нарушение последовательности команд в ФФД 1.2

Разберем ситуацию: в старых версиях ФФД (1.05) мы могли свободно использовать методы печати текста, такие как PrintString, практически в любой момент формирования чека. Однако в ФФД 1.2 процесс работы с маркированным товаром стал строго регламентированным. Фискальный накопитель нового образца (ФН-М) ожидает четкой последовательности действий.

Проанализируем типичный ошибочный сценарий. Разработчик пытается вывести информацию о скидках или рекламный текст сразу после отправки кода маркировки, но до регистрации самой позиции. В этот момент ККТ находится в состоянии ожидания завершения операции с маркировкой. Любая посторонняя команда, такая как PrintString или StringForPrinting, сбивает внутренний алгоритм кассы, что и приводит к сообщению «Внутренняя ошибка ПО».

Рассмотрим пример кода, который вызывал падение системы у автора темы:


// Если в коде между проверкой марки и регистрацией позиции 
// вклинивается печать текста, ФФД 1.2 выдаст ошибку
Если ПустоеЗначение(СписокТоваров.СкидкаПоСтроке) = 0 Тогда
    Объект.StringForPrinting = "Скидка " + СписокТоваров.СкидкаПоСтроке;
    Объект.PrintString(); // КРИТИЧЕСКАЯ ОШИБКА: печать текста прерывает сессию маркировки
КонецЕсли;

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

Причина 2: Некорректная обработка спецсимволов DataMatrix (GS1)

Выясним причину, связанную с форматом кода маркировки. Код DataMatrix содержит непечатные символы-разделители GS (ASCII код 29). Программисты часто пытаются «собрать» код вручную, разрезая строку и вставляя Симв(29) программно. Это часто приводит к ошибкам, так как структура кода может меняться в зависимости от товарной группы.

Посмотрим на пример «опасного» кода:


GTINSerial = СокрЛП(Сред(КодМаркировки, 1, 31));
СоедКод = СокрЛП(Сред(КодМаркировки, 33, 6));
КриптоХвост = СокрЛП(Сред(КодМаркировки, 40, 47));
// Ручная вставка разделителей может исказить код
КМ = GTINSerial + Симв(29) + СоедКод + Симв(29) + КриптоХвост;
Объект.BarCode = КМ;

Рассмотрим, почему это работает нестабильно. Разные сканеры настроены по-разному. Один сканер может быть настроен в режиме эмуляции клавиатуры и «вырезать» спецсимволы, а другой — передавать их корректно. Если вы в коде принудительно добавляете Симв(29), а сканер их уже передал, ККТ получит некорректную последовательность байтов и вернет ошибку ПО.

Решение: Проанализируем настройки сканера. Рекомендуется перевести сканер в режим COM-портов (USB-VCP). В этом случае сканер передает код «как есть», вместе со всеми разделителями GS. В коде 1С достаточно передать полученную от сканера строку в объект драйвера без ручного «разрезания» и склеивания.

Причина 3: Расчет цены и суммы позиции со скидками

В ФФД 1.2 проверка кода маркировки тесно связана с финансовыми показателями позиции. Если вы передаете цену и количество, а итоговая сумма позиции в драйвере не совпадает с результатом арифметического умножения (из-за округления скидок), драйвер может заблокировать операцию.

Рассмотрим правильный алгоритм регистрации позиции для Штрих-М под ФФД 1.2:

  1. Устанавливаем тип чека (приход, возврат).
  2. Передаем код маркировки в свойство BarCode.
  3. Устанавливаем ItemStatus (для продажи — 1, для возврата — 3).
  4. Вызываем FNCheckItemBarcode() для проверки марки в ФН.
  5. Обязательно вызываем FNAcceptMarkingCode() для подтверждения реализации.
  6. Только после этого заполняем данные о цене, количестве, НДС и вызываем FNSendItemBarcode() или Registration().

Посмотрим на пример корректной реализации регистрации позиции:


Объект.BarCode = ТекущийКодМаркировки;
Объект.ItemStatus = 1; // Продажа
Объект.CheckItemMode = 0; // Проверка через ФН
Объект.FNCheckItemBarcode(); // Запрос на проверку

// Здесь можно добавить небольшую паузу или проверку ResultCode
// После успешной проверки подтверждаем
Объект.FNAcceptMarkingCode(); 

// Теперь регистрируем саму продажу
Объект.Quantity = Колво;
Объект.Price = Окр(СуммаПозиции / Колво, 2);
Объект.Summ = СуммаПозиции;
Объект.Tax1 = 0; // Без НДС
Объект.PaymentItemSign = 1; // Товар
Объект.PaymentTypeSign = 4; // Полный расчет
Объект.FNSendItemBarcode(); // Финализируем регистрацию позиции

Проверка настроек оборудования

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

Резюме и выводы

Подводя итог, можно сказать, что ошибка «Некорректная операция, внутренняя ошибка ПО» — это чаще всего признак того, что касса получила команду, которую не ожидала в текущем статусе чека.

Для решения проблемы выполним следующие шаги: во-первых, уберем все лишние методы PrintString внутри цикла обработки товаров; во-вторых, откажемся от ручного формирования строки DataMatrix в пользу прямого чтения данных со сканера в режиме COM-порта; в-третьих, проверим, что цена и сумма позиции передаются в драйвер с учетом всех скидок и не вызывают математических противоречий.

Соблюдение этих правил обеспечит стабильную работу касс Штрих-М с маркированными товарами на любом объекте, независимо от модели используемого сканера.

← На главную