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

Разработка и Конфигурация · 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. 1
    Преобразуйте строку в УникальныйИдентификатор через конструктор
  2. 2
    Вызовите ПолучитьСсылку(GUID) у менеджера нужного типа
  3. 3
    Проверьте существование объекта запросом по ссылке
  4. 4
    Если объект не найден — создайте его с этим GUID через УстановитьСсылкуНового() или зафиксируйте ошибку обмена

Проверка: существует ли объект с таким GUID

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

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

"ВЫБРАТЬ ПЕРВЫЕ 1

| Т.Ссылка

|ИЗ

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

|ГДЕ

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

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

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

Альтернатива без запроса — попытка получить объект и проверка на Неопределено:

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

Если Объект = Неопределено Тогда

// объекта нет в базе

КонецЕсли;

Этот вариант медленнее, так как читает все данные объекта, но удобен, если объект всё равно нужен для дальнейшей работы. Признак «битой» ссылки в интерфейсе — строка вида «<Объект не найден> (a4f2c1e0-…)» в полях ввода и отчётах.

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

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

Запрос по ссылке вернул строку
Норма

Объект существует, ссылка рабочая

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

Пустой результат — объекта нет, ссылка битая

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

Возвращён объект, доступны реквизиты

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

Возвращено Неопределено — объект удалён или не переносился

Отображение в поле ввода
Норма

Показывается наименование или номер объекта

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

Текст «Объект не найден» с идентификатором

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

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

Функция НайтиСсылкуПоGUID(GUID)

Менеджеры = Новый Массив;

Менеджеры.Добавить(Справочники);

Менеджеры.Добавить(Документы);

Менеджеры.Добавить(ПланыВидовХарактеристик);

Менеджеры.Добавить(ПланыСчетов);

Менеджеры.Добавить(ПланыВидовРасчета);

Менеджеры.Добавить(БизнесПроцессы);

Менеджеры.Добавить(Задачи);

Для Каждого Коллекция Из Менеджеры Цикл

Для Каждого Менеджер Из Коллекция Цикл

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

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

...

КонецЦикла;

КонецЦикла;

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

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

Более правильное архитектурное решение — передавать тип вместе с GUID. В формате XML пакета XDTO или при сериализации через ЗначениеВСтрокуВнутр / XMLСтрока тип сохраняется автоматически, и на приёмной стороне ссылка восстанавливается без перебора:

СтрокаДляПередачи = XMLСтрока(Ссылка);        // упаковка с типом

СсылкаНазад = XMLЗначение(Тип("..."), СтрокаДляПередачи); // восстановление

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

Создание объекта с заданным GUID

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

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

НовыйЭлемент.УстановитьСсылкуНового(

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

НовыйЭлемент.Наименование = "Загружено обменом";

НовыйЭлемент.Записать();

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

Этот приём лежит в основе типовых механизмов обмена: сначала создаётся «заглушка» с нужным GUID, затем при полной загрузке она заполняется данными. Так ссылки между объектами сохраняются корректными даже при загрузке в произвольном порядке.

Типичные ошибки при работе с GUID

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

Вторая ошибка — сравнение идентификаторов как строк с учётом регистра. Разные системы выгружают GUID в верхнем или нижнем регистре; строковое сравнение «A4F2…» и «a4f2…» даст ложное неравенство. Сравнивайте значения типа УникальныйИдентификатор, а не их строковые представления.

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

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

FAQ

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

Штатного глобального метода «найти по GUID везде» в платформе нет. Нужно либо перебирать менеджеры ссылочных типов с проверкой существования, либо передавать тип вместе с идентификатором в формате обмена.

Чем ПолучитьСсылку() отличается от НайтиПоКоду() или запроса?

ПолучитьСсылку() формирует ссылку из GUID локально, без обращения к базе, и не проверяет существование объекта. Поиск по коду и запрос читают данные из базы и возвращают только реально существующие объекты.

Что делать, если строка GUID пришла без дефисов?

Программно вставьте дефисы после 8, 12, 16 и 20 символов, чтобы получить канонический вид xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, и только после этого передавайте строку в конструктор Новый УникальныйИдентификатор().

Меняется ли GUID объекта при копировании или обмене?

При копировании объекта внутри базы создаётся новый идентификатор. При корректно настроенном обмене GUID сохраняется — именно это обеспечивает сопоставление объектов между базами.

Как восстановить объект по «битой» ссылке?

Из текста «Объект не найден» извлеките GUID, получите ссылку через ПолучитьСсылку() у нужного менеджера, затем создайте объект-заглушку с этим идентификатором через УстановитьСсылкуНового() и заполните его данными из источника.

Работает ли ПолучитьСсылку() на клиенте в управляемых формах?

Метод доступен только на сервере. В клиентском коде вызывайте серверную процедуру, которая выполнит получение ссылки и проверку существования, и вернёт результат.

Итог

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

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