При работе с интеграциями и обмене данными через формат 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.ФизЛицо вы увидите не строку, а ссылку. Если такого объекта нет в базе, вы увидите надпись "Объект не найден", но это все равно будет объект типа Ссылка, а не Строка.
Поскольку фабрика уже сделала за нас работу по преобразованию данных в ссылку, самый правильный и логичный способ получить ГУИД — это воспользоваться методами самой ссылки. Рассмотрим, как это сделать программно:
УникальныйИдентификатор().Посмотрим на пример реализации:
// Получаем ссылку из объекта XDTO
СсылкаНаОбъект = ОбъектXDTO.ФизЛицо;
// Проверяем, что это действительно ссылка, и извлекаем ГУИД
Если ТипЗнч(СсылкаНаОбъект) = Тип("СправочникСсылка.ФизическиеЛица") Тогда
НужныйГуд = СсылкаНаОбъект.УникальныйИдентификатор();
Сообщить("Получен ГУИД: " + Строка(НужныйГуд));
КонецЕсли;
Важный нюанс: метод УникальныйИдентификатор() возвращает объект типа УникальныйИдентификатор. Если вам нужна именно строка для дальнейшей записи в текстовый файл или лог, используйте функцию Строка() или XMLСтрока().
Существует еще более универсальный и быстрый способ получить строковое представление идентификатора из ссылки, полученной через XDTO. Функция XMLСтрока() работает крайне эффективно, так как она предназначена именно для преобразования объектов 1С в их каноническое строковое представление в XML.
Проанализируем ситуацию: даже если ссылка является «битой» (объект удален или еще не создан), 1С все равно хранит внутри ссылки её ГУИД. Рассмотрим код:
// Прямое получение строкового ГУИДа из ссылки XDTO
ТекстовыйGUID = XMLСтрока(ОбъектXDTO.ФизЛицо);
// Результат будет: "4ffc7e92-67ad-12e8-8caa-88d7f67f550c"
Этот метод хорош тем, что он не требует обращения к базе данных для проверки существования объекта. Мы работаем только с метаданными самой ссылки, что значительно ускоряет разбор больших XML-файлов.
Если ваша задача — получить именно строку и вы не хотите, чтобы фабрика тратила ресурсы на создание объектов СправочникСсылка, можно изменить подход на уровне определения схемы. Рассмотрим два варианта:
xs:string вместо ссылочного типа 1С. В этом случае фабрика прочитает значение «как есть».ЧтениеXML.Значение, не прибегая к методу ФабрикаXDTO.ПрочитатьXML() для этого фрагмента.Однако чаще всего автоматическая типизация — это преимущество, а не проблема, если знать, как с ней работать.
Выясним причину, по которой иногда удобнее использовать другой инструмент. В 1С есть два похожих, но разных механизма:
ФабрикаXDTO — это низкоуровневый инструмент. Она работает с ОбъектXDTO. Когда вы читаете данные через фабрику, вы получаете промежуточный объект, свойства которого могут быть как простыми значениями, так и ссылками (если указан xsi:type).
СериализаторXDTO — это высокоуровневая обертка. Она предназначена для того, чтобы сразу превращать XML в объекты 1С (ДокументОбъект, СправочникОбъект, Ссылка). Если вы используете СериализаторXDTO.ПрочитатьXML(), вы получите готовую ссылку на справочник в один шаг.
Посмотрим на пример с сериализатором:
// Использование сериализатора для прямого получения ссылки
Ссылка = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Идентификатор = Ссылка.УникальныйИдентификатор();
Часто возникает вопрос: «Что будет, если в XML пришел ГУИД, которого нет в моей базе?». Это критически важный момент для понимания работы ссылочных типов.
Когда ФабрикаXDTO видит тип CatalogRef, она создает объект ссылки в оперативной памяти. Этот объект содержит внутри себя переданный ГУИД. Для 1С не имеет значения, существует ли запись в таблице базы данных в данный момент. Ссылка — это просто адрес. Вы можете спокойно получить этот адрес (ГУИД) методами, описанными выше, даже если при попытке открыть эту ссылку в интерфейсе вы увидите «Объект не найден».
Подводя итог, можно выделить следующие ключевые правила работы с ГУИДами в XDTO:
УникальныйИдентификатор() — самый надежный способ извлечь данные из ссылки.XMLСтрока() является наиболее предпочтительной.xsi:type в исходном XML или настройки вашего XDTO-пакета.Применяя эти знания, вы сможете эффективно обрабатывать любые данные, поступающие в систему через XML, сохраняя целостность идентификаторов и обеспечивая высокую скорость работы ваших интеграционных решений.