Разработка и Конфигурация · 11 мин
Как получить ссылку на объект по уникальному идентификатору в 1С
Практические способы получить ссылку на объект 1С по GUID: ПолучитьСсылку(), преобразование строки в УникальныйИдентификатор, поиск по всем типам, проверка битых ссылок.
Уникальный идентификатор (GUID) — это 36-символьная строка вида «8b3b3c4e-…», которая однозначно определяет объект в базе 1С. Задача получить по нему ссылку возникает при обмене данными между базами, при разборе внешних файлов, при интеграции через HTTP-сервисы и при восстановлении «битых» ссылок. Встроенный язык платформы даёт для этого несколько инструментов, и выбор зависит от того, известен ли тип объекта заранее.
Главный метод — ПолучитьСсылку(), доступный у менеджеров справочников, документов, планов видов характеристик и других ссылочных типов. Он не обращается к данным объекта, а формирует ссылку напрямую из идентификатора, поэтому работает быстро и не требует запроса к базе. Однако у него есть тонкости: метод не проверяет, существует ли объект на самом деле.
Ниже разобраны рабочие приёмы: преобразование строки в тип УникальныйИдентификатор, получение ссылки при известном и неизвестном типе, проверка существования объекта, обратная задача — получение GUID из ссылки, а также типичные ошибки, которые приводят к «битым» ссылкам и ошибкам обмена.
Что такое уникальный идентификатор и где он хранится
Каждый объект ссылочного типа в 1С (элемент справочника, документ, план счетов и т.д.) имеет поле «Ссылка», внутри которого хранится 16-байтовый уникальный идентификатор. В интерфейсе и при выгрузке он представляется строкой из 36 символов с дефисами, например a4f2c1e0-5b7d-11ec-9f3a-00155d0a1b2c. Регистр символов значения не имеет.
Важно понимать: GUID сам по себе не содержит информации о типе объекта. Одна и та же строка может теоретически соответствовать и элементу справочника, и документу — платформа различает их только в связке «тип + идентификатор». Именно поэтому метод ПолучитьСсылку() вызывается у конкретного менеджера, а не глобально.
Получить GUID существующей ссылки можно через свойство УникальныйИдентификатор():
GUIDСтрокой = Строка(СсылкаНаОбъект.УникальныйИдентификатор());
В клиент-серверном варианте идентификатор также виден в таблицах СУБД в поле _IDRRef (в двоичном виде), а в файловой базе — во внутреннем хранилище 1Cv8.1CD, но напрямую работать с этими данными не рекомендуется.
Преобразование строки в тип УникальныйИдентификатор
Если GUID пришёл из внешней системы, файла обмена или строки URL, его нужно сначала превратить в значение типа УникальныйИдентификатор. Делается это конструктором:
GUID = Новый УникальныйИдентификатор("a4f2c1e0-5b7d-11ec-9f3a-00155d0a1b2c");
Если строка имеет неверный формат — лишние символы, неправильное количество дефисов, недопустимые знаки — конструктор вызовет исключение. Поэтому в коде, принимающем данные извне, преобразование стоит оборачивать в попытку:
Попытка
GUID = Новый УникальныйИдентификатор(СтрокаИзФайла);
Исключение
ВызватьИсключение "Некорректный формат GUID: " + СтрокаИзФайла;
КонецПопытки;
Отдельный случай — пустой идентификатор 00000000-0000-0000-0000-000000000000. Он соответствует пустой ссылке, и передавать его в поиск объекта бессмысленно: такой ссылке не будет соответствовать ни один реальный объект.
Получение ссылки при известном типе объекта
Самый частый сценарий: тип объекта известен из контекста обмена. Например, из другой базы пришёл GUID элемента справочника «Номенклатура». Код получения ссылки выглядит так:
GUID = Новый УникальныйИдентификатор(СтрокаGUID);
Ссылка = Справочники.Номенклатура.ПолучитьСсылку(GUID);
Тот же приём работает для документов, планов видов характеристик, планов счетов, планов обмена, бизнес-процессов и задач — у всех менеджеров ссылочных типов есть метод ПолучитьСсылку():
СсылкаДок = Документы.РеализацияТоваровУслуг.ПолучитьСсылку(GUID);
Ключевая особенность метода: он не выполняет запрос к базе. Ссылка формируется локально из типа и идентификатора. Если объекта с таким GUID не существует, вы всё равно получите ссылку — но «битую». Поэтому следующий обязательный шаг — проверка существования.
- 1Преобразуйте строку в УникальныйИдентификатор через конструктор
- 2Вызовите ПолучитьСсылку(GUID) у менеджера нужного типа
- 3Проверьте существование объекта запросом по ссылке
- 4Если объект не найден — создайте его с этим GUID через УстановитьСсылкуНового() или зафиксируйте ошибку обмена
Проверка: существует ли объект с таким GUID
Самый быстрый способ проверки — запрос по ссылке. Он не создаёт объект в памяти и отрабатывает за одно обращение к индексу:
Запрос = Новый Запрос(
"ВЫБРАТЬ ПЕРВЫЕ 1
| Т.Ссылка
|ИЗ
| Справочник.Номенклатура КАК Т
|ГДЕ
| Т.Ссылка = &Ссылка");
Запрос.УстановитьПараметр("Ссылка", Ссылка);
ОбъектСуществует = Не Запрос.Выполнить().Пустой();
Альтернатива без запроса — попытка получить объект и проверка на Неопределено:
Объект = Ссылка.ПолучитьОбъект();
Если Объект = Неопределено Тогда
// объекта нет в базе
КонецЕсли;
Этот вариант медленнее, так как читает все данные объекта, но удобен, если объект всё равно нужен для дальнейшей работы. Признак «битой» ссылки в интерфейсе — строка вида «<Объект не найден> (a4f2c1e0-…)» в полях ввода и отчётах.
Как проверить результат
Объект существует, ссылка рабочая
Пустой результат — объекта нет, ссылка битая
Возвращён объект, доступны реквизиты
Возвращено Неопределено — объект удалён или не переносился
Показывается наименование или номер объекта
Текст «Объект не найден» с идентификатором
Поиск ссылки, когда тип объекта неизвестен
Если из внешней системы пришёл только GUID без указания типа, придётся перебирать менеджеры ссылочных типов. Универсальная функция строится на переборе коллекций метаданных:
Функция НайтиСсылкуПоGUID(GUID)
Менеджеры = Новый Массив;
Менеджеры.Добавить(Справочники);
Менеджеры.Добавить(Документы);
Менеджеры.Добавить(ПланыВидовХарактеристик);
Менеджеры.Добавить(ПланыСчетов);
Менеджеры.Добавить(ПланыВидовРасчета);
Менеджеры.Добавить(БизнесПроцессы);
Менеджеры.Добавить(Задачи);
Для Каждого Коллекция Из Менеджеры Цикл
Для Каждого Менеджер Из Коллекция Цикл
Ссылка = Менеджер.ПолучитьСсылку(GUID);
// проверка существования запросом
...
КонецЦикла;
КонецЦикла;
КонецФункции
Такой перебор с проверкой каждой ссылки запросом — дорогая операция: на конфигурации с сотнями ссылочных типов это сотни запросов к базе. Поэтому универсальный поиск оправдан только как разовый сервисный инструмент, а не как часть регулярного обмена.
Более правильное архитектурное решение — передавать тип вместе с GUID. В формате XML пакета XDTO или при сериализации через ЗначениеВСтрокуВнутр / XMLСтрока тип сохраняется автоматически, и на приёмной стороне ссылка восстанавливается без перебора:
СтрокаДляПередачи = XMLСтрока(Ссылка); // упаковка с типом
СсылкаНазад = XMLЗначение(Тип("..."), СтрокаДляПередачи); // восстановление
В реальных обменах тип объекта почти всегда известен из структуры сообщения: узел «Номенклатура» содержит только номенклатуру. Проектируйте формат обмена так, чтобы тип передавался явно — это избавит от перебора всех менеджеров и ускорит загрузку на порядки.
Создание объекта с заданным GUID
Обратная задача тоже частая: объект из другой базы ещё не загружен, но ссылка на него нужна уже сейчас. Платформа позволяет создать новый объект с заранее заданным идентификатором:
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.УстановитьСсылкуНового(
Справочники.Номенклатура.ПолучитьСсылку(GUID));
НовыйЭлемент.Наименование = "Загружено обменом";
НовыйЭлемент.Записать();
Метод УстановитьСсылкуНового() нужно вызывать до первой записи объекта. После записи идентификатор изменить нельзя — он является частью первичного ключа. Если объект с таким GUID уже существует, попытка записи завершится ошибкой нарушения уникальности.
Этот приём лежит в основе типовых механизмов обмена: сначала создаётся «заглушка» с нужным GUID, затем при полной загрузке она заполняется данными. Так ссылки между объектами сохраняются корректными даже при загрузке в произвольном порядке.
Типичные ошибки при работе с GUID
Первая ошибка — использование ПолучитьСсылку() без проверки существования с последующей записью этой ссылки в реквизиты других объектов. В базе накапливаются «битые» ссылки, которые потом приходится вычищать обработками. Всегда проверяйте результат запросом.
Вторая ошибка — сравнение идентификаторов как строк с учётом регистра. Разные системы выгружают GUID в верхнем или нижнем регистре; строковое сравнение «A4F2…» и «a4f2…» даст ложное неравенство. Сравнивайте значения типа УникальныйИдентификатор, а не их строковые представления.
Третья ошибка — попытка получить GUID у несохранённого объекта через УникальныйИдентификатор() у ссылки, которой ещё нет. До записи используйте ПолучитьСсылкуНового() — именно он возвращает ссылку, назначенную новому объекту.
FAQ
Можно ли получить ссылку по GUID без указания типа объекта одним вызовом?
Штатного глобального метода «найти по GUID везде» в платформе нет. Нужно либо перебирать менеджеры ссылочных типов с проверкой существования, либо передавать тип вместе с идентификатором в формате обмена.
Чем ПолучитьСсылку() отличается от НайтиПоКоду() или запроса?
ПолучитьСсылку() формирует ссылку из GUID локально, без обращения к базе, и не проверяет существование объекта. Поиск по коду и запрос читают данные из базы и возвращают только реально существующие объекты.
Что делать, если строка GUID пришла без дефисов?
Программно вставьте дефисы после 8, 12, 16 и 20 символов, чтобы получить канонический вид xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, и только после этого передавайте строку в конструктор Новый УникальныйИдентификатор().
Меняется ли GUID объекта при копировании или обмене?
При копировании объекта внутри базы создаётся новый идентификатор. При корректно настроенном обмене GUID сохраняется — именно это обеспечивает сопоставление объектов между базами.
Как восстановить объект по «битой» ссылке?
Из текста «Объект не найден» извлеките GUID, получите ссылку через ПолучитьСсылку() у нужного менеджера, затем создайте объект-заглушку с этим идентификатором через УстановитьСсылкуНового() и заполните его данными из источника.
Работает ли ПолучитьСсылку() на клиенте в управляемых формах?
Метод доступен только на сервере. В клиентском коде вызывайте серверную процедуру, которая выполнит получение ссылки и проверку существования, и вернёт результат.
Что важно запомнить
Ссылка по GUID получается методом ПолучитьСсылку() у менеджера конкретного типа, строка предварительно преобразуется конструктором Новый УникальныйИдентификатор(). Метод не проверяет существование объекта — делайте это запросом. Тип объекта передавайте вместе с GUID, а при загрузке новых объектов фиксируйте идентификатор через УстановитьСсылкуНового() до записи.