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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки часто возникает задача получить не просто ссылку на объект (как внутренний идентификатор), а именно строковую навигационную ссылку вида e1cib/data/Справочник.Партнеры?ref=80da0cc47a6c412011e6d1853fb92181. Такая ссылка полезна для передачи во внешние системы, вставки в электронные письма или использования в интерфейсе для быстрого перехода к объекту.

Однако при попытке решить эту задачу "в лоб" с помощью написания запросов в 1С разработчики сталкиваются с рядом платформенных ограничений. В этой статье мы подробно разберем, почему это сложно сделать одним запросом, и рассмотрим эффективные способы обхода этих ограничений.

Анализ ограничений языка запросов

Проанализируем ситуацию, чтобы не допускать ошибок при вызове функций: навигационная ссылка состоит из текстового префикса, имени метаданных и уникального идентификатора (UUID). Казалось бы, достаточно просто "склеить" эти части. Но здесь нас поджидают три основные проблемы:

  1. Типизация UUID: Начиная с версии платформы 8.3.22, в языке запросов появилась функция УникальныйИдентификатор(Ссылка). Но она возвращает значение специального типа УникальныйИдентификатор, а не строку. В языке запросов 1С нельзя принудительно привести UUID к строке, что подтверждает любой анализатор кода проектов (функция ВЫРАЗИТЬ не поддерживает тип СТРОКА для идентификаторов).
  2. Отсутствие функций манипуляции строками: Стандартный UUID содержит дефисы (например, 550e8400-e29b-41d4-a716-446655440000), в то время как в навигационной ссылке после параметра ref= должен идти 32-символьный код без дефисов. В языке запросов нет функции СтрЗаменить(), поэтому часто используется вспомогательный код 1С для получения ссылки по GUID для очистки строки.
  3. Имя метаданных: В запросе невозможно динамически получить строковое представление типа объекта (например, "Справочник.Номенклатура").

Рассмотрим подробнее доступные решения этой задачи.

Способ 1. Использование вычисляемых полей в СКД

Если ваша задача связана с выводом данных в отчет или динамический список, Система компоновки данных (СКД) — это самый простой и правильный путь. В отличие от чистого запроса, СКД позволяет использовать функции встроенного языка в вычисляемых полях.

Разберем по шагам, как это настроить:

  1. Перейдем на вкладку "Вычисляемые поля" в схеме компоновки данных.
  2. Добавим новое поле, назовем его НавигационнаяСсылка.
  3. В колонке "Выражение" пропишем стандартную функцию платформы:

ПолучитьНавигационнуюСсылку(Ссылка)

Платформа сама определит тип объекта и сформирует корректную ссылку для каждой строки результата. Это работает максимально эффективно, так как преобразование происходит на этапе формирования результата, а не в момент выполнения запроса к СУБД.

Способ 2. Предварительное хранение ссылки в реквизите

Для высоконагруженных систем, где ссылки нужно получать массово в сложных запросах или динамических списках без использования СКД, оптимальным решением будет материализация ссылки. Проанализируем этот подход: мы один раз вычисляем ссылку при записи объекта и сохраняем её в базе.

Для реализации этого метода выполним следующие действия:

  1. Добавим в нужный объект (например, в справочник Контрагенты) реквизит НавигационнаяСсылка с типом Строка (длина 100-150 символов).
  2. В модуле объекта пропишем обработчик события ПередЗаписью:

Процедура ПередЗаписью(Отказ)
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    
    // Получаем ссылку. Для нового объекта сначала нужно получить ссылку.
    Если ЭтоНовый() Тогда
        УстановитьСсылкуНового(Справочники.Контрагенты.ПолучитьСсылку());
    КонецЕсли;
    
    НавигационнаяСсылка = ПолучитьНавигационнуюСсылку(Ссылка);
КонецПроцедуры

Теперь в любом запросе мы можем просто обратиться к реквизиту НавигационнаяСсылка, что будет работать мгновенно:


ВЫБРАТЬ
    Контрагенты.Наименование КАК Наименование,
    Контрагенты.НавигационнаяСсылка КАК СсылкаТекстом
ИЗ
    Справочник.Контрагенты КАК Контрагенты

Способ 3. Постобработка результата запроса в коде

Если нам нужно получить ссылку "здесь и сейчас" без изменения структуры метаданных, мы используем программную обработку результата запроса. Выясним, как это реализовать наиболее эффективно.

Рассмотрим пример кода:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Партнеры.Ссылка КАК Ссылка
    |ИЗ
    |   Справочник.Партнеры КАК Партнеры";

РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл
    // Формируем ссылку на стороне сервера или клиента
    ТекСсылка = ПолучитьНавигационнуюСсылку(Выборка.Ссылка);
    // Далее используем полученную строку ТекСсылка
КонецЦикла;

Важный нюанс: Функция ПолучитьНавигационнуюСсылку() доступна на клиенте и на сервере. Если вы работаете с большим массивом данных, лучше делать это на сервере, чтобы избежать лишних сетевых вызовов.

Техническая справка: Функция УникальныйИдентификатор в 8.3.22

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

Пример использования в запросе:


ВЫБРАТЬ
    УникальныйИдентификатор(Партнеры.Ссылка) КАК Идентификатор
ИЗ
    Справочник.Партнеры КАК Партнеры

Хотя этот метод возвращает UUID, а не готовую навигационную ссылку, он позволяет выгрузить идентификаторы во временную таблицу, а затем при передаче данных на сторону встроенного языка (например, в ТаблицуЗначений), система автоматически сможет преобразовать их в строковое представление. Однако, как мы выяснили выше, собрать полную строку e1cib/... исключительно средствами SELECT в 1С всё еще невозможно из-за отсутствия функций конкатенации типов, отличных от строки, и отсутствия функций замены символов.

Заключение и рекомендации

Проанализировав все способы, можно сделать следующие выводы:

Помните, что формат ссылки ref=... чувствителен к порядку байтов. В СУБД (SQL Server/PostgreSQL) 1С хранит GUID в бинарном виде со смещением байтов. Поэтому попытки собрать ссылку прямым SQL-запросом к базе данных (через CAST к varchar) приведут к получению неверного идентификатора, который не будет распознан системой 1С как корректная ссылка.

← На главную