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

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

Как в 1С получить ссылку на объект по навигационной ссылке

Как в 1С получить ссылку на объект по навигационной ссылке: разбор формата e1cib, извлечение GUID, готовая функция, проверка битых ссылок и типовые ошибки.

Навигационная ссылка вида e1cib/data/Справочник.Номенклатура?ref=80b900155d0ee41311ee8d3f4f2a1c5b содержит всё, что нужно для восстановления ссылки на объект: имя типа данных и уникальный идентификатор в шестнадцатеричном виде. Платформа 1С не предоставляет одной готовой функции «ссылка из навигационной ссылки» для произвольного кода, поэтому задача решается разбором строки и конструированием ссылки через менеджер объекта.

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

Что такое навигационная ссылка и из чего она состоит

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

Типичная ссылка на объект данных выглядит так:

e1cib/data/Справочник.Номенклатура?ref=80b900155d0ee41311ee8d3f4f2a1c5b

Структура разбирается на три части. Префикс e1cib/data/ указывает, что это ссылка на объект данных (бывают также ссылки на формы списков, отчёты, разделы). Далее идёт полное имя типа метаданных — Справочник.Номенклатура, Документ.РеализацияТоваровУслуг и так далее. После знака вопроса параметр ref содержит уникальный идентификатор объекта в виде 32 шестнадцатеричных символов без разделителей.

Важно понимать: значение параметра ref — это тот же GUID, который возвращает Строка(Ссылка.УникальныйИдентификатор()), только записанный без дефисов. Дополнительных преобразований и «перестановки байтов» при разборе навигационной ссылки не требуется — в отличие от разбора GUID, извлечённого из строкового представления битой ссылки вида <Объект не найден> (123:...), где порядок байтов действительно отличается.

Базовый способ: разбор строки и ПолучитьСсылку

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

НавигационнаяСсылка = "e1cib/data/Справочник.Номенклатура?ref=80b900155d0ee41311ee8d3f4f2a1c5b";

// Выделяем GUID из параметра ref

ПозицияRef = СтрНайти(НавигационнаяСсылка, "ref=");

GUIDСтрокой = Сред(НавигационнаяСсылка, ПозицияRef + 4, 32);

// Форматируем в стандартный вид GUID с дефисами

GUIDФорматированный = Сред(GUIDСтрокой, 1, 8) + "-"

+ Сред(GUIDСтрокой, 9, 4) + "-"

+ Сред(GUIDСтрокой, 13, 4) + "-"

+ Сред(GUIDСтрокой, 17, 4) + "-"

+ Сред(GUIDСтрокой, 21, 12);

УникальныйИд = Новый УникальныйИдентификатор(GUIDФорматированный);

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

Конструктор Новый УникальныйИдентификатор() принимает строку строго в формате xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, поэтому дефисы нужно вставить вручную. Если исходная строка содержит лишние символы или имеет неверную длину, будет вызвано исключение — это удобно использовать для валидации входных данных.

Метод ПолучитьСсылку() не обращается к базе данных и не проверяет существование объекта. Он просто конструирует ссылку с заданным идентификатором. Поэтому следующим обязательным шагом должна быть проверка, что объект реально существует.

Порядок действий
  1. 1
    Извлеките из навигационной ссылки имя типа между e1cib/data/ и знаком ?
  2. 2
    Извлеките 32 шестнадцатеричных символа после ref= и вставьте дефисы в формат GUID
  3. 3
    Создайте идентификатор: Новый УникальныйИдентификатор(GUID)
  4. 4
    Получите ссылку через менеджер: Справочники[Имя].ПолучитьСсылку(Ид)
  5. 5
    Проверьте существование объекта запросом или через ОбщегоНазначения.СсылкаСуществует

Универсальная функция для любого ссылочного типа

Когда тип объекта заранее неизвестен, менеджер нужно определять по имени вида метаданных. Удобнее всего использовать менеджер корневой конфигурации через вычисление имени коллекции: Справочники, Документы, ПланыВидовХарактеристик, ПланыСчетов, ПланыОбмена, БизнесПроцессы, Задачи.

Функция ПолучитьСсылкуПоНавигационнойСсылке(НавигационнаяСсылка) Экспорт

// 1. Проверяем префикс

Если Не СтрНачинаетсяС(НавигационнаяСсылка, "e1cib/data/") Тогда

ВызватьИсключение "Строка не является навигационной ссылкой на объект данных";

КонецЕсли;

// 2. Имя типа: между "e1cib/data/" и "?"

Остаток = Сред(НавигационнаяСсылка, СтрДлина("e1cib/data/") + 1);

ПозицияВопроса = СтрНайти(Остаток, "?");

Если ПозицияВопроса = 0 Тогда

ВызватьИсключение "В навигационной ссылке отсутствуют параметры";

КонецЕсли;

ПолноеИмяТипа = Лев(Остаток, ПозицияВопроса - 1); // "Справочник.Номенклатура"

// 3. GUID из параметра ref

ПозицияRef = СтрНайти(НавигационнаяСсылка, "ref=");

Если ПозицияRef = 0 Тогда

ВызватьИсключение "В навигационной ссылке отсутствует параметр ref";

КонецЕсли;

GUIDСтрокой = Сред(НавигационнаяСсылка, ПозицияRef + 4, 32);

GUIDФорматированный = Сред(GUIDСтрокой, 1, 8) + "-"

+ Сред(GUIDСтрокой, 9, 4) + "-" + Сред(GUIDСтрокой, 13, 4) + "-"

+ Сред(GUIDСтрокой, 17, 4) + "-" + Сред(GUIDСтрокой, 21, 12);

// 4. Менеджер по виду метаданных

ЧастиИмени = СтрРазделить(ПолноеИмяТипа, ".");

ИмяМенеджера = ЧастиИмени[0]; // "Справочник"

ИмяОбъекта = ЧастиИмени[1]; // "Номенклатура"

Менеджер = Неопределено;

Если ИмяМенеджера = "Справочник" Тогда

Менеджер = Справочники[ИмяОбъекта];

ИначеЕсли ИмяМенеджера = "Документ" Тогда

Менеджер = Документы[ИмяОбъекта];

ИначеЕсли ИмяМенеджера = "ПланВидовХарактеристик" Тогда

Менеджер = ПланыВидовХарактеристик[ИмяОбъекта];

ИначеЕсли ИмяМенеджера = "ПланСчетов" Тогда

Менеджер = ПланыСчетов[ИмяОбъекта];

ИначеЕсли ИмяМенеджера = "ПланОбмена" Тогда

Менеджер = ПланыОбмена[ИмяОбъекта];

ИначеЕсли ИмяМенеджера = "БизнесПроцесс" Тогда

Менеджер = БизнесПроцессы[ИмяОбъекта];

ИначеЕсли ИмяМенеджера = "Задача" Тогда

Менеджер = Задачи[ИмяОбъекта];

Иначе

ВызватьИсключение "Неподдерживаемый вид объекта: " + ИмяМенеджера;

КонецЕсли;

Возврат Менеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(GUIDФорматированный));

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

Функцию разумно разместить в общем серверном модуле, чтобы она была доступна и из обработок, и из регламентных заданий. Если в вашей конфигурации используется БСП, часть проверок можно заменить готовыми методами ОбщегоНазначения.

Проверка, что объект существует

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

Самый надёжный способ проверки — запрос:

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

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

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

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

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

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

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

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

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

Запрос по полученной ссылке
Норма

Возвращает одну строку — объект существует

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

Пустой результат — ссылка битая или база другая

Строковое представление ссылки
Норма

Обычное представление объекта (наименование, номер)

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

Строка вида <Объект не найден> (...)

Тип результата функции
Норма

Ожидаемый тип, например СправочникСсылка.Номенклатура

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

Неопределено или исключение на этапе разбора строки

Обратная задача и альтернативные подходы

Обратное преобразование выполняется штатно: ПолучитьНавигационнуюСсылку(Ссылка) вернёт строку вида e1cib/data/..., которую можно передать пользователю или сохранить во внешней системе. Для хранения ссылок между базами чаще используют не навигационную ссылку целиком, а пару «полное имя типа + GUID» — это компактнее и не зависит от формата, который теоретически может меняться между версиями платформы.

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

Отдельный сценарий — разбор ссылок из строки «Объект не найден». Там GUID хранится в другом порядке байтов, и прямое применение функции из этой статьи даст неверный идентификатор. Для таких строк нужна отдельная процедура перестановки байтов либо обработка с ИТС.

Сравнение вариантов

Разбор навигационной ссылки + ПолучитьСсылку

Универсально, работает для любых ссылочных типов; требует ручного разбора строки и проверки существования

Хранение пары тип + GUID во внешней системе

Надёжнее для интеграций, не зависит от формата e1cib; требует менять формат обмена

ОбщегоНазначения.СсылкаСуществует (БСП)

Готовая проверка существования; доступна только в конфигурациях на БСП

Разбор строки 'Объект не найден'

Единственный путь восстановить битую ссылку из её текста; требует перестановки байтов GUID

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

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

Ещё одна ловушка — навигационные ссылки не на объекты: ссылки на формы списков, отчёты, команды интерфейса не содержат параметра ref и не могут быть преобразованы в ссылку на данные. Функция должна отсекать такие входные значения на этапе проверки префикса e1cib/data/.

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

Типичные ошибки
01
Передача GUID без дефисов в конструктор — исключение о неверном формате параметра
02
Использование ссылки без проверки существования — ошибки 'Объект не найден' в дальнейшей логике
03
Применение функции к строке 'Объект не найден' — GUID там в другом порядке байтов, результат неверный
04
Разбор ссылок на формы и отчёты — в них нет параметра ref, функция падает или возвращает мусор
05
Игнорирование RLS — объект 'не найден' из-за прав, а не из-за отсутствия в базе

Мини-FAQ по смежным вопросам

Можно ли получить ссылку из навигационной ссылки штатной функцией платформы?

Отдельной готовой функции «ссылка из навигационной ссылки» для произвольного кода в платформе нет. Платформа сама умеет открывать такие ссылки через ПерейтиПоНавигационнойСсылке(), но для получения ссылки в коде используется разбор строки и ПолучитьСсылку(), как показано выше.

Работает ли способ для навигационных ссылок из другой информационной базы?

Технически ссылка будет сконструирована, но объект с таким GUID найдётся только если базы связаны обменом и идентификаторы синхронизированы. Иначе вы получите битую ссылку, поэтому проверка существования обязательна.

Чем отличается GUID в параметре ref от GUID в строке 'Объект не найден'?

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

Как получить ссылку, если известен только GUID без типа объекта?

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

Можно ли использовать этот подход на клиенте в тонком клиенте?

Разбор строки и создание УникальныйИдентификатор доступны и на клиенте, но вызов менеджеров (Справочники, Документы) и запросы выполняются только на сервере. Размещайте функцию в серверном общем модуле и вызывайте её с клиента через серверный вызов.

Итог

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

Навигационная ссылка содержит тип объекта и GUID в параметре ref. Извлеките обе части, отформатируйте GUID с дефисами, создайте ссылку через менеджер вида объектов и обязательно проверьте существование объекта запросом. Для строк 'Объект не найден' нужен отдельный алгоритм с перестановкой байтов.