В процессе разработки и сопровождения систем на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда при попытке открыть форму документа (например, ВходящееПисьмо) система выдает критическую ошибку: «Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа. Ошибка преобразования данных XDTO». При этом в тексте ошибки фигурирует загадочное свойство v и указание на недопустимый символ XML.
В этой статье мы подробно разберем, почему это происходит, как найти «битые» данные и как предотвратить подобные инциденты в будущем. Проанализируем техническую сторону вопроса и рассмотрим конкретные программные способы решения.
Для начала проанализируем саму структуру ошибки. Когда мы работаем в Тонком клиенте или Веб-клиенте, платформа 1С использует механизм XDTO (XML Data Transfer Objects) для передачи данных формы между сервером и клиентом. Весь контент реквизитов формы упаковывается в XML-пакет.
Свойство v в данном контексте расшифровывается как Value (Значение). Это стандартное имя тега в пакете {http://v8.1c.ru/8.2/uobjects}, в который помещается содержимое строковых и других простых типов данных. Если в строковом реквизите (например, в теме письма или имени вложения) содержится символ, который запрещен стандартом XML 1.0, сериализатор XDTO не может корректно сформировать пакет и «вылетает» с ошибкой еще на этапе подготовки данных на сервере.
Важный нюанс: в Толстом клиенте (особенно в обычном приложении) эта ошибка может не проявляться, так как передача данных часто идет напрямую через память, минуя строгую XML-сериализацию. Это часто сбивает с толку разработчиков, так как «под администратором в толстом клиенте всё открывается».
Согласно спецификации XML 1.0, в текстовых узлах разрешены только определенные диапазоны символов. Все управляющие символы ASCII с кодами от 0 до 31 (за исключением табуляции, перевода строки и возврата каретки) являются нелегальными.
Рассмотрим список «запрещенных» кодов:
Чаще всего такие символы попадают в базу при копировании текста из внешних источников (Word, PDF, веб-страницы) или при автоматической загрузке данных из внешних систем, например, при получении почты с некорректными заголовками или именами файлов.
Если форма не открывается, нам нужно выяснить, в каком именно поле сидит «нелегал». Рассмотрим пошагово, как это сделать:
Шаг 1. Использование консоли запросов.
Попробуем выбрать данные проблемного объекта через консоль запросов, запущенную в Тонком клиенте. Если при выполнении запроса или при попытке просмотреть результат в таблице консоль выдает ту же самую ошибку XDTO, значит, мы на верном пути. Путем исключения полей в запросе можно найти конкретный реквизит (например, Наименование, Комментарий или ИмяФайла), содержащий спецсимвол.
Шаг 2. Поиск позиции символа.
В тексте ошибки обычно указывается позиция символа. Однако помните, что это позиция в XML-пакете, а не в строке базы данных. Тем не менее, по контексту (как в примере: _7_1@065_851...) можно визуально определить, на какую строку это похоже.
Шаг 3. Анализ через HEX-редактор.
Если визуально строка выглядит нормально, скопируйте её содержимое (если удастся извлечь через толстый клиент или обработку) в любой HEX-редактор. Ищите байты с кодами меньше 20 (в шестнадцатеричной системе), которые не являются 09, 0A или 0D.
Чтобы проблема не повторялась, необходимо «дезинфицировать» входящие данные перед их записью в базу данных. Разберем основные инструменты, которые нам предоставляет платформа и типовые конфигурации.
В современных версиях платформы (8.3.20+) появился мощный механизм для работы с такими строками. Мы можем использовать функцию НайтиНедопустимыеСимволыXML(). Рассмотрим пример кода:
ПроблемнаяСтрока = Объект.Наименование;
Позиция = НайтиНедопустимыеСимволыXML(ПроблемнаяСтрока);
Если Позиция > 0 Тогда
Сообщить("Найден запрещенный символ в позиции: " + Позиция);
// Здесь можно применить очистку
КонецЕсли;
Если ваша конфигурация построена на базе Библиотеки стандартных подсистем (БСП), вам не нужно изобретать велосипед. В составе БСП есть готовый метод в общем модуле ОбщегоНазначенияКлиентСервер. Проанализируем его использование:
// Очистка строки от символов, которые не поддерживает XML
ЧистаяСтрока = ОбщегоНазначенияКлиентСервер.УдалитьНедопустимыеСимволыXML(ВходящаяСтрока);
Объект.Наименование = ЧистаяСтрока;
Этот метод рекомендуется вызывать в обработчике ПередЗаписью или непосредственно в логике загрузки данных (например, при парсинге почты или чтении из внешнего API).
Если вы работаете на старой платформе или без БСП, можно реализовать собственную функцию очистки. Выясним, как это сделать с помощью регулярных выражений через COM-объект VBScript.RegExp:
Функция ОчиститьСтрокуДляXML(Знач ВходящаяСтрока) Экспорт
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.MultiLine = Истина;
RegExp.Global = Истина;
RegExp.IgnoreCase = Истина;
// Маска исключает все символы, кроме разрешенных в XML 1.0
RegExp.Pattern = "[^\x09\x0A\x0D\x20-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]";
Возврат RegExp.Replace(ВходящаяСтрока, "");
КонецФункции
Мы выяснили, что ошибка XDTO при открытии формы — это почти всегда следствие «грязных» данных. Алгоритм наших действий при возникновении такой ситуации:
УдалитьНедопустимыеСимволыXML, чтобы исключить повторение ситуации.Особое внимание следует уделять загрузке вложений из электронной почты. Как показывает практика, именно некорректные имена файлов вложений чаще всего становятся причиной блокировки работы пользователей с документами ВходящееПисьмо.