Навигационная ссылка на элемент справочника из клиентского кода 1С
Содержание
Ссылку на элемент справочника в 1С получают функцией ПолучитьНавигационнуюСсылку(Ссылка). В тонком и веб-клиенте она не вызывается напрямую из клиентского кода, поэтому её оборачивают в серверную функцию с директивой &НаСервереБезКонтекста и возвращают на клиент готовую строку вида e1cib/data/Справочник.Номенклатура?ref=....
Если пользователю нужна ссылка без программирования, её даёт сам интерфейс: в заголовке открытой формы элемента есть значок-цепочка «Получить ссылку». Код нужен, когда ссылку надо вставить в письмо, отчёт, комментарий или передать во внешнюю систему автоматически. Всё ниже относится к платформе 8.3 и управляемому приложению, конфигурация значения не имеет.
Как устроена навигационная ссылка 1С
Навигационная ссылка — это текстовый адрес объекта внутри информационной базы. По нему платформа понимает, что открыть: элемент, список, отчёт или обработку.
Основные виды адресов:
| Что открывает | Пример строки |
|---|---|
| Элемент справочника | e1cib/data/Справочник.Контрагенты?ref=8a3b000c29e8a1b711ee4f2c1d6a7b90 |
| Список справочника | e1cib/list/Справочник.Контрагенты |
| Обработку или отчёт | e1cib/app/Обработка.ЗагрузкаДанных |
| Команду | e1cib/command/... |
Такая строка — относительная: она работает только внутри уже запущенного сеанса той же базы. Чтобы ссылку можно было открыть из почты или мессенджера, к ней приклеивают адрес базы. Его возвращает ПолучитьНавигационнуюСсылкуИнформационнойБазы():
- 🖥 для файловой и клиент-серверной базы — строка с префиксом
e1c://; - 🌐 для веб-публикации — адрес вида
https://сервер/имя_публикации.
Полная ссылка собирается так: адрес базы + # + относительная ссылка.
Значение после ref= — это уникальный идентификатор элемента, записанный 32 шестнадцатеричными символами без дефисов и с переставленными блоками. Поэтому оно не совпадает «в лоб» с тем, что возвращает Ссылка.УникальныйИдентификатор().
Получение ссылки на справочник в программном коде
Сам метод простой. Синтаксис: ПолучитьНавигационнуюСсылку(<Значение>, <ИмяРеквизита>).
- Значение — ссылка на элемент справочника, документа или другого ссылочного объекта.
- ИмяРеквизита — необязательный параметр. Если указать имя реквизита типа
ХранилищеЗначения, получится адрес содержимого этого реквизита. Так, например, выводят картинку товара в поле формы.
Минимальный рабочий пример на сервере:
&НаСервере
Процедура ПоказатьСсылкуНаСервере()
Элемент = Справочники.Номенклатура.НайтиПоКоду("00-00000015");
Если Элемент.Пустая() Тогда
Возврат;
КонецЕсли;
Адрес = ПолучитьНавигационнуюСсылку(Элемент);
Сообщить(Адрес);
КонецПроцедуры
На выходе будет строка e1cib/data/Справочник.Номенклатура?ref=.... Обратите внимание на проверку Пустая(): если элемент не найден, НайтиПоКоду вернёт пустую ссылку, и адрес на неё бесполезен.
Полная ссылка для отправки за пределы 1С
&НаСервереБезКонтекста
Функция ПолнаяСсылкаНаЭлемент(Ссылка)
Возврат ПолучитьНавигационнуюСсылкуИнформационнойБазы()
+ "#" + ПолучитьНавигационнуюСсылку(Ссылка);
КонецФункции
Такую строку можно вставить в письмо. Получатель, у которого установлена 1С и есть доступ к базе, откроет элемент сразу в нужной форме.
Тонкий, веб- и толстый клиент: где можно вызывать метод
Здесь и кроется суть вопроса «на клиенте». Доступность метода различается по режимам запуска.
| Клиент | ПолучитьНавигационнуюСсылку | Как получить ссылку |
|---|---|---|
| Тонкий клиент | недоступна в клиентском коде | вызов сервера |
| Веб-клиент | недоступна в клиентском коде | вызов сервера |
| Толстый клиент (управляемое приложение) | доступна | можно напрямую, но лучше тоже через сервер |
| Сервер, внешнее соединение | доступна | напрямую |
Если написать вызов в процедуре с директивой &НаКлиенте, тонкий клиент выдаст ошибку о том, что метод недоступен на клиенте. Причём в толстом клиенте тот же код отработает, и ошибка всплывёт только у пользователей тонкого или веб-клиента. Это частая ловушка при тестировании.
Не полагайтесь на то, что код работает у разработчика в толстом клиенте: проверяйте в тонком.
Особенность веб-клиента
В веб-клиенте полная ссылка — это обычный адрес страницы браузера. При открытии карточки элемента в адресной строке появляется хвост #e1cib/data/.... Такой адрес можно скопировать прямо из браузера и отправить коллеге: он откроет его в своём браузере после входа в публикацию. Для писем из кода собирайте ту же строку функцией с ПолучитьНавигационнуюСсылкуИнформационнойБазы(), а не вписывайте адрес сервера константой: при переезде публикации константа устареет.
Правильная схема для формы элемента
В форме элемента справочника ссылка лежит в Объект.Ссылка. Передаём её на сервер без контекста формы — так вызов лёгкий, форма не гоняется по сети целиком.
&НаКлиенте
Процедура ПолучитьСсылку(Команда)
Если Не ЗначениеЗаполнено(Объект.Ссылка) Тогда
ПоказатьПредупреждение(, "Сначала запишите элемент справочника.");
Возврат;
КонецЕсли;
ТекстСсылки = НавигационнаяСсылкаНаСервере(Объект.Ссылка);
КонецПроцедуры
&НаСервереБезКонтекста
Функция НавигационнаяСсылкаНаСервере(Ссылка)
Возврат ПолучитьНавигационнуюСсылку(Ссылка);
КонецФункции
Здесь ТекстСсылки — строковый реквизит формы, выведенный в поле. Пользователь выделяет текст и копирует его. У нового, ещё не записанного элемента ссылки нет, поэтому сначала проверка.
Схема для формы списка
В списке справочника ссылку берут из текущей строки динамического списка:
&НаКлиенте
Процедура СсылкаНаТекущий(Команда)
ТекущиеДанные = Элементы.Список.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
ТекстСсылки = НавигационнаяСсылкаНаСервере(ТекущиеДанные.Ссылка);
КонецПроцедуры
Серверная функция та же, что и в форме элемента. Если в списке включён множественный выбор, перебирайте Элементы.Список.ВыделенныеСтроки и передавайте на сервер массив ссылок одним вызовом, а не по одному.
Не вызывайте сервер в цикле по выделенным строкам. При 200 выделенных элементах это 200 обращений к серверу, и в веб-клиенте пользователь заметит задержку.
Ссылки в отчётах, печатных формах и надписях
Ссылка на справочник нужна не только в коде. Чаще всего её выводят туда, где по ней можно щёлкнуть.
Отчёты на СКД
В отчёте на системе компоновки данных поле ссылочного типа уже работает как переход: двойной щелчок открывает элемент справочника. Отдельно получать навигационную ссылку не нужно.
Табличный документ, собранный кодом
В печатной форме или отчёте, который формируется программно, ссылку кладут в расшифровку области:
Область = Макет.ПолучитьОбласть("Строка");
Область.Параметры.Наименование = Выборка.Наименование;
Область.Параметры.Расшифровка = Выборка.Ссылка;
ТабДок.Вывести(Область);
Чтобы это работало, у ячейки в макете в свойствах должен быть указан параметр расшифровки. Пользователь щёлкает по ячейке — открывается карточка.
Если табличный документ уйдёт в PDF или Excel, расшифровка пропадёт. В этом случае выводите в ячейку текст полной ссылки, собранной функцией ПолнаяСсылкаНаЭлемент.
Надпись-гиперссылка в форме
Для надписи на форме удобна форматированная строка. Пятый параметр конструктора — навигационная ссылка:
&НаСервере
Процедура ЗаполнитьНадпись(Контрагент)
Адрес = ПолучитьНавигационнуюСсылку(Контрагент);
Элементы.НадписьКонтрагент.Заголовок =
Новый ФорматированнаяСтрока(Строка(Контрагент), , , , Адрес);
КонецПроцедуры
По щелчку платформа сама откроет элемент. Если нужно своё поведение, используйте у надписи событие ОбработкаНавигационнойСсылки и в нём отключайте стандартную обработку.
Как открыть справочник по полученной ссылке и проверить её
Обратная задача — открыть элемент по строке. На клиенте для этого есть ПерейтиПоНавигационнойСсылке(Адрес). Метод доступен и в тонком, и в веб-клиенте, вызов сервера не нужен.
Поведение зависит от строки:
- 🔗
e1cib/...— откроется объект в текущем сеансе; - 🌐
http://илиhttps://— откроется браузер; - ❌ мусор или чужая база — исключение.
Поэтому строку, пришедшую от пользователя или из внешней системы, проверяйте:
&НаКлиенте
Процедура ОткрытьПоСсылке(Адрес)
Если Не СтрНачинаетсяС(НРег(СокрЛП(Адрес)), "e1cib/") Тогда
ПоказатьПредупреждение(, "Строка не похожа на навигационную ссылку 1С.");
Возврат;
КонецЕсли;
Попытка
ПерейтиПоНавигационнойСсылке(СокрЛП(Адрес));
Исключение
ПоказатьПредупреждение(, "Не удалось открыть ссылку: "
+ КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры
Если в строке полный адрес с #, перед проверкой отрежьте всё до решётки: Сред(Адрес, СтрНайти(Адрес, "#") + 1).
Из каких ситуаций ссылка «не открывается»
Проверка ссылки на сервере
Иногда ссылку надо не открыть, а превратить обратно в элемент справочника, например при обработке входящего запроса через HTTP-сервис. Платформенной функции «строка → ссылка» нет. Применяют разбор идентификатора: 32 символа после ref= переставляют в формат GUID.
&НаСервереБезКонтекста
Функция ЭлементПоНавигационнойСсылке(Адрес, ИмяСправочника)
Позиция = СтрНайти(Адрес, "ref=");
Если Позиция = 0 Тогда
Возврат Неопределено;
КонецЕсли;
Ид = Сред(Адрес, Позиция + 4, 32);
Если СтрДлина(Ид) <> 32 Тогда
Возврат Неопределено;
КонецЕсли;
Гуид = Сред(Ид, 25, 8) + "-" + Сред(Ид, 21, 4) + "-"
+ Сред(Ид, 17, 4) + "-" + Сред(Ид, 1, 4) + "-" + Сред(Ид, 5, 12);
Попытка
Элемент = Справочники[ИмяСправочника].ПолучитьСсылку(
Новый УникальныйИдентификатор(Гуид));
Исключение
Возврат Неопределено;
КонецПопытки;
Запрос = Новый Запрос("ВЫБРАТЬ ПЕРВЫЕ 1 Т.Ссылка ИЗ Справочник."
+ ИмяСправочника + " КАК Т ГДЕ Т.Ссылка = &Ссылка");
Запрос.УстановитьПараметр("Ссылка", Элемент);
Если Запрос.Выполнить().Пустой() Тогда
Возврат Неопределено;
КонецЕсли;
Возврат Элемент;
КонецФункции
Запрос в конце обязателен. ПолучитьСсылку вернёт ссылку на любой GUID, даже несуществующий, и без проверки вы получите «битую» ссылку <Объект не найден>.
ИмяСправочника подставляется в текст запроса. Если оно приходит извне, сначала сверяйте его с Метаданные.Справочники.Найти(ИмяСправочника), иначе это дыра для подстановки чужого текста запроса.
Другие способы открыть справочник без навигационной ссылки
Навигационная ссылка — не единственный путь к форме. Внутри одного сеанса чаще удобнее открывать объект напрямую.
| Задача | Метод на клиенте | Когда выбирать |
|---|---|---|
| Открыть карточку элемента | ПоказатьЗначение(, Ссылка) | есть ссылка, нужна основная форма |
| Открыть конкретную форму элемента | ОткрытьФорму("Справочник.Номенклатура.ФормаОбъекта", Новый Структура("Ключ", Ссылка)) | нужна не основная форма или параметры |
| Открыть список | ОткрытьФорму("Справочник.Номенклатура.ФормаСписка") | показать весь справочник |
| Открыть по строке-адресу | ПерейтиПоНавигационнойСсылке(Адрес) | ссылка пришла текстом |
Ссылку на элемент передавать между формами можно напрямую: значение типа СправочникСсылка спокойно живёт на клиенте. Навигационная строка нужна только там, где объект должен «пережить» выход из сеанса: письмо, задача в трекере, комментарий, внешний сервис.
Для пользователей есть ручной путь. Скопированную через значок-цепочку ссылку другой сотрудник открывает в главном меню командой «Перейти по ссылке» и вставляет строку в поле.
Где это пригодится в рабочих конфигурациях
Несколько сценариев, ради которых ссылку на справочник получают кодом.
- Письмо ответственному. Регламентное задание находит контрагентов с незаполненным ИНН и рассылает менеджерам список полных ссылок. Менеджер щёлкает — открывается карточка.
- Интеграция с таск-трекером. При создании задачи во внешней системе в описание пишется полная ссылка на элемент номенклатуры. Сотрудник переходит из трекера прямо в 1С.
- Комментарий в документе. В поле комментария сохраняют ссылку на связанный элемент справочника. Из строки её открывают кнопкой через
ПерейтиПоНавигационнойСсылке. - Картинка товара в форме.
ПолучитьНавигационнуюСсылку(Товар, "Картинка")для реквизита-хранилища даёт адрес, который подставляют в поле картинки. Файл не выгружается на диск. - Отчёт для руководителя в Excel. Вместо расшифровки, которая теряется при сохранении, в колонку выводится полная ссылка. Её можно открыть, если на компьютере установлена 1С.
В типовых конфигурациях на БСП для открытия адреса есть готовая процедура ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку. Она сама разбирается с разными видами адресов, поэтому в доработках типовых удобнее вызывать её, а не писать обработку заново.
Частые вопросы
Будет ли ссылка работать после переноса базы на другой сервер?
e1cib/data/...?ref=... останется прежней: идентификатор элемента не меняется при выгрузке и загрузке базы. Изменится адрес базы, поэтому старые полные ссылки придётся пересобрать.