При работе с маркированной продукцией в программе «1С:Управление торговлей 11» (особенно в релизах ветки 11.4) пользователи часто сталкиваются с неприятной ситуацией. При сканировании кода DataMatrix в документах «Приобретение товаров и услуг» или «Перемещение товаров» система выдает критическую ошибку: «Текст XML содержит недопустимый символ в позиции 31» (номер позиции может варьироваться). При этом в рабочем месте кассира (РМК) те же самые марки сканируются без проблем. В данной статье мы подробно разберем, почему это происходит и как программно устранить эту проблему.
Давайте проанализируем структуру кода маркировки. Согласно стандартам GS1, в коде DataMatrix используются специальные управляющие символы-разделители. Чаще всего это символ GS (Group Separator), имеющий ASCII-код 29. Он необходим для того, чтобы алгоритмы расшифровки понимали, где заканчивается одна группа данных (например, серийный номер) и начинается другая (например, код проверки).
Проблема заключается в механизме передачи данных между клиентом и сервером в 1С. Когда вы сканируете марку, драйвер сканера передает строку на клиентскую сторону. Затем программа пытается передать эту строку на сервер для обработки (поиска номенклатуры, проверки статуса ИС МП и т.д.). Для этого используется технология XDTO, которая упаковывает данные в XML. Однако стандарт XML 1.0 официально запрещает использование управляющих символов с кодами ниже 32 (за исключением нескольких исключений, таких как перевод строки). Как только символ GS (код 29) попадает в поток сериализации, XML-парсер «вылетает» с ошибкой недопустимого символа.
Рассмотрим ситуацию, почему в одних формах все работает, а в других — нет. В современных типовых конфигурациях механизмы работы с торговым оборудованием реализованы по-разному. В коде РМК часто применяется более «продвинутая» логика: данные со сканера либо сразу преобразуются в структуру, где спецсимволы уже обработаны, либо кодируются в формат Base64 до момента передачи на сервер. В стандартных документах закупки или перемещения в старых релизах УТ 11 может использоваться упрощенный вызов серверных процедур, который отправляет «сырую» строку, что и приводит к ошибке.
Самый быстрый способ решить проблему без кардинальной переработки конфигурации — это заменить «опасный» символ на безопасную последовательность перед тем, как данные уйдут на сервер. Проанализируем, как это реализовано в общих модулях 1С. Мы можем использовать встроенные функции для получения разделителя и его замены.
В модуле формы документа (например, ПТиУ) в процедуре ВнешнееСобытие или в обработчике оповещения, где вызывается ОбработатьШтрихкоды, необходимо добавить очистку строки. Пример кода для реализации в расширении или патче:
// Заменяем спец.символы, которые нельзя передать на сервер напрямую в XML
РазделительGS1 = МенеджерОборудованияМаркировкаКлиентСервер.РазделительGS1();
ЭкранированныйСимволGS1 = МенеджерОборудованияМаркировкаКлиентСервер.ЭкранированныйСимволGS1();
// Предположим, Данные - это строка, полученная от сканера
ОчищенныеДанные = СтрЗаменить(Данные, РазделительGS1, ЭкранированныйСимволGS1);
После такой замены строка становится валидной для XML-сериализатора. На стороне сервера встроенные механизмы 1С обычно умеют делать обратное преобразование или корректно распознают экранированный символ при парсинге марки.
Более надежный и современный способ передачи бинарных или содержащих спецсимволы данных — кодирование в Base64. Рассмотрим, как программно проверить и перекодировать штрихкод. Для этого можно воспользоваться методами общего модуля ШтрихкодированиеИСКлиентСервер.
Проанализируем фрагмент кода, который проверяет формат данных и выполняет преобразование:
Если Не ДанныеШтрихкода.Свойство("ФорматBase64")
Или (ДанныеШтрихкода.Свойство("ФорматBase64") И ДанныеШтрихкода.ФорматBase64 = Ложь) Тогда
// Выполняем кодирование строки штрихкода в Base64
ДанныеШтрихкода.Штрихкод = ШтрихкодВBase64(ДанныеШтрихкода.Штрихкод);
ДанныеШтрихкода.Вставить("ФорматBase64", Истина);
КонецЕсли;
Важный момент: Чтобы этот способ заработал, серверная процедура ОбработатьШтрихкодыСервер должна «ожидать» данные в таком формате. Если конфигурация слишком старая, может потребоваться доработка и серверной части, чтобы она выполняла Base64Значение() перед началом разбора кода маркировки.
Иногда проблему можно решить на уровне настроек без изменения кода. Рассмотрим параметры драйвера «1С:Сканеры штрихкода (NativeApi)»:
Внимание: Этот метод сработает только в том случае, если используемая версия конфигурации УТ 11 поддерживает обработку Base64 во всех документах. Если после переключения сканер перестал реагировать или марки перестали подбираться, значит, логика конфигурации не готова к автоматическому декодированию Base64, и придется возвращаться к программному методу из Решения 1.
Если программные методы не помогают, проанализируем физический режим работы устройства. Сканеры могут работать в двух основных режимах:
GS часто просто теряется или заменяется драйвером ОС на неожидаемые комбинации клавиш.Для сканера Zebra DS2208 мы рекомендуем перевести устройство в режим USB CDC Host. После этого в системе появится виртуальный COM-порт, который нужно выбрать в настройках 1С. Это обеспечит наиболее стабильную передачу управляющих символов DataMatrix без их искажения.
Ошибка с недопустимым символом в XML — это классический конфликт между старыми стандартами обмена данными и новыми требованиями к маркировке товаров. Для исправления ситуации в УТ 11.4 оптимальным является использование расширения, которое перехватывает событие сканирования и очищает строку от символа ASCII 29 перед вызовом серверных функций. Также не забывайте обновлять версию платформы 1С до актуальной (например, 8.3.21 и выше), так как в свежих релизах механизмы работы XDTO со спецсимволами постоянно совершенствуются.