К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как получить объект по GUID в 1С

Как получить объект по ГУИДу в 1С: метод ПолучитьСсылку, работа с уникальным идентификатором, поиск ссылок по GUID, типичные ошибки и примеры кода на встроенном языке.

Уникальный идентификатор (GUID, ГУИД) — это 36-символьная строка вида «8b3a4c5e-…», которую платформа 1С присваивает каждой ссылке на объект базы: справочнику, документу, плану счетов. Получить объект по GUID требуется при обмене данными между базами, интеграции с внешними системами, отладке переноса данных и восстановлении «битых» ссылок.

Важно понимать разницу между тремя сущностями: ссылка — это объект встроенного языка вида «СправочникСсылка.Номенклатура», объект — открытая на изменение сущность с данными (СправочникОбъект), а GUID — только строковое представление ссылки. Нельзя «получить объект» напрямую из GUID: сначала из строки восстанавливается ссылка, затем по ссылке получается объект методом ПолучитьОбъект().

Ниже разобраны все рабочие способы: штатный метод ПолучитьСсылку, поиск по строковому представлению через XML-тип, обработка случаев, когда объекта в базе нет, и типичные ошибки, которые приводят к созданию «битых» ссылок и потере данных.

Что такое GUID в 1С и как его узнать

GUID (глобально уникальный идентификатор) — это 128-битное значение, которое платформа генерирует при создании ссылки. Встроенный тип данных называется УникальныйИдентификатор. У одной ссылки всегда один GUID, и он не меняется при переносе объекта между базами средствами конвертации данных — именно поэтому GUID используют как ключ сопоставления при обмене.

Узнать GUID существующей ссылки можно несколькими способами. В коде — через одноимённое свойство:

Ид = СсылкаНаТовар.УникальныйИдентификатор();

СтрокаГУИД = Строка(Ид); // "8b3a4c5e-...."

В пользовательском режиме GUID не отображается в формах по умолчанию. Его можно посмотреть через консоль запросов, универсальную обработку «Поиск объектов по GUID» или через адресную строку веб-клиента, где идентификатор присутствует в параметре ref. Также GUID виден при выгрузке объекта в XML — там он фигурирует как значение ссылки.

Основной способ: метод ПолучитьСсылку

Штатный механизм — метод ПолучитьСсылку() менеджера конкретного типа объекта. Он принимает значение типа УникальныйИдентификатор и возвращает ссылку соответствующего типа:

СтрокаГУИД = "8b3a4c5e-1a2b-4c3d-9e8f-0123456789ab";

Ид = Новый УникальныйИдентификатор(СтрокаГУИД);

Ссылка = Справочники.Номенклатура.ПолучитьСсылку(Ид);

Если Не Ссылка.Пустая() Тогда

Объект = Ссылка.ПолучитьОбъект();

КонецЕсли;

Ключевая особенность: ПолучитьСсылку не проверяет, существует ли объект в базе. Если объект с таким GUID никогда не записывался, метод всё равно вернёт корректную ссылку — «обещание» объекта. Такая ссылка даже может быть записана как новый элемент: если вызвать ПолучитьОбъект() у несуществующей ссылки, вернётся Неопределено, а если создать объект через СоздатьЭлемент() и присвоить ему эту ссылку через УстановитьСсылкуНового(), объект запишется именно с этим GUID.

Это свойство активно используется в обменах: сначала всем новым объектам назначаются GUID из базы-источника, затем они записываются, и ссылочная целостность сохраняется без дополнительного сопоставления.

bsl
Ид = Новый УникальныйИдентификатор(СтрокаГУИД);
Ссылка = Справочники.Номенклатура.ПолучитьСсылку(Ид);
Если ОбщегоНазначения.СсылкаСуществует(Ссылка) Тогда
    Объект = Ссылка.ПолучитьОбъект();
КонецЕсли;

Как проверить, что объект существует

Поскольку ПолучитьСсылку возвращает ссылку независимо от наличия объекта, проверка существования обязательна. Самый надёжный способ — запрос к базе:

