Тип ссылки в 1С: как узнать в интерфейсе и программно
Содержание
Тип ссылки в 1С показывает, на какой объект базы она указывает: справочник, документ, перечисление, план счетов
и так далее. Если нужно определить тип прямо сейчас — в режиме «1С:Предприятие» откройте элемент и получите навигационную ссылку: её адрес начинается с e1cib/data/Справочник.Контрагенты, и часть после /data/ — это и есть тип. В коде тип ссылки возвращает функция ТипЗнч.
Способов несколько, и выбор зависит от того, где вы находитесь. Пользователю без доступа к конфигуратору хватит навигационной ссылки. Разработчику удобнее ТипЗнч и Метаданные(). Для отбора записей в отчёте работает оператор ССЫЛКА в запросе. Ниже — каждый способ с примерами и готовым кодом.
/data/.ТипЗнч(Ссылка) и сравнивайте с Тип("..."); имя объекта даст Метаданные().ССЫЛКА в условии или ВЫРАЗИТЬ для приведения.Что такое ссылка и из чего складывается её тип
Ссылка — это указатель на конкретную запись в таблице базы данных. У неё две составляющие: тип (какая это таблица) и уникальный идентификатор (какая именно строка).
Тип ссылки всегда привязан к объекту метаданных. Для справочника «Контрагенты» тип будет СправочникСсылка.Контрагенты, для документа реализации — ДокументСсылка.РеализацияТоваровУслуг. Префикс (СправочникСсылка, ДокументСсылка и т.д.) говорит о виде объекта, а вторая часть — о его имени.
Важная деталь: тип не хранится внутри идентификатора. Он задаётся тем, через какой менеджер объекта вы получили ссылку. Поэтому по «голому» GUID восстановить тип нельзя — об этом ниже.
Отдельно стоит различать два понятия, которые новички путают. Тип значения — это то, чем ссылка является прямо сейчас (например, ДокументСсылка.СчётНаОплату). Допустимые типы реквизита — это набор типов, которые поле в принципе может хранить; у составного реквизита их несколько. Первое отвечает на вопрос «что лежит в переменной», второе — «что туда вообще можно положить». Для каждого из них свой инструмент, и дальше это видно на примерах.
Способ 1. Навигационная ссылка в режиме «1С:Предприятие»
Это единственный надёжный способ для пользователя без конфигуратора.
- Откройте нужный элемент справочника или документ.
- Вызовите главное меню (значок в левом верхнем углу окна).
- Выберите команду
Получить ссылку. - В открывшемся поле будет строка вида
e1cib/data/Справочник.Контрагенты?ref=a1b2c3....
Часть между /data/ и ?ref= — это полное имя объекта: Справочник.Контрагенты. По нему сразу понятно и вид (справочник), и имя (Контрагенты).
Команда Получить ссылку есть почти во всех типовых конфигурациях на управляемых формах (БП 3.0, ЗУП 3.1, УТ 11). Если в вашей форме её нет, попробуйте контекстное меню строки списка — там бывает тот же пункт.
Этот приём работает и для проверки составных реквизитов: открыли документ, перешли по ссылке в поле «Контрагент» — и по адресу видите, справочник это или физлицо.
Навигационная ссылка полезна ещё и тем, что её можно передать коллеге. Он вставит её в поле перехода своей базы (если конфигурации совпадают) и попадёт ровно на тот же объект. При этом тип останется читаемым в самом тексте ссылки — ничего вычислять не нужно.
Способ 2. Функция ТипЗнч в отладчике и консоли запросов
ТипЗнч — основной инструмент разработчика. Она возвращает значение типа Тип, а при выводе строкой показывает полное имя типа ссылки.
ИмяТипа = Строка(ТипЗнч(Ссылка));
// Результат: "СправочникСсылка.Контрагенты"
В отладчике это ещё проще. Остановите выполнение на нужной строке, выделите переменную и нажмите Shift+F9 (вычислить выражение) либо наведите курсор — всплывающая подсказка покажет тип значения.
Если под рукой нет конфигуратора, но есть внешняя обработка «Консоль запросов» или консоль кода, выполните в ней ту же строку — результат увидите в сообщениях.
Ещё один инструмент отладчика — Табло. Добавьте в него выражение ТипЗнч(Ссылка), и при каждой остановке вы будете видеть актуальный тип без лишних вычислений. На вкладке «Локальные» отладчик и так показывает типы всех переменных текущего метода — иногда достаточно просто заглянуть туда.
Сравнивать тип нужно не со строкой, а с результатом функции Тип:
Если ТипЗнч(Ссылка) = Тип("СправочникСсылка.Контрагенты") Тогда
Сообщить("Это контрагент");
КонецЕсли;
Частая ошибка — сравнение ТипЗнч(Ссылка) = "СправочникСсылка.Контрагенты". Такое условие всегда ложно: слева тип, справа строка. Оборачивайте ожидаемый тип в Тип("...").
Способ 3. Метаданные ссылки: имя, полное имя и вид объекта
Когда нужно не просто сравнить, а получить читаемое имя объекта, используйте метод Метаданные(). Он возвращает объект описания метаданных, у которого есть свои свойства.
ПолноеИмя = Ссылка.Метаданные().ПолноеИмя(); // "Справочник.Контрагенты"
Имя = Ссылка.Метаданные().Имя; // "Контрагенты"
Синоним = Ссылка.Метаданные().Синоним; // "Контрагенты" (как в интерфейсе)
Чтобы определить именно вид объекта (справочник, документ, перечисление), проверьте, в какой коллекции метаданных он лежит:
Если Метаданные.Документы.Содержит(Ссылка.Метаданные()) Тогда
Сообщить("Ссылка указывает на документ");
ИначеЕсли Метаданные.Справочники.Содержит(Ссылка.Метаданные()) Тогда
Сообщить("Ссылка указывает на элемент справочника");
КонецЕсли;
Это удобнее разбора строки: не нужно вручную отрезать префикс до точки. Разница между ТипЗнч и Метаданные() простая: первая отвечает на вопрос «какого типа значение», вторая — «как устроен объект, на который оно указывает».
Если же задача обратная — узнать, какие типы вообще разрешены для составного реквизита, — читайте метаданные не ссылки, а самого реквизита:
Реквизит = Метаданные.Документы.РеализацияТоваровУслуг.Реквизиты.Контрагент;
Для Каждого ДопустимыйТип Из Реквизит.Тип.Типы() Цикл
Сообщить(Строка(ДопустимыйТип));
КонецЦикла;
Свойство Тип возвращает описание типов, а метод Типы() — массив всех разрешённых типов. Так вы увидите полный список, даже если в конкретной записи заполнен только один из них.
Этот способ удобен при разборе чужой конфигурации: прежде чем писать проверку ТипЗнч, посмотрите, какие типы вообще может содержать реквизит. Иначе рискуете проверить не все варианты и пропустить часть данных.
Способ 4. Определение типа в языке запросов
В запросе тип ссылки проверяют оператором ССЫЛКА. Он возвращает истину, если значение принадлежит указанному типу. Это основной приём для полей составного типа.
ВЫБРАТЬ
Таблица.Значение КАК Значение,
ВЫБОР
КОГДА Таблица.Значение ССЫЛКА Справочник.Контрагенты
ТОГДА "Контрагент"
КОГДА Таблица.Значение ССЫЛКА Документ.РеализацияТоваровУслуг
ТОГДА "Документ реализации"
ИНАЧЕ "Иной тип"
КОНЕЦ КАК ВидЗначения
ИЗ
РегистрСведений.МойРегистр КАК Таблица
Второй способ в запросе — приведение через ВЫРАЗИТЬ. Если значение не того типа, к которому его приводят, результат будет NULL:
ВЫБРАТЬ
ВЫРАЗИТЬ(Таблица.Значение КАК Справочник.Контрагенты) КАК КакКонтрагент
ИЗ
РегистрСведений.МойРегистр КАК Таблица
Непустое значение в колонке КакКонтрагент означает, что ссылка указывает на контрагента. Этот приём часто применяют, чтобы вытащить реквизиты объекта только для нужного типа, не ломая запрос на остальных. Через точку от ВЫРАЗИТЬ(... КАК Справочник.Контрагенты) можно сразу обращаться к реквизитам контрагента — без приведения такие обращения к составному полю работать не будут.
Оба приёма — ССЫЛКА и ВЫРАЗИТЬ — не зависят от того, существует ли запись в базе. Они опираются только на тип, прописанный в метаданных поля, поэтому подходят и для проверки «битых» ссылок на удалённые объекты.
Оператор ССЫЛКА не читает сам объект из базы — он сравнивает тип по метаданным. Поэтому работает быстро даже на больших выборках.
Способ 5. Можно ли узнать тип по GUID (уникальному идентификатору)
Короткий ответ — по одному идентификатору нельзя. Разберём, почему.
Идентификатор ссылки получают так:
Идентификатор = Ссылка.УникальныйИдентификатор();
ИдентификаторСтрокой = Строка(Идентификатор);
// "a1b2c3d4-0000-0000-0000-000000000000"
В этой строке закодирован только номер строки в таблице. Вид и имя объекта в GUID не хранятся. Чтобы из идентификатора снова получить ссылку, нужно указать менеджер конкретного объекта:
Ид = Новый УникальныйИдентификатор("a1b2c3d4-0000-0000-0000-000000000000");
ВосстановленнаяСсылка = Справочники.Контрагенты.ПолучитьСсылку(Ид);
// Тип — СправочникСсылка.Контрагенты, но только потому,
// что мы взяли менеджер Контрагенты
Тип задаёт менеджер, через который вы получаете ссылку, а не сам GUID. Если бы вы вызвали Документы.РеализацияТоваровУслуг.ПолучитьСсылку(Ид) с тем же идентификатором, получили бы ссылку на документ — метод не проверяет, существует ли такая запись.
Единственная ситуация, когда тип «виден» рядом с идентификатором, — навигационная ссылка (способ 1). Там тип записан текстом перед ?ref=, и его можно просто прочитать.
Эту же навигационную ссылку можно получить и из кода — пригодится, когда нужно записать в лог не только GUID, но и тип:
Адрес = ПолучитьНавигационнуюСсылку(Ссылка);
// "e1cib/data/Справочник.Контрагенты?ref=a1b2c3..."
В отличие от Строка(Ссылка.УникальныйИдентификатор()), здесь тип сохраняется в тексте. Если позже понадобится восстановить объект — из строки сразу понятно, какой менеджер использовать.
Таблица: префиксы типов ссылок и объекты метаданных
Каждому виду объекта соответствует свой префикс типа ссылки. Полное имя объекта метаданных строится по тому же принципу.
| Объект метаданных | Тип ссылки | Пример полного имени |
|---|---|---|
| Справочник | СправочникСсылка.<Имя> | Справочник.Контрагенты |
| Документ | ДокументСсылка.<Имя> | Документ.РеализацияТоваровУслуг |
| Перечисление | ПеречислениеСсылка.<Имя> | Перечисление.СтавкиНДС |
| План счетов | ПланСчетовСсылка.<Имя> | ПланСчетов.Хозрасчетный |
| План видов характеристик | ПланВидовХарактеристикСсылка.<Имя> | ПланВидовХарактеристик.Пользователи |
| План видов расчёта | ПланВидовРасчетаСсылка.<Имя> | ПланВидовРасчета.Начисления |
| Бизнес-процесс | БизнесПроцессСсылка.<Имя> | БизнесПроцесс.Согласование |
| Задача | ЗадачаСсылка.<Имя> | Задача.ЗадачаИсполнителя |
| План обмена | ПланОбменаСсылка.<Имя> | ПланОбмена.ПолныйОбмен |
Зная эту таблицу, по строке Строка(ТипЗнч(Ссылка)) вы без труда разберёте и вид объекта, и его имя.
Обратите внимание на закономерность: тип ссылки — это имя вида с суффиксом Ссылка, а полное имя объекта метаданных — вид без суффикса. Поэтому СправочникСсылка.Контрагенты и Справочник.Контрагенты описывают один и тот же объект, но с разных сторон: первое — тип значения, второе — имя в дереве конфигурации. В коде это соответствие и реализует Метаданные(): берёт тип значения и возвращает полное имя объекта.
У перечислений есть нюанс: их значения — это предопределённые элементы, а не записи, которые можно создавать. Но тип у них такой же полноценный (ПеречислениеСсылка.<Имя>), и ТипЗнч работает с ними ровно так же, как со справочниками.
Частые ошибки при проверке типа ссылки
Ошибки обычно повторяются из проекта в проект.
- 🔴 Сравнение типа со строкой.
ТипЗнч(Ссылка) = "СправочникСсылка.Контрагенты"не сработает. НуженТип("СправочникСсылка.Контрагенты"). - 🔴 Путаница
NULL,Неопределенои пустой ссылки. Пустая ссылка (Справочники.Контрагенты.ПустаяСсылка()) имеет полноценный тип.NULLприходит из запроса, когда связь не найдена.Неопределено— это незаполненный реквизит составного типа. Для всех трёхТипЗнчвернёт разное, и путать их нельзя. - 🔴 Вызов
Метаданные()уНеопределено. Если в составном реквизите пусто, строкаСсылка.Метаданные()вызовет ошибку «Значение не является значением объектного типа ». Сначала проверяйтеЗначениеЗаполнено(Ссылка)илиТипЗнч. - 🔴 Ожидание «составного типа» от значения. В реквизите составного типа всегда лежит конкретное значение.
ТипЗнчвернёт фактический тип (например,ДокументСсылка.СчётНаОплату), а не абстрактный «составной». - 🔴 Разбор префикса строкой вместо
Содержит. Отрезать часть до точки отСтрока(ТипЗнч(...))можно, но при опечатке код молча перестанет узнавать нужный вид. КоллекцииМетаданные.Документы.Содержит(...)иМетаданные.Справочники.Содержит(...)надёжнее. - 🔴 Попытка вычислить тип из GUID. Строка идентификатора не содержит вида объекта. Если в коде осталась только она, тип уже потерян — храните рядом полное имя типа или навигационную ссылку.
Частые вопросы
Чем ТипЗнч отличается от Метаданные()?
ТипЗнч возвращает тип значения (объект класса Тип) — им удобно сравнивать. Метаданные() возвращает описание объекта метаданных с его именем, синонимом, реквизитами. Для сравнения берут ТипЗнч, для получения имени — Метаданные().Как в запросе проверить, что составное поле заполнено ссылкой на документ?
ССЫЛКА: ГДЕ Поле ССЫЛКА Документ.РеализацияТоваровУслуг. Или перечислите нужные типы в конструкции ВЫБОР КОГДА ... ССЫЛКА ....Можно ли определить тип несуществующей (удалённой) ссылки?
Почему ТипЗнч у пустой ссылки возвращает тип, а не Неопределено?
Справочники.Контрагенты.ПустаяСсылка() — это значение типа СправочникСсылка.Контрагенты. Пустой её делает нулевой идентификатор, но тип остаётся.Как узнать тип, если под рукой нет конфигуратора?
Строка(ТипЗнч(Ссылка)) во внешней обработке-консоли.