Как сохранить и получить ГУИД (GUID) при разборе XML через XDTO в 1С

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

При работе с интеграциями и обмене данными через формат XML программисты 1С часто сталкиваются с особенностью работы механизма XDTO. Когда мы считываем данные, содержащие ссылки на объекты (например, справочники или документы), 1С проявляет «интеллект» и автоматически преобразует строковое представление ГУИДа в объект соответствующей ссылки. Это часто сбивает с толку новичков, которые ожидают увидеть в отладчике простую строку, а находят объект типа СправочникСсылка. В этой статье мы подробно разберем, почему это происходит и как правильно извлечь Уникальный идентификатор (GUID) в таких ситуациях.

Разберем причину: почему пропадает строка и появляется ссылка

Рассмотрим механизм работы ФабрикаXDTO. Когда выполняется метод ПрочитатьXML(), система анализирует атрибуты узлов. Если в XML-файле у значения указан атрибут xsi:type (например, xsi:type="d3p1:CatalogRef.ФизическиеЛица"), фабрика обращается к своей схеме типов. Понимая, что данный тип соответствует ссылочному типу 1С, она автоматически инициирует десериализацию.

Проанализируем фрагмент кода, который обычно вызывает вопросы:


ЧтениеXML = Новый ЧтениеXML;    
ЧтениеXML.УстановитьСтроку(ДанныеСтр);
Имя = ЧтениеXML.Имя;
// Фабрика считывает данные и сразу типизирует их
ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML, ФабрикаXDTO.Тип(ЧтениеXML.URIПространстваИмен, Имя));

В этот момент значение 4ffc7e92-67ad-12e8-8caa-88d7f67f550c, которое в файле выглядит как текст, превращается в полноценный объект 1С. В отладчике в свойстве ОбъектXDTO.ФизЛицо вы увидите не строку, а ссылку. Если такого объекта нет в базе, вы увидите надпись "Объект не найден", но это все равно будет объект типа Ссылка, а не Строка.

Решение 1: Получение идентификатора через метод УникальныйИдентификатор()

Поскольку фабрика уже сделала за нас работу по преобразованию данных в ссылку, самый правильный и логичный способ получить ГУИД — это воспользоваться методами самой ссылки. Рассмотрим, как это сделать программно:

  1. Сначала мы получаем объект из XDTO.
  2. Проверяем, является ли полученное значение ссылкой.
  3. Вызываем метод УникальныйИдентификатор().

Посмотрим на пример реализации:


// Получаем ссылку из объекта XDTO
СсылкаНаОбъект = ОбъектXDTO.ФизЛицо;

// Проверяем, что это действительно ссылка, и извлекаем ГУИД
Если ТипЗнч(СсылкаНаОбъект) = Тип("СправочникСсылка.ФизическиеЛица") Тогда
    НужныйГуд = СсылкаНаОбъект.УникальныйИдентификатор();
    Сообщить("Получен ГУИД: " + Строка(НужныйГуд));
КонецЕсли;

Важный нюанс: метод УникальныйИдентификатор() возвращает объект типа УникальныйИдентификатор. Если вам нужна именно строка для дальнейшей записи в текстовый файл или лог, используйте функцию Строка() или XMLСтрока().

Решение 2: Использование функции XMLСтрока() для быстрого извлечения

Существует еще более универсальный и быстрый способ получить строковое представление идентификатора из ссылки, полученной через XDTO. Функция XMLСтрока() работает крайне эффективно, так как она предназначена именно для преобразования объектов 1С в их каноническое строковое представление в XML.

Проанализируем ситуацию: даже если ссылка является «битой» (объект удален или еще не создан), 1С все равно хранит внутри ссылки её ГУИД. Рассмотрим код:


// Прямое получение строкового ГУИДа из ссылки XDTO
ТекстовыйGUID = XMLСтрока(ОбъектXDTO.ФизЛицо);
// Результат будет: "4ffc7e92-67ad-12e8-8caa-88d7f67f550c"

Этот метод хорош тем, что он не требует обращения к базе данных для проверки существования объекта. Мы работаем только с метаданными самой ссылки, что значительно ускоряет разбор больших XML-файлов.

Решение 3: Изменение схемы XDTO (предотвращение типизации)

Если ваша задача — получить именно строку и вы не хотите, чтобы фабрика тратила ресурсы на создание объектов СправочникСсылка, можно изменить подход на уровне определения схемы. Рассмотрим два варианта:

  1. Изменение XSD-пакета: Если вы сами контролируете схему, укажите для данного поля тип xs:string вместо ссылочного типа 1С. В этом случае фабрика прочитает значение «как есть».
  2. Чтение через ЧтениеXML напрямую: Если типизация XDTO вам мешает, вы можете разобрать конкретный узел вручную, используя ЧтениеXML.Значение, не прибегая к методу ФабрикаXDTO.ПрочитатьXML() для этого фрагмента.

Однако чаще всего автоматическая типизация — это преимущество, а не проблема, если знать, как с ней работать.

Разберем отличия: ФабрикаXDTO против СериализатораXDTO

Выясним причину, по которой иногда удобнее использовать другой инструмент. В 1С есть два похожих, но разных механизма:

ФабрикаXDTO — это низкоуровневый инструмент. Она работает с ОбъектXDTO. Когда вы читаете данные через фабрику, вы получаете промежуточный объект, свойства которого могут быть как простыми значениями, так и ссылками (если указан xsi:type).

СериализаторXDTO — это высокоуровневая обертка. Она предназначена для того, чтобы сразу превращать XML в объекты 1С (ДокументОбъект, СправочникОбъект, Ссылка). Если вы используете СериализаторXDTO.ПрочитатьXML(), вы получите готовую ссылку на справочник в один шаг.

Посмотрим на пример с сериализатором:


// Использование сериализатора для прямого получения ссылки
Ссылка = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Идентификатор = Ссылка.УникальныйИдентификатор();

Проанализируем ситуацию с «битыми» ссылками

Часто возникает вопрос: «Что будет, если в XML пришел ГУИД, которого нет в моей базе?». Это критически важный момент для понимания работы ссылочных типов.

Когда ФабрикаXDTO видит тип CatalogRef, она создает объект ссылки в оперативной памяти. Этот объект содержит внутри себя переданный ГУИД. Для 1С не имеет значения, существует ли запись в таблице базы данных в данный момент. Ссылка — это просто адрес. Вы можете спокойно получить этот адрес (ГУИД) методами, описанными выше, даже если при попытке открыть эту ссылку в интерфейсе вы увидите «Объект не найден».

Итоги и рекомендации

Подводя итог, можно выделить следующие ключевые правила работы с ГУИДами в XDTO:

Применяя эти знания, вы сможете эффективно обрабатывать любые данные, поступающие в систему через XML, сохраняя целостность идентификаторов и обеспечивая высокую скорость работы ваших интеграционных решений.

← На главную