Переход на формат фискальных данных (ФФД) 1.2 принес множество изменений в протоколы обмена с контрольно-кассовой техникой (ККТ). Одной из наиболее частых проблем, с которой сталкиваются разработчики на платформе 1С:Предприятие 7.7 при работе с драйверами Штрих-М, является ошибка при передаче данных покупателя (наименование и ИНН). В старых форматах (ФФД 1.05) эти данные передавались как независимые теги, но в ФФД 1.2 правила игры изменились.
В этой статье мы подробно разберем, почему возникают ошибки 94 и 51, как правильно использовать составные теги и приведем готовый рабочий код для интеграции.
Ранее для передачи наименования покупателя (тег 1227) и ИНН (тег 1228) использовался метод FNSendTag или FNSendTagOperation. Прошивки ККТ под ФФД 1.2 строго следуют новым спецификациям, согласно которым эти реквизиты теперь являются частью составного тега 1256 (Данные покупателя). Попытка отправить их «по отдельности» приводит к тому, что ККТ возвращает ошибку «94: Некорректная операция» или просто игнорирует данные.
Проанализируем ситуацию: составной тег — это своего рода «контейнер» (STLV-структура), который сначала открывается в памяти драйвера, наполняется вложенными тегами, а затем отправляется в ККТ одной командой. Разберем по шагам, как реализовать этот механизм.
Для корректной передачи данных нам необходимо использовать специализированные методы драйвера DrvFR.dll: FNBeginSTLVTag, FNAddTag и FNSendSTLVTag. Рассмотрим последовательность действий:
FNOpenCheck.1256.1227 с названием клиента.1228 с ИНН клиента.1254 (адрес покупателя).Ниже приведен пример кода, адаптированный для использования в глобальном модуле или обработке обслуживания ККТ. Мы используем объект драйвера AddIn.DrvFR.
// Создаем объект драйвера, если он еще не создан
Если ПустоеЗначение(ЭККА) = 1 Тогда
ЭККА = СоздатьОбъект("AddIn.DrvFR");
КонецЕсли;
// Устанавливаем пароль администратора/кассира
ЭККА.Password = ПарольККТ;
// 1. Начинаем формирование составного тега 1256 (Данные покупателя)
ЭККА.TagNumber = 1256;
TagID = ЭККА.FNBeginSTLVTag(); // Метод возвращает уникальный идентификатор контейнера
// 2. Добавляем Наименование покупателя (Тег 1227)
Если СокрЛП(Клиент.ПолноеНаименование) <> "" Тогда
ЭККА.TagID = TagID;
ЭККА.TagNumber = 1227;
ЭККА.TagType = 7; // Тип тега: Строка
ЭККА.TagValueStr = СокрЛП(Клиент.ПолноеНаименование);
ЭККА.FNAddTag(); // Добавляем тег во временный буфер STLV
КонецЕсли;
// 3. Добавляем ИНН покупателя (Тег 1228)
Если СокрЛП(Клиент.ИНН) <> "" Тогда
ЭККА.TagID = TagID;
ЭККА.TagNumber = 1228;
ЭККА.TagType = 7; // В ФФД 1.2 ИНН также передается как строка
ЭККА.TagValueStr = СокрЛП(Клиент.ИНН);
ЭККА.FNAddTag();
КонецЕсли;
// 4. Отправляем сформированный составной тег в ККТ
// Важно: вызывается ОДИН РАЗ после добавления всех вложенных тегов
ЭККА.FNSendSTLVTag();
// Проверка на ошибки
Если ЭККА.ResultCode <> 0 Тогда
Сообщить("Ошибка передачи данных покупателя: " + ЭККА.ResultCodeDescription, "!");
КонецЕсли;
Многие пользователи замечают, что даже после успешной передачи тегов в ОФД, данные покупателя не появляются на бумажном чеке. Выясним причину: в ФФД 1.2 печать реквизитов покупателя на бумаге не является строго обязательной для всех типов расчетов, и в прошивках Штрих-М за это отвечают настройки таблиц (обычно Таблица 17, поле «Печать реквизитов покупателя»).
Если вы хотите гарантированно видеть эти данные на чеке, рекомендуется выводить их текстовыми строками вручную сразу после отправки тегов:
ЭККА.StringForPrinting = "Покупатель: " + СокрЛП(Клиент.ПолноеНаименование);
ЭККА.PrintString();
Если СокрЛП(Клиент.ИНН) <> "" Тогда
ЭККА.StringForPrinting = "ИНН: " + СокрЛП(Клиент.ИНН);
ЭККА.PrintString();
КонецЕсли;
Если при выполнении приведенного выше кода вы получаете ошибку 51 (Некорректные параметры в команде), следует обратить внимание на следующие моменты:
1228 строго валидируется. Для юридических лиц это должно быть ровно 10 цифр, для ИП — 12 цифр. Если в строке окажутся пробелы или лишние символы, драйвер вернет ошибку 51. Используйте СокрЛП() и проверку длины строки.FNAddTag, если значение пустое. Драйвер может не принять пустой вложенный тег внутри STLV-контейнера.DrvFR.dll до версии 5.17 или выше. В версиях 4.x поддержка STLV-тегов реализована не полностью.FNOpenCheck. Вне открытого чека регистрация данных покупателя для конкретной продажи невозможна.Для понимания логики полезно посмотреть, как эта же задача решается в современных конфигурациях на платформе 8.3. Там часто используется Таблица Значений для накопления вложенных тегов перед циклической обработкой. Рассмотрим этот принцип, чтобы лучше понять структуру данных:
// Пример логики для понимания структуры (8.3)
НомерСоставногоТега = 1256;
Объект.TagNumber = НомерСоставногоТега;
ИдКонтейнера = Объект.FNBeginSTLVTag();
Для Каждого СтрокаТега Из ТаблицаВнутреннихТегов Цикл
Объект.TagID = ИдКонтейнера;
Объект.TagNumber = СтрокаТега.Номер;
Объект.TagType = СтрокаТега.Тип;
Объект.TagValueStr = СтрокаТега.Значение;
Объект.FNAddTag();
КонецЦикла;
Объект.FNSendSTLVTag();
Как мы видим, принцип идентичен: создание контейнера -> наполнение -> отправка. В 1С 7.7 мы просто делаем это последовательно без использования таблиц значений, что вполне оправдано для линейного кода формирования чека.
Резюме: Основной секрет успеха при работе с ФФД 1.2 и Штрих-М в среде 1С 7.7 — это отказ от старых методов записи тегов в пользу механизмов STLV. Правильное использование FNBeginSTLVTag и FNSendSTLVTag позволяет полностью исключить ошибки протокола и обеспечить корректную передачу данных в налоговую службу через ОФД. Для быстрой проверки связи с кассой и ОФД при отладке можно воспользоваться программой для тестирования ККМ Штрих и Атол.