Разработка и Конфигурация · 11 мин
Как в 1С получить ссылку по уникальному идентификатору (УИД)
Как в 1С получить ссылку на объект по уникальному идентификатору: ПолучитьСсылку, запросы, поиск по базе, обработка битых ссылок и типичные ошибки разработчика.
Получение ссылки на объект по уникальному идентификатору — одна из базовых задач при разработке и администрировании 1С. Она возникает при обмене данными между базами, при разборе ошибок в логах, при интеграции с внешними системами и при восстановлении «битых» ссылок. Во всех этих случаях на руках есть только строка вида «8b3f9c2e-…», а нужна полноценная ссылка на элемент справочника, документ или другой объект.
Ключевой момент, который нужно понимать сразу: уникальный идентификатор сам по себе не содержит информации о типе объекта. Один и тот же УИД может принадлежать справочнику «Номенклатура», документу «Реализация товаров» или узлу плана обмена. Поэтому корректное получение ссылки всегда включает два шага — определение типа объекта и собственно получение ссылки штатным методом.
Ниже разобраны основные способы: метод ПолучитьСсылку() менеджера объекта, универсальная функция поиска по всем типам метаданных, получение ссылки запросом, а также проверка результата и работа с битыми ссылками.
Что такое УИД и как он связан со ссылкой
Уникальный идентификатор (GUID, УИД) — это 128-битное значение, которое платформа 1С присваивает каждому объекту базы данных при его создании. Именно УИД хранится в физической таблице и однозначно определяет запись. Ссылка же — это объект встроенного языка, который содержит и идентификатор, и тип объекта.
Получить строковое представление УИД из существующей ссылки можно так:
СтрокаУИД = XMLСтрока(Ссылка.УникальныйИдентификатор());
// или проще:
СтрокаУИД = Строка(Ссылка.УникальныйИдентификатор());
Обратное преобразование строки в значение типа «УникальныйИдентификатор» выполняется конструктором:
УИД = Новый УникальныйИдентификатор("8b3f9c2e-1a4d-4e5f-9a0b-1c2d3e4f5a6b");
Обратите внимание: если строка имеет неверный формат (опечатка, лишние символы, скобки), конструктор вызовет исключение. Поэтому при обработке внешних данных преобразование стоит оборачивать в попытку.
Способ 1. Метод ПолучитьСсылку() при известном типе объекта
Если известно, к какому типу относится искомый объект, задача решается одной строкой — методом ПолучитьСсылку() менеджера соответствующего вида объектов:
УИД = Новый УникальныйИдентификатор(СтрокаУИД);
Ссылка = Справочники.Номенклатура.ПолучитьСсылку(УИД);
// для документа:
СсылкаДок = Документы.РеализацияТоваровУслуг.ПолучитьСсылку(УИД);
Метод доступен у менеджеров справочников, документов, планов видов характеристик, планов счетов, планов видов расчёта, бизнес-процессов, задач и планов обмена. Для перечислений и регистров сведений он не применяется — там другая модель адресации данных.
Важная особенность: ПолучитьСсылку() не обращается к базе данных и не проверяет, существует ли объект. Метод просто «собирает» ссылку из типа и идентификатора. Если объекта с таким УИД никогда не было или он удалён, вы получите формально корректную, но битую ссылку. Проверка существования — отдельный шаг, описанный ниже.
Способ 2. Поиск ссылки по УИД, когда тип неизвестен
На практике часто встречается ситуация: в логе обмена или в сообщении об ошибке есть только УИД, а тип объекта неизвестен. В этом случае пишут универсальную функцию, которая перебирает менеджеры метаданных и проверяет существование объекта каждого типа.
Функция НайтиСсылкуПоУИД(СтрокаУИД) Экспорт
Попытка
УИД = Новый УникальныйИдентификатор(СтрокаУИД);
Исключение
Возврат Неопределено;
КонецПопытки;
ТипыМенеджеров = Новый Массив;
ТипыМенеджеров.Добавить(Справочники);
ТипыМенеджеров.Добавить(Документы);
ТипыМенеджеров.Добавить(ПланыВидовХарактеристик);
ТипыМенеджеров.Добавить(ПланыСчетов);
ТипыМенеджеров.Добавить(ПланыВидовРасчета);
ТипыМенеджеров.Добавить(БизнесПроцессы);
ТипыМенеджеров.Добавить(Задачи);
ТипыМенеджеров.Добавить(ПланыОбмена);
Для Каждого МенеджерКоллекции Из ТипыМенеджеров Цикл
Для Каждого Менеджер Из МенеджерКоллекции Цикл
Ссылка = Менеджер.ПолучитьСсылку(УИД);
Запрос = Новый Запрос(
"ВЫБРАТЬ ПЕРВЫЕ 1 ИСТИНА ИЗ "
+ Менеджер.ПустаяСсылка().Метаданные().ПолноеИмя()
+ " ГДЕ Ссылка = &Ссылка");
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Если Не Запрос.Выполнить().Пустой() Тогда
Возврат Ссылка;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Возврат Неопределено;
КонецФункции
Такой перебор — ресурсоёмкая операция: в крупной конфигурации сотни видов объектов, и на каждый выполняется отдельный запрос. Для разового поиска это приемлемо, но в цикле обработки тысяч идентификаторов функцию использовать нельзя — там нужно заранее знать тип или сузить круг кандидатов по контексту задачи.
Способ 3. Проверка существования объекта и битые ссылки
После получения ссылки любым способом нужно убедиться, что объект реально существует. Есть три рабочих варианта проверки.
Первый — запрос по ссылке, как в примере выше. Это самый надёжный способ, он не вызывает исключений и легко встраивается в циклы.
Второй — проверка через версию данных. У несуществующего объекта свойство ВерсияДанных возвращает пустую строку:
Если ПустаяСтрока(Ссылка.ВерсияДанных) Тогда
// объект не существует — ссылка битая
КонецЕсли;
Третий вариант — попытка обращения к реквизиту. Обращение к полю битой ссылки вызывает исключение, поэтому способ используют только внутри конструкции «Попытка…Исключение». Для массовых проверок он медленнее запроса.
Как проверить результат
Запрос по ссылке вернул строку, ВерсияДанных не пустая
Запрос пуст, ВерсияДанных = пустая строка — ссылка битая
Тип соответствует ожидаемому объекту обмена
Тип другой — УИД принадлежит иному объекту, проверьте источник
ПометкаУдаления = Ложь
Объект существует, но помечен на удаление — уточните, можно ли его использовать
Способ 4. Получение ссылки запросом и в типовых механизмах
Иногда УИД хранится в базе как строка — например, в реквизите сопоставления при интеграции с сайтом или внешней системой. Тогда ссылку ищут запросом по этому реквизиту:
Запрос = Новый Запрос(
"ВЫБРАТЬ ПЕРВЫЕ 1 Т.Ссылка
|ИЗ Справочник.Номенклатура КАК Т
|ГДЕ Т.ИдентификаторВнешнейСистемы = &УИДСтрокой");
Запрос.УстановитьПараметр("УИДСтрокой", СтрокаУИД);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Ссылка = Выборка.Ссылка;
КонецЕсли;
В конфигурациях на базе Библиотеки стандартных подсистем (БСП) для обмена данными применяется функция ОбменДаннымиСлужебный и регистры соответствия объектов, где связь «УИД — ссылка» уже хранится явно. Если обмен настроен штатно, правильнее читать соответствие оттуда, а не конструировать ссылку вручную.
Для интерактивной работы полезна консоль запросов или обработка «поиск ссылки по GUID»: администратор вставляет идентификатор и сразу видит объект. Такие обработки реализуют тот же перебор менеджеров, что описан выше, только с пользовательским интерфейсом.
- 1Преобразуйте строку в УникальныйИдентификатор через Новый УникальныйИдентификатор(), обернув в Попытку
- 2Определите тип объекта: из контекста задачи или перебором менеджеров метаданных
- 3Получите ссылку методом Менеджер.ПолучитьСсылку(УИД)
- 4Проверьте существование объекта запросом или через ВерсияДанных
- 5Проверьте пометку удаления и только после этого используйте ссылку в записях
Особые случаи и ограничения
УИД из строки соединения или внешней системы
Внешние системы могут передавать идентификатор в верхнем регистре, без дефисов или в фигурных скобках (формат COM). Перед созданием УникальногоИдентификатора строку нужно нормализовать: удалить скобки и привести к стандартному виду. Платформа принимает строку независимо от регистра, но отсутствие дефисов уже вызовет ошибку.
УИД в технологическом журнале
В технологическом журнале идентификаторы часто записаны в «перевёрнутом» (байтовом) представлении, отличном от привычной строки. Напрямую скопировать такое значение в конструктор нельзя — потребуется преобразование порядка байтов. Это частая причина «неработающего» кода у начинающих администраторов.
Права доступа
Запрос на проверку существования объекта выполняется с учётом прав текущего пользователя и RLS. Если у пользователя нет прав на чтение объекта, запрос вернёт пустой результат, хотя объект существует. В серверных процедурах с признаком «Привилегированный» или в привилегированном режиме проверка будет корректной.
Частые вопросы
Можно ли получить ссылку, не зная тип объекта?
Да, но только перебором: для каждого менеджера метаданных (справочники, документы, планы и т.д.) формируется ссылка через ПолучитьСсылку(), затем запросом проверяется её существование. Первый тип, где объект найден, и даёт искомую ссылку. Операция ресурсоёмкая, поэтому применяется для разового поиска, а не в массовых обработках.
Почему ПолучитьСсылку() возвращает ссылку, а объекта в базе нет?
Метод не обращается к базе данных — он просто конструирует ссылку из типа и идентификатора. Если объект с таким УИД удалён или никогда не существовал, вы получите битую ссылку. Проверяйте существование запросом или через ПустаяСтрока(Ссылка.ВерсияДанных).
Как проверить, что ссылка битая?
Самый быстрый способ — сравнить ПустаяСтрока(Ссылка.ВерсияДанных): у несуществующего объекта версия данных пустая. Альтернатива — запрос «ВЫБРАТЬ ПЕРВЫЕ 1 … ГДЕ Ссылка = &Ссылка». Обращение к реквизиту битой ссылки вызовет исключение, поэтому такой способ используют только внутри Попытки.
Работает ли ПолучитьСсылку() для регистров и перечислений?
Нет. Метод есть у справочников, документов, планов видов характеристик, планов счетов, планов видов расчёта, бизнес-процессов, задач и планов обмена. Записи регистров адресуются ключом записи (набором измерений), а значения перечислений — предопределённым порядком, у них нет УИД.
УИД из технологического журнала не находится — что делать?
В технологическом журнале идентификаторы хранятся в перевёрнутом байтовом представлении, отличном от строкового формата. Нужно преобразовать порядок байтов в стандартный вид GUID, и только после этого передавать строку в конструктор Новый УникальныйИдентификатор.
Как массово найти ссылки для тысячи УИД из файла?
Загрузите идентификаторы во временную таблицу запроса, соедините её с таблицей нужного типа по условию Ссылка = ПолучитьСсылку-параметр либо храните УИД строкой и ищите по реквизиту сопоставления. Перебор менеджеров метаданных в цикле для массовой обработки не подходит — он выполнит сотни запросов на каждый идентификатор.
Что важно запомнить
Ссылку по УИД получают методом ПолучитьСсылку() менеджера конкретного типа после преобразования строки через Новый УникальныйИдентификатор. Метод не проверяет существование объекта — результат всегда проверяют запросом или через ВерсияДанных. При неизвестном типе перебирают менеджеры метаданных, а УИД из технологического журнала предварительно преобразуют из байтового представления.