Разработка и Конфигурация · 13 мин
1С: как получить объект по навигационной ссылке
Как в 1С получить объект по навигационной ссылке: ПолучитьНавигационнуюСсылку, ПолучитьИзВременногоХранилища, разбор ссылки в запросе и коде, типичные ошибки.
Навигационная ссылка в 1С — это строка вида e1cib/data/Документ.РеализацияТоваровУслуг?ref=8b9a00155d64030111e7a1b2c3d4e5f6, которая однозначно указывает на объект информационной базы. Такие ссылки используются при обмене между базами, в интеграциях через HTTP-сервисы, при переходах по внешним уведомлениям и при формировании ссылок для пользователей. Задача «получить объект по навигационной ссылке» возникает, когда на входе есть только строка, а нужно открыть, изменить или проверить сам объект.
Важно сразу разделить два понятия: навигационная ссылка — это просто текст, а объект базы — это данные, которые нужно найти по уникальному идентификатору, зашитому внутри строки. Платформа не имеет единой функции «дать объект по навигационной ссылке», поэтому задача решается разбором строки и извлечением из неё типа объекта и УИД, после чего строится обычная ссылка типа ДокументСсылка или СправочникСсылка.
Ниже рассмотрены рабочие способы: обратная операция через ПолучитьНавигационнуюСсылку, ручной разбор строки, получение ссылки через Новый УникальныйИдентификатор и менеджер объекта, а также проверка существования объекта и типичные ошибки, которые приводят к битым ссылкам.
Что такое навигационная ссылка и как она устроена
Навигационная ссылка формируется платформой автоматически и имеет строгую структуру. Для объектных данных (документов, справочников, задач) она выглядит как e1cib/data/<ПолноеИмяМетаданных>?ref=<УИД>. Часть e1cib/data — служебный префикс, далее идёт полное имя объекта метаданных в том виде, как оно задано в конфигураторе, а после параметра ref — шестнадцатеричное представление уникального идентификатора.
Обратите внимание: УИД в навигационной ссылке записан в «перевёрнутом» виде относительно привычного строкового представления GUID. Платформа при формировании ссылки меняет порядок байтов, поэтому простое копирование фрагмента после ref= в конструктор Новый УникальныйИдентификатор() даст неверный идентификатор. Это самая частая причина, почему «объект по ссылке не находится».
Навигационные ссылки бывают не только на объекты, но и на записи регистров сведений, разделы, отчёты и обработки. Метод разбора, описанный ниже, применим именно к ссылкам вида e1cib/data на объектные данные — справочники, документы, планы видов характеристик и т.п.
Как получить навигационную ссылку объекта
Прежде чем разбирать чужую ссылку, полезно понимать, как она создаётся. Для любой ссылки на объект платформа предоставляет глобальный метод ПолучитьНавигационнуюСсылку():
НавСсылка = ПолучитьНавигационнуюСсылку(ДокументСсылка);
// Результат: e1cib/data/Документ.РеализацияТоваровУслуг?ref=...
Для записи регистра сведений метод вызывается с ключом записи, для констант — с именем константы. Полученную строку можно сохранить в дополнительном свойстве, отправить во внешнюю систему или показать пользователю в сообщении — по ней любой клиент 1С, подключённый к этой же базе, откроет объект.
Полезный приём для отладки: в тонком клиенте навигационную ссылку открытой формы можно скопировать через команду «Получить ссылку» (кнопка с изображением цепочки в системной панели или сочетание клавиш). Это удобный способ получить тестовую строку для проверки своего кода разбора.
Разбор навигационной ссылки и получение ссылки на объект
Универсальный подход — извлечь из строки полное имя метаданных и УИД, затем через Менеджер соответствующего вида построить ссылку. Сначала нужно правильно преобразовать шестнадцатеричный УИД из ссылки в строку GUID. Платформа сама умеет делать обратное преобразование: если передать в конструктор Новый УникальныйИдентификатор() строку из 32 шестнадцатеричных символов без дефисов, она интерпретируется корректно в том представлении, которое используется в навигационных ссылках.
Функция СсылкаИзНавигационнойСсылки(НавСсылка)
// Отделяем имя метаданных и УИД
ПозицияПараметра = СтрНайти(НавСсылка, "?ref=");
Если ПозицияПараметра = 0 Тогда
Возврат Неопределено;
КонецЕсли;
ЧастьДанных = Сред(НавСсылка, СтрНайти(НавСсылка, "e1cib/data/") + 10);
ИмяМетаданных = Лев(ЧастьДанных, СтрНайти(ЧастьДанных, "?") - 1);
УИДСтрокой = Сред(НавСсылка, ПозицияПараметра + 5);
УИД = Новый УникальныйИдентификатор(УИДСтрокой);
Менеджер = МенеджерПоИмени(ИмяМетаданных); // см. ниже
Если Менеджер = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Возврат Менеджер.ПолучитьСсылку(УИД);
КонецФункции
Функция МенеджерПоИмени сопоставляет строку вида «Документ.РеализацияТоваровУслуг» с нужным менеджером. Проще всего получить объект метаданных через Метаданные.НайтиПоПолномуИмени(ИмяМетаданных) и по его родителю определить коллекцию:
Функция МенеджерПоИмени(ИмяМетаданных)
ОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(ИмяМетаданных);
Если ОбъектМетаданных = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Родитель = ОбъектМетаданных.Родитель().Имя;
Если Родитель = "Справочники" Тогда
Возврат Справочники[ОбъектМетаданных.Имя];
ИначеЕсли Родитель = "Документы" Тогда
Возврат Документы[ОбъектМетаданных.Имя];
ИначеЕсли Родитель = "ПланыВидовХарактеристик" Тогда
Возврат ПланыВидовХарактеристик[ОбъектМетаданных.Имя];
КонецЕсли;
Возврат Неопределено;
КонецФункции
Проверка существования объекта и получение самого объекта
После того как ссылка построена, следующий обязательный шаг — убедиться, что объект реально есть в базе. Самый быстрый способ — запрос без обращения к данным объекта:
Запрос = Новый Запрос(
"ВЫБРАТЬ ПЕРВЫЕ 1 ИСТИНА
|ИЗ Документ.РеализацияТоваровУслуг КАК Т
|ГДЕ Т.Ссылка = &Ссылка");
Запрос.УстановитьПараметр("Ссылка", НайденнаяСсылка);
ОбъектСуществует = Не Запрос.Выполнить().Пустой();
Если запрос вернул результат — можно безопасно вызывать НайденнаяСсылка.ПолучитьОбъект() и работать с данными: читать реквизиты, изменять, записывать. Если объект не найден, корректное поведение — вернуть вызывающему коду Неопределено или сообщение об ошибке, а не пытаться создавать объект с чужим УИД без явной необходимости.
Отдельный случай — помеченные на удаление объекты. Запрос выше их находит, и это нормально: пометка удаления не делает объект несуществующим. Но если ваша логика не должна работать с помеченными, добавьте в запрос условие НЕ Т.ПометкаУдаления.
- 1Извлеките из навигационной ссылки полное имя метаданных и УИД после параметра ref=
- 2Постройте значение УникальныйИдентификатор из шестнадцатеричной строки
- 3Найдите объект метаданных через Метаданные.НайтиПоПолномуИмени и получите его менеджер
- 4Создайте ссылку вызовом Менеджер.ПолучитьСсылку(УИД)
- 5Проверьте существование объекта простым запросом по ссылке
- 6Вызовите ПолучитьОбъект() только после успешной проверки
Альтернативные способы и когда их применять
Ручной разбор строки — не единственный вариант. В зависимости от ситуации удобнее другие механизмы платформы.
Если навигационная ссылка приходит от пользователя внутри того же клиентского приложения (например, из письма или мессенджера), проще всего не разбирать её в коде, а использовать обработчик ОбработкаПереходаПоНавигационнойСсылке в модуле управляемого приложения или глобальный поиск по строке. Платформа сама сопоставит ссылку с объектом и откроет форму.
Для интеграций через HTTP-сервисы надёжнее передавать не готовую навигационную ссылку, а пару «тип объекта + УИД» отдельными параметрами. Это избавляет принимающую сторону от парсинга строки и от проблем с экранированием русских имён метаданных в URL. Если же внешняя система уже хранит навигационные ссылки, разбор по схеме выше остаётся единственным вариантом.
Ещё одна альтернатива — поиск по строковому представлению УИД через ПолучитьСсылку без разбора имени метаданных, когда тип объекта известен заранее из контекста задачи. Это самый короткий и быстрый код, но он не универсален.
Сравнение вариантов
Универсален, работает с любой ссылкой e1cib/data. Требует аккуратного парсинга и преобразования УИД.
Лучший вариант для своих интеграций: без парсинга и ошибок экранирования. Не подходит, если формат ссылки задан внешней системой.
Подходит для открытия формы пользователю, но не даёт программного доступа к объекту в серверном коде.
Типичные ошибки и ограничения
Первая ошибка — попытка использовать ЗначениеИзСтрокиВнутр или поиск по представлению вместо разбора УИД. Навигационная ссылка не является внутренним представлением значения, и эти механизмы к ней неприменимы.
Вторая ошибка — игнорирование регистра и кодировки имени метаданных. В ссылках, прошедших через браузер или письмо, русские буквы в имени объекта могут быть закодированы в percent-encoding (например, %D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82). Перед разбором такую строку нужно раскодировать, иначе Метаданные.НайтиПоПолномуИмени вернёт Неопределено.
Третья группа проблем связана с правами и разделением данных. Пользователь, под чьей сессией выполняется код, может не иметь прав на чтение объекта — запрос вернёт пустой результат, хотя объект существует. В разделённых базах объект может находиться в другой области данных и быть недоступен в принципе. Оба случая внешне выглядят как «объект не найден», поэтому в интеграционном коде полезно логировать и сам факт неуспешного поиска, и контекст пользователя.
Как проверить, что всё сработало правильно
Критерий корректной реализации простой: цикл «ссылка → навигационная ссылка → обратно ссылка» должен давать исходное значение. Возьмите реальный объект, получите для него навигационную ссылку через ПолучитьНавигационнуюСсылку, прогоните её через свою функцию разбора и сравните результат с исходной ссылкой оператором равенства. Совпадение означает, что и парсинг, и преобразование УИД написаны верно.
Дополнительно проверьте граничные случаи: ссылку на несуществующий УИД (функция должна вернуть Неопределено, а не упасть с ошибкой), ссылку на объект другого вида метаданных и строку, вообще не являющуюся навигационной ссылкой. Устойчивость к «мусорным» входным данным критична, если строки приходят извне.
Как проверить результат
ПолучитьНавигационнуюСсылку(Результат) совпадает с исходной строкой
Ссылки различаются — ошибка в преобразовании УИД или имени метаданных
Запрос по ссылке возвращает строку, ПолучитьОбъект() даёт объект
ПолучитьОбъект() возвращает Неопределено — объекта нет или нет прав
Функция возвращает Неопределено без исключения
Ошибка времени выполнения на пустой или битой строке
Что важно запомнить
Навигационная ссылка — это строка с именем метаданных и УИД объекта. Объект получают в три шага: разбор строки, построение ссылки через Менеджер.ПолучитьСсылку(УИД), проверка существования запросом. Только после проверки вызывайте ПолучитьОбъект().
Частые вопросы
Можно ли получить объект по навигационной ссылке одной встроенной функцией?
Нет, в платформе нет штатной функции «объект по навигационной ссылке». Есть обратная — ПолучитьНавигационнуюСсылку(). Прямая задача решается разбором строки и построением ссылки через менеджер вида объекта.
Почему ПолучитьСсылку по УИД возвращает ссылку, а ПолучитьОбъект — Неопределено?
Метод ПолучитьСсылку только конструирует значение ссылки из идентификатора и не обращается к базе. Если объекта с таким УИД нет (или нет прав на его чтение), ПолучитьОбъект вернёт Неопределено. Проверяйте существование запросом заранее.
Как открыть форму объекта, если известна только навигационная ссылка?
Если код выполняется в клиентском приложении, используйте метод ПерейтиПоНавигационнойСсылке() — платформа сама откроет нужную форму. Программный разбор строки при этом не требуется.
Работает ли разбор ссылки для записей регистров сведений?
Частично. Ссылки на регистры сведений содержат ключ записи в более сложном формате, чем одиночный ref. Для них надёжнее передавать значения измерений отдельно и строить ключ записи программно.
Опасно ли создавать объект с УИД из чужой навигационной ссылки?
Да. Метод ПолучитьСсылку позволяет записать в базу ссылку на несуществующий объект, что приводит к битым ссылкам в реквизитах и ошибкам при обмене. Создавайте новые объекты с заданным УИД только осознанно, например при синхронизации данных между базами.
Что делать, если имя метаданных в ссылке закодировано символами %D0%?
Это percent-encoding русских букв — строка прошла через браузер, письмо или HTTP. Перед разбором раскодируйте её (например, через РаскодироватьСтроку с параметром СпособКодированияСтроки.КодировкаURL), иначе поиск метаданных по имени завершится неудачей.