Запрос = Новый Запрос(

"ВЫБРАТЬ ПЕРВЫЕ 1 ИСТИНА

|ИЗ Справочник.Номенклатура КАК Т

|ГДЕ Т.Ссылка = &Ссылка");

Запрос.УстановитьПараметр("Ссылка", Ссылка);

Существует = Не Запрос.Выполнить().Пустой();

В конфигурациях на базе БСП (Библиотека стандартных подсистем) есть готовая функция ОбщегоНазначения.СсылкаСуществует(Ссылка), которая делает то же самое. Альтернативный приём без запроса — попытка прочитать любой реквизит ссылки или вызвать ПолучитьОбъект() и сравнить результат с Неопределено, но обращение к реквизитам битой ссылки вызовет исключение, поэтому вариант с запросом предпочтительнее.

Контрольные точки

Как проверить результат

Ссылка после ПолучитьСсылку
Норма

Ссылка не пустая, тип соответствует ожидаемому

Тревожный признак

Ссылка пустая — значит, GUID не валиден или обнулён

Существование объекта
Норма

Запрос по ссылке возвращает строку, ПолучитьОбъект() возвращает объект

Тревожный признак

Запрос пустой, ПолучитьОбъект() вернул Неопределено — объекта в базе нет

Чтение реквизитов
Норма

Реквизиты читаются без исключений

Тревожный признак

Ошибка «Ошибка при вызове метода контекста» — ссылка битая

Получение ссылки, когда тип объекта неизвестен

Метод ПолучитьСсылку требует заранее знать тип: справочник, документ или план видов характеристик. Если GUID пришёл из внешней системы без указания типа, придётся перебирать менеджеры. Практичный подход — последовательно пройти по нужным коллекциям метаданных и проверять существование:

Функция НайтиСсылкуПоГУИД(СтрокаГУИД)

Ид = Новый УникальныйИдентификатор(СтрокаГУИД);

Для Каждого Менеджер Из Справочники Цикл

Ссылка = Менеджер.Значение.ПолучитьСсылку(Ид);

// проверка существования запросом

КонецЦикла;

КонецФункции

Полный перебор всех таблиц базы — дорогая операция, на больших базах она может занимать минуты. Поэтому в интеграциях GUID всегда передают вместе с типом объекта (например, «Catalog.Номенклатура» в формате Enterprise Data или имя таблицы в собственном протоколе). Это снимает неоднозначность и ускоряет поиск до одного запроса.

Поиск объекта по GUID через строку ссылки

Второй распространённый сценарий — GUID известен в виде, в котором он хранится в «битой ссылке» или в XML-выгрузке. Строковое представление ссылки для ЗначениеВСтрокуВнутр и XML отличается от обычного GUID порядком байтов. Если у вас есть значение из текста ошибки «Объект не найден», штатного метода прямого преобразования нет — используют либо готовые обработки поиска битых ссылок, либо перебор с сравнением Строка(Ссылка.УникальныйИдентификатор()).

При обмене через XML (методы ПрочитатьXML, планы обмена) платформа восстанавливает ссылки автоматически. Если же вы разбираете XML вручную через ЧтениеXML, GUID из атрибута преобразуется стандартно: Новый УникальныйИдентификатор(СтрокаИзXML), далее ПолучитьСсылку.

Сравнение подходов

Менеджер.ПолучитьСсылку(Ид)

Основной способ, когда тип объекта известен. Быстрый, но не проверяет существование объекта — нужна отдельная проверка.

Запрос по таблицам с перебором типов

Подходит, когда тип неизвестен. Медленно на больших базах, требует ограничения списка таблиц.

Готовые обработки поиска по GUID

Удобны для разового поиска администратором без программирования. Не подходят для встраивания в прикладной код обмена.

Типичные ошибки и ограничения

Самая частая ошибка — попытка сконструировать GUID вручную с нарушением формата. Конструктор Новый УникальныйИдентификатор(Строка) выбрасывает исключение, если строка не соответствует шаблону 8-4-4-4-12 шестнадцатеричных символов. Перед созданием идентификатора строку из внешнего источника стоит обрезать от пробелов и проверить длину.

Вторая группа ошибок связана с правами и транзакциями. Получение объекта методом ПолучитьОбъект() требует права чтения, а запись — права изменения; при RLS объект может «не существовать» для пользователя, хотя в базе он есть. Также нельзя получать объект по ссылке и долго держать его открытым в транзакции обмена — это приводит к конфликтам блокировок при параллельной работе.

Типичные ошибки
01
Вызов ПолучитьОбъект() без проверки существования — получаете Неопределено и ошибку при обращении к реквизитам
02
Передача строки GUID с пробелами или в неверном регистре из внешней системы — исключение в конструкторе УникальныйИдентификатор
03
Поиск по всем таблицам базы без ограничения типов — тяжёлые запросы и блокировки на рабочей базе
04
Сравнение GUID как строк с разным регистром символов при сопоставлении баз — ложные несовпадения, дубли объектов при обмене
05
Использование ПолучитьСсылку для проверки существования — метод всегда возвращает непустую ссылку, проверка бессмысленна

Порядок безопасной реализации в коде

Для прикладного кода обмена или интеграции выдерживайте единый порядок: валидация строки, создание идентификатора, получение ссылки, проверка существования, работа с объектом. Такой конвейер исключает обращения к битым ссылкам и делает поведение предсказуемым при любых входных данных.

Порядок действий
  1. 1
    Получите строку GUID из внешнего источника и очистите её от пробелов и лишних символов
  2. 2
    Создайте значение: Ид = Новый УникальныйИдентификатор(СтрокаГУИД) — оберните в Попытка/Исключение
  3. 3
    Получите ссылку нужного типа: Ссылка = Справочники.Имя.ПолучитьСсылку(Ид)
  4. 4
    Проверьте существование объекта запросом или функцией СсылкаСуществует
  5. 5
    Если объект есть — получите его через Ссылка.ПолучитьОбъект() и работайте с данными
  6. 6
    Если объекта нет — создайте новый и зафиксируйте GUID через УстановитьСсылкуНового, если это требуется обменом

При массовой обработке (загрузка тысяч объектов) проверку существования выгоднее выполнять пакетно: собрать все GUID в таблицу значений, одним запросом найти существующие ссылки и далее обрабатывать только разницу. Это сокращает число обращений к базе на порядки по сравнению с проверкой каждой ссылки в цикле.

При сопоставлении объектов между базами храните GUID в служебном регистре сведений «Соответствия объектов», а не вычисляйте его на лету. Это ускоряет обмены и позволяет разруливать ситуации, когда объект в одной из баз был пересоздан с новым идентификатором.
ПЗ
Практическое замечание

Частые вопросы

Можно ли получить объект сразу по GUID, минуя ссылку?

Нет. Встроенный язык не имеет метода «получить объект по идентификатору». Путь всегда двухступенчатый: GUID → ссылка через ПолучитьСсылку, затем ссылка → объект через ПолучитьОбъект(). Промежуточная проверка существования ссылки — обязательный элемент надёжного кода.

Почему ПолучитьОбъект() возвращает Неопределено?

Это значит, что ссылки с таким GUID в базе нет: объект не создавался, был удалён физически или GUID пришёл из другой базы без переноса самого объекта. Метод ПолучитьСсылку при этом отработал корректно — он не обращается к данным, а только конструирует ссылку.

Одинаковы ли GUID у объекта в разных базах?

Только если объект переносился штатными средствами обмена или был создан с принудительной установкой ссылки через УстановитьСсылкуНового. Если объект создавался в каждой базе независимо, GUID будут разными даже при совпадении всех реквизитов.

Как найти GUID битой ссылки в документе?

Программно — прочитать значение реквизита: битая ссылка возвращается как обычная ссылка, у неё можно взять УникальныйИдентификатор(). В пользовательском режиме проще воспользоваться обработкой поиска и восстановления битых ссылок, которая покажет GUID и тип утерянного объекта.

Можно ли изменить GUID существующего объекта?

Напрямую — нет, GUID неизменен на протяжении жизни ссылки. Обходной путь: создать новый объект с нужным GUID через УстановитьСсылкуНового, перенести данные и заменить все ссылки на старый объект, после чего удалить его. Операция рискованная и выполняется только с резервной копией.

Работает ли поиск по GUID в запросе?

Да, но не по строке GUID напрямую. В запрос передают уже готовую ссылку как параметр: Запрос.УстановитьПараметр("Ссылка", Ссылка). Сравнение в запросе идёт по ссылке, а ссылка предварительно получается из GUID методом ПолучитьСсылку.

Итог

Что важно запомнить

Объект по GUID получают в два шага: Новый УникальныйИдентификатор(строка) → Менеджер.ПолучитьСсылку(Ид) → Ссылка.ПолучитьОбъект(). Метод ПолучитьСсылку не проверяет существование объекта, поэтому перед работой всегда проверяйте ссылку запросом или функцией СсылкаСуществует. Тип объекта при интеграциях передавайте вместе с GUID — это избавляет от перебора таблиц.