При внедрении разрешительного режима для 1С 8 или настройке взаимодействия с системой для 1С 7.7 многие сталкиваются с ситуацией: коды маркировки с бутылок проверяются в системе "Честный ЗНАК" без проблем, а при сканировании кега и отправке запроса возвращается ошибка "cannot find code in db". При этом попытка вручную обрезать "длинный хвост" кода приводит к ошибке парсинга. Разберем, почему так происходит и как это исправить.
Проблема кроется не в том, что кода нет в базе данных, а в том, как ваша учетная система, например, 1С, обрабатывает и передает этот код в "Честный ЗНАК". Если вам нужно проверить статус конкретного кода вручную, можно использовать обработку для запроса информации кодов Честного знака, чтобы убедиться в их корректности.
Код Data Matrix, нанесенный на кег, — это не просто набор букв и цифр. Это структурированная строка, в которой разные блоки данных (идентификаторы применения или AI) отделены друг от друга специальным непечатаемым символом — разделителем групп GS1. В 1С этот символ можно получить с помощью функции Симв(29).
Когда 2D-сканер считывает код, он передает в систему всю строку целиком, включая эти невидимые разделители. Если на каком-то этапе (при передаче данных от сканера, при сохранении в 1С или при формировании JSON-запроса) этот символ теряется или искажается, структура кода нарушается. Система "Честный ЗНАК" получает "слипшуюся" строку, не может разобрать ее на составные части (GTIN, серийный номер, крипточасть) и, как следствие, не может найти такой код в своей базе данных, возвращая ошибку "cannot find code".
Проанализируем пример ответа от "Честного ЗНАКа", который получил автор вопроса:
{"code":0,"description":"ok","codes":[{"cis":"0104607026590735215BI.pcO93XOOX\u001D3350000030","valid":true, ..., "message":"cannot find code [0104607026590735215BI.pcO93XOOX\u001D3350000030] in db","found":false, ...}],"reqId":"..."}
Ключевой момент здесь — последовательность \u001D. Это и есть экранированное представление символа GS1 для формата JSON. Проблема автора заключалась в том, что в его коде такой разделитель отсутствовал в нужном месте (например, перед идентификатором 93, обозначающим код проверки), из-за чего вся структура "ломалась".
Решение заключается в том, чтобы обеспечить корректную обработку кода маркировки на всех этапах: от сканирования до отправки запроса в API.
Симв(29).
Симв(29)) должен быть преобразован в \u001d.
Рассмотрим полезный пример кода, который иллюстрирует правильный подход к обработке строки с кодом маркировки. Хотя синтаксис может быть немного устаревшим ("клюшки"), принцип остается абсолютно актуальным и для современных конфигураций на управляемых формах. Подобная логика работы с API востребована и в других категориях, например, когда реализуется проверка кода маркировки шин для разрешительного режима.
Шаг 1. Сохранение кода после сканирования.
После получения строки со сканера заменяем невидимый разделитель на текстовый заменитель. Это делает строку безопасной для хранения в базе данных и для отображения в интерфейсе.
// СтрМарки - это строка, полученная от сканера
СтрМарки = СтрЗаменить(СтрМарки, Симв(29), "<GS1>");
// Теперь в переменной СтрМарки вместо невидимого символа будет текстовая вставка ""
Шаг 2. Подготовка кода для отправки в API.
Когда нам нужно отправить запрос, мы выполняем обратную операцию, а затем экранируем все специальные символы для JSON.
// ПолнМарка - это строка, которую мы достали из базы данных (с заменителем )
// Возвращаем обратно символ-разделитель
ТекМарка = СокрЛП(СтрЗаменить(ПолнМарка, "<GS1>", Симв(29)));
// Далее ТекМарка используется для формирования тела JSON-запроса.
// Предположим, что переменная "Результат" содержит строку, которая станет частью JSON.
// Экранируем специальные символы.
Результат = СтрЗаменить(Результат, "\", "\\"); // Сначала экранируем сам обратный слэш
Результат = СтрЗаменить(Результат, "/", "\/");
Результат = СтрЗаменить(Результат, """", "\""");
Результат = СтрЗаменить(Результат, Симв(13), "\r"); // Возврат каретки
Результат = СтрЗаменить(Результат, СимволТабуляции,"\t"); // Табуляция
Результат = СтрЗаменить(Результат, Симв(8), "\b"); // Backspace
Результат = СтрЗаменить(Результат, Симв(10), "\n"); // Перевод строки
Результат = СтрЗаменить(Результат, Симв(12), "\f"); // Прогон страницы
// И самое главное для нашей задачи:
Результат = СтрЗаменить(Результат, Симв(29), "\u001d"); // Экранируем разделитель GS1
Этот подход гарантирует, что в "Честный ЗНАК" будет отправлен валидный JSON с корректно отформатированным кодом маркировки. В крупных торговых точках, где ведется учет по нескольким организациям, также может потребоваться установка нескольких локальных модулей Честный знак на одном рабочем месте.
Важный итог: никогда не обрезайте код маркировки, полученный с кега. "Длинный хвост" содержит критически важную информацию, включая криптографическую подпись. Проблема почти всегда заключается не в длине кода, а в корректной обработке служебных символов внутри него.