Ссылка на объект 1С: свойство Ссылка, GUID и навигационный URL

· 9 мин

Содержание

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

Ниже — как получить каждую из них: из объекта, из идентификатора, из интерфейса и в запросе. Для встроенного языка используется типовой синтаксис платформы 8.3.

От объекта к ссылке и обратно

У любого объекта (СправочникОбъект, ДокументОбъект) есть свойство Ссылка. Оно возвращает ссылку на этот же объект в базе:

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

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

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

Разница принципиальная. Ссылка — это лёгкий указатель, он не читает все реквизиты из базы и не блокирует запись. Объект — «тяжёлый», его читают целиком и только когда нужно что-то изменить и записать.

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

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

Ссылка на объект открытой формы и выделенные строки списка

Частый вопрос — как получить ссылку прямо из открытой формы, без поиска объекта в коде.

На форме объекта (элемента справочника, документа) данные лежат в реквизите Объект, и ссылка доступна так же через точку:

ТекущаяСсылка = Объект.Ссылка;

У нового, ещё не записанного объекта ссылка пустая — реальный идентификатор платформа присваивает только при первой записи. Поэтому в обработчике ПриСозданииНаСервере для нового объекта Объект.Ссылка вернёт пустую ссылку; получать её имеет смысл после Записать().

На форме списка ссылку текущей и выделенных строк берут у элемента формы. Для динамического списка текущая строка — это и есть ссылка:

ТекущаяСсылка = Элементы.Список.ТекущаяСтрока;
Выделенные = Элементы.Список.ВыделенныеСтроки; // массив ссылок

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

Ссылка как уникальный идентификатор (GUID)

Внутри каждой ссылки лежит УникальныйИдентификатор — 128-битный GUID, постоянный на всё время жизни объекта. Именно он нужен, когда ссылку передают во внешнюю систему, в URL или в лог.

Ид = Ссылка.УникальныйИдентификатор();
СтрокаИд = Строка(Ид); // "a1b2c3d4-0000-0000-0000-9f8e7d6c5b4a"

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

Ид = Новый УникальныйИдентификатор("a1b2c3d4-0000-0000-0000-9f8e7d6c5b4a");
Ссылка = Справочники.Номенклатура.ПолучитьСсылку(Ид);

Метод ПолучитьСсылку есть у менеджеров справочников, документов, планов видов характеристик, планов счетов и других ссылочных типов.

ПолучитьСсылку не проверяет, существует ли объект в базе. Он просто собирает ссылку из идентификатора. Если объект с таким GUID удалён или никогда не существовал, вы получите рабочую с виду, но «битую» ссылку. Проверять существование нужно отдельно — об этом в разделе про пустые и несуществующие ссылки.

Строковое представление GUID всегда одной длины — 36 символов: 32 шестнадцатеричные цифры и 4 дефиса, например a1b2c3d4-0000-0000-0000-9f8e7d6c5b4a. На это удобно опираться при валидации: если во внешней системе пришла строка другой длины или с посторонними символами, это точно не идентификатор объекта 1С.

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

Навигационная ссылка и URL для веб-клиента

Навигационная ссылка — это внутренний адрес объекта в формате e1cib/data/.... Её получают функцией ПолучитьURL:

НавСсылка = ПолучитьURL(Ссылка);
// e1cib/data/Справочник.Номенклатура?ref=a1b2c3d400000000...

Такую строку можно:

  • 📌 вставить гиперссылкой в поле формы, в примечание, в письмо пользователю внутри системы;
  • 📌 открыть программно на клиенте командой ПерейтиПоНавигационнойСсылке(НавСсылка);
  • 📌 отдать в тонкий или веб-клиент — платформа откроет форму нужного объекта.

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

АдресФайла = ПолучитьURL(Ссылка, "Скан");

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

Навигационную ссылку можно построить не только на объект, но и на список: тогда переход откроет форму списка. Это удобно, когда пользователя нужно направить не в конкретную карточку, а в отфильтрованный журнал документов .

Полный адрес для веб-клиента

Строка e1cib/data/... — это относительный адрес внутри базы. Чтобы получить ссылку, которую можно отправить коллеге в мессенджере, к ней добавляют адрес публикации базы:

https://server.company.ru/buh/#e1cib/data/Справочник.Номенклатура?ref=a1b2c3d4...

Обратите внимание на решётку # перед e1cib — в веб-клиенте навигационная часть идёт после неё. Если базу публикуют под другим именем, меняется только начало адреса; хвост e1cib/data/... остаётся прежним. Адрес публикации у вас фиксирован в настройках веб-сервера, его не нужно вычислять в коде — достаточно подставить известную строку.

Как скопировать ссылку на объект в режиме предприятия

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

Она лежит в главном меню приложения — это кнопка в левом верхнем углу окна (в интерфейсе «Такси» — со значком меню). В выпадающем меню есть команда получения ссылки на активное окно; платформа покажет готовую строку, её останется скопировать.

Полученную строку коллега вставляет в адрес своего клиента (или открывает командой перехода по ссылке) и попадает ровно в ту же карточку. Это работает для форм объектов, списков и отчётов — везде, где есть активное окно.

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

Если команды в меню нет, её могла скрыть настройка интерфейса в конкретной конфигурации. Тогда ссылку получают программно через ПолучитьURL в обработке или консоли, как показано выше.

Ссылки в запросах и консоли запросов

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

Выбрать ссылку и представление объекта:

ВЫБРАТЬ
    Товары.Ссылка КАК Ссылка,
    ПРЕДСТАВЛЕНИЕ(Товары.Ссылка) КАК Наименование
ИЗ
    Справочник.Номенклатура КАК Товары

Отобрать по списку ссылок, переданному параметром:

ВЫБРАТЬ
    Товары.Ссылка
ИЗ
    Справочник.Номенклатура КАК Товары
ГДЕ
    Товары.Ссылка В (&СписокСсылок)

Параметр СписокСсылок заполняют в коде массивом или списком значений, элементы которого — ссылки. Из результата запроса ссылку достают так же через точку: Выборка.Ссылка.

Литерал ссылки прямо в тексте запроса

Когда нужна конкретная предопределённая ссылка или пустая ссылка, используют функцию ЗНАЧЕНИЕ:

ГДЕ
    Товары.ВидНоменклатуры = ЗНАЧЕНИЕ(Справочник.ВидыНоменклатуры.Услуга)
    И Товары.Ссылка <> ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)

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

Консоль запросов

Консоль запросов — это внешняя обработка, а не часть платформы. В ней текст запроса пишут так же, а ссылочные параметры подбирают в диалоге подбора значений. Чтобы получить ссылку на объект из результата, достаточно выбрать в запросе поле Ссылка: в таблице результата её можно открыть двойным кликом и, через главное меню окна, получить навигационную ссылку .

Одинаковы ли ссылки в файловой и серверной базе

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

Различается только одно — полный адрес для веб-клиента:

Что получаемФайловая базаКлиент-серверная
Свойство Ссылка, GUIDОдинаковоОдинаково
Навигационная строка e1cib/data/...ОдинаковоОдинаково
Полный URL для веб-клиентаЗависит от публикации файловой базыАдрес сервера публикации

Поэтому код получения ссылки переносить между базами не нужно. Жёстко прописывать в коде начало URL (https://...) не стоит — при переносе базы адрес публикации меняется, и ссылки перестанут открываться. Храните навигационную часть, а адрес публикации подставляйте из настройки.

Пустая ссылка и обработка несуществующих объектов

Пустая ссылка — это ссылка «ни на что»: незаполненное значение ссылочного реквизита. Получить её и проверить можно двумя способами:

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

Если Ссылка.Пустая() Тогда
    Сообщить("Номенклатура не выбрана");
КонецЕсли;

Метод Пустая() возвращает Истина для незаполненной ссылки. В запросе ту же проверку делают через ЗНАЧЕНИЕ(...ПустаяСсылка), как показано выше.

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

Объект = Ссылка.ПолучитьОбъект();
Если Объект = Неопределено Тогда
    // объект удалён или никогда не существовал
    Возврат;
КонецЕсли;

Всегда проверяйте результат ПолучитьОбъект() на Неопределено, прежде чем обращаться к реквизитам — иначе получите ошибку «Значение не является значением объектного типа ».

Как найти битые ссылки в базе

Если в базе уже накопились ссылки на удалённые объекты, их ищут штатными средствами, а не перебором в коде:

  • 🔧 Удаление помеченных объектов — перед удалением платформа сама проверяет, нет ли ссылок на объект, и не даёт удалить то, на что ещё ссылаются.
  • 🔧 Поиск и удаление дублей / поиск ссылок на объект — показывает, где используется конкретный объект.
  • 🔧 Тестирование и исправление в конфигураторе (режим проверки логической целостности) — находит и помечает ссылки на несуществующие объекты.
Какая ссылка на объект вам нужна?

Частые вопросы

Чем ссылка отличается от объекта?
Ссылка — лёгкий указатель на объект в базе, им оперируют в коде и запросах. Объект получают методом ПолучитьОбъект() только для изменения и записи: он читается из базы целиком и может блокировать запись.
Как из строки с GUID снова получить ссылку?
Создайте идентификатор Новый УникальныйИдентификатор(СтрокаGUID) и передайте его в ПолучитьСсылку нужного менеджера, например Справочники.Контрагенты.ПолучитьСсылку(Ид). Существование объекта метод не проверяет.
Почему ссылка есть, а объект не открывается?
Скорее всего, объект удалён, а ссылка на него осталась (битая ссылка). ПолучитьОбъект() в этом случае вернёт Неопределено. Такие ссылки ищут через тестирование и исправление или поиск ссылок на объект.
Можно ли отправить ссылку коллеге в мессенджере?
Да, если к навигационной строке e1cib/data/... добавить адрес публикации базы в веб-клиенте (с решёткой # перед e1cib). Коллега откроет ту же карточку, если у него есть доступ к этой базе и права на объект.
Меняется ли GUID объекта при выгрузке и загрузке базы?
Нет. Идентификатор постоянен и сохраняется при выгрузке/загрузке .dt и при переносе между файловым и серверным режимом. Меняется только полный адрес публикации для веб-клиента.