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

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

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

Суть проблемы: невидимый символ GS

Коды маркировки в формате DataMatrix используют стандарт GS1. Для разделения полей переменной длины в таких кодах используется специальный управляющий символ — Group Separator (GS). Его код в таблице ASCII равен 29.

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

Почему удаление символа — это плохая идея?

Иногда возникает искушение просто удалить этот символ из строки, например, с помощью функции СтрЗаменить(КИЗ, Символ(29), ""). Однако делать это категорически не рекомендуется. Символ GS1 является структурным разделителем данных. Если его удалить, структура кода маркировки нарушится, и при попытке проверки кода через API системы «Честный ЗНАК» или при передаче в другие государственные системы он будет признан невалидным.

Правильное решение: экранирование спецсимволов

Чтобы избежать ошибки парсинга XML и при этом сохранить целостность кода маркировки, необходимо выполнить экранирование. Вместо прямого использования символа ASCII 29 мы заменяем его на экранированную последовательность \x1d.

Рассмотрим, как это реализовать на практике с использованием стандартных механизмов платформы.

Использование Менеджера оборудования

В актуальных конфигурациях 1С для работы с торговым оборудованием предусмотрен специальный объект МенеджерОборудованияКлиентСервер. В нем уже заложены функции для работы с разделителями. Разберем пошагово, как внедрить это в ваш код:

  1. Определим разделитель и его экранированный аналог.
  2. Перед добавлением строки в табличную часть документа произведем замену в строке сканированного кода.

Вот пример кода, который позволит безопасно подготовить строку перед вставкой в ТабличнуюЧасть:


// Получаем строку из сканера
СканДанные = ТекШтрихкод.СканированныйШтрихкод;

// Используем методы Менеджера оборудования для замены
ЭкранированнаяСтрока = СтрЗаменить(
    СканДанные, 
    МенеджерОборудованияКлиентСервер.РазделительGS1(), 
    МенеджерОборудованияКлиентСервер.ЭкранированныйСимволGS1()
);

// Добавляем строку в табличную часть
НоваяСтрока = Объект.Запасы.Добавить();
НоваяСтрока.КИЗ = ЭкранированнаяСтрока;

Почему это работает?

Когда вы заменяете символ GS на строку \x1d, вы превращаете "опасный" непечатный символ в текстовую последовательность, которая является абсолютно безопасной для любого XML-сериализатора. Платформа 1С при сохранении объекта на сервер видит обычный текст и не пытается интерпретировать его как управляющую команду.

Важно помнить, что символ GS1 может встречаться в коде маркировки несколько раз. Например, если в коде зашифрованы идентификаторы GTIN, серийный номер и срок годности, разделители будут стоять между каждым из этих блоков. Метод СтрЗаменить обрабатывает все вхождения символа в строке, поэтому ваше решение будет работать для любых типов кодов маркировки, корректно экранируя все необходимые позиции.

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

Мы рекомендуем придерживаться следующих правил при работе с маркировкой:

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

← На главную