К статье
Практический материал

Разработка и Конфигурация · 13 мин

Как получить тип СправочникСсылка в 1С

Как получить тип СправочникСсылка в 1С: Тип(), ТипЗнч(), Справочники.ТипВсеСсылки(), проверка типа ссылки в запросе и на форме. Примеры кода и частые ошибки.

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

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

Ниже разобраны все основные способы: функции Тип() и ТипЗнч(), свойство МенеджерСправочника.ТипВсеСсылки(), оператор запроса ССЫЛКА и работа с метаданными. Примеры кода применимы на платформе 8.3 как в толстом, так и в тонком клиенте, с учётом ограничений контекста сервера и клиента.

Что такое тип СправочникСсылка и зачем его получать

В 1С каждый объект базы данных имеет ссылку — уникальный идентификатор, по которому система находит запись. Для справочников ссылка имеет тип вида СправочникСсылка.<ИмяСправочника>, например СправочникСсылка.Контрагенты. Это не строка и не число, а отдельный тип данных платформы.

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

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

Получение типа через Тип() и ТипЗнч()

Функция ТипЗнч(Значение) возвращает тип конкретного значения, хранящегося в переменной. Это основной способ узнать, что именно передано в процедуру:

Процедура ОбработатьЗначение(ВходноеЗначение)

Если ТипЗнч(ВходноеЗначение) = Тип("СправочникСсылка.Номенклатура") Тогда

// это ссылка на номенклатуру

Сообщить("Получена номенклатура: " + ВходноеЗначение);

КонецЕсли;

КонецПроцедуры

Функция Тип("СправочникСсылка.Номенклатура") создаёт объект типа «Тип» по строковому имени. Имя строится по шаблону: СправочникСсылка, точка, имя справочника как оно задано в конфигураторе. Ошибка в имени вызовет исключение времени выполнения, поэтому при динамическом формировании строки имя стоит брать из метаданных, а не вводить вручную.

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

Проверка без привязки к виду справочника

Если Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)) Тогда

// значение — ссылка на какой-либо справочник

КонецЕсли;

Получение описания типа через менеджер справочника

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

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

// ОписаниеТипов, содержащее СправочникСсылка.Номенклатура

ТипНоменклатуры = ОписаниеТипаНоменклатура.Типы()[0];

// сам объект Тип

Такое описание типов нужно, когда требуется не просто проверка, а конструирование: ограничение типа колонки таблицы значений, настройка параметра динамического списка, приведение значения через ПривестиЗначение().

ТаблицаЗначений = Новый ТаблицаЗначений;

ТаблицаЗначений.Колонки.Добавить("Товар",

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

Аналогично работает Справочники.ТипВсеСсылки() без указания вида — возвращается описание, включающее ссылочные типы всех справочников конфигурации. Это удобно для колонок «любая ссылка на справочник» и универсальных обработок.

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

Проверка типа ссылки в запросе

В языке запросов тип проверяется без функций встроенного языка — оператором ССЫЛКА в секции ГДЕ:

ВЫБРАТЬ

Товары.Номенклатура КАК Номенклатура

ИЗ

Документ.РеализацияТоваровУслуг.Товары КАК Товары

ГДЕ

Товары.Номенклатура ССЫЛКА Справочник.Номенклатура

Обратите внимание на синтаксис: после ССЫЛКА пишется Справочник.Имя (без слова «Ссылка»), а не привычное «СправочникСсылка.Имя». Это частая ошибка при переносе логики из кода в запрос.

Для приведения поля составного типа к конкретному типу используется функция ВЫРАЗИТЬ(... КАК Справочник.Номенклатура). Она не фильтрует записи, а позволяет обращаться к реквизитам через точку без соединений. Проверка на пустую ссылку делается сравнением с ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка).

Перебор всех справочников через метаданные

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

Для Каждого МетаСправочник Из Метаданные.Справочники Цикл

ИмяТипа = "СправочникСсылка." + МетаСправочник.Имя;

ТекущийТип = Тип(ИмяТипа);

Сообщить(МетаСправочник.Синоним + " -> " + ИмяТипа);

КонецЦикла;

Работа с метаданными доступна только на сервере (и в толстом клиенте). В тонком и веб-клиенте коллекция Метаданные недоступна — переносите такой код в серверные процедуры общих модулей с признаком «Сервер».

Через метаданные также проверяют, относится ли конкретная ссылка к справочникам вообще: Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)) вернёт объект метаданных, у которого можно проверить родителя или использовать Метаданные.Справочники.Содержит(ОбъектМетаданных).

Порядок действий: узнать вид справочника по ссылке
  1. 1
    Получите тип значения: ТипЗнч(Ссылка)
  2. 2
    Найдите объект метаданных: Метаданные.НайтиПоТипу(ТипЗнч(Ссылка))
  3. 3
    Проверьте, что результат не Неопределено и что Метаданные.Справочники.Содержит(ОбъектМетаданных) = Истина
  4. 4
    Прочитайте имя вида: ОбъектМетаданных.Имя
  5. 5
    При необходимости получите пустую ссылку этого вида: Справочники[ОбъектМетаданных.Имя].ПустаяСсылка()

Получение ссылки и типа по строке и GUID

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

УникальныйИд = Новый УникальныйИдентификатор(СтрокаGUID);

СсылкаНаЭлемент = Справочники.Номенклатура.ПолучитьСсылку(УникальныйИд);

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

Строковое представление типа получают простым приведением: Строка(ТипЗнч(Ссылка)) вернёт что-то вроде «Номенклатура» (синоним), а для технического имени используйте XMLТипЗнч(Ссылка).ИмяТипа — результат вида «CatalogRef.Номенклатура», удобный для логирования и обменов.

Типичные ошибки
01
Сравнение Строка(ТипЗнч(Ссылка)) с именем справочника: синоним может отличаться от имени и меняться при доработках — сравнивайте сами типы
02
Использование Тип("СправочникСсылка.Имя") с именем, которого нет в конфигурации, — получите исключение; формируйте имя из метаданных
03
Проверка ссылки через Попытка/Исключение вместо ТипЗнч() — медленнее и маскирует реальные ошибки
04
Обращение к Метаданные в клиентском контексте тонкого клиента — код недоступен, алгоритм падает
05
Путаница СправочникСсылка и СправочникОбъект: попытка записи через ссылку без ПолучитьОбъект()

Сравнение способов получения типа

Выбор инструмента зависит от контекста задачи. Сводное сопоставление:

СпособЧто возвращаетКогда применятьОграничение
ТипЗнч(Значение)Тип конкретного значенияПроверка входных параметровНужен сам экземпляр значения
Тип("СправочникСсылка.Имя")Объект Тип по строкеСравнение с известным видомОшибка при неверном имени
Справочники.Имя.ТипВсеСсылки()ОписаниеТиповТипизация колонок, параметровТолько сервер/толстый клиент для ряда операций
Справочники.ТипВсеСсылки()ОписаниеТипов всех справочниковПроверка «любой справочник»Не даёт конкретный вид
Оператор ССЫЛКА в запросеБулево условиеОтбор в запросахТолько внутри текста запроса
Метаданные.СправочникиКоллекция видовУниверсальные обработкиНедоступно на тонком клиенте
Маршрут решения

Как выбрать действие

Нужно проверить тип переменной в кодеИспользуйте ТипЗнч() и сравнение с Тип() или ТипВсеСсылки().СодержитТип()
Нужно отобрать записи по типу в выборкеПрименяйте оператор ССЫЛКА в условии ГДЕ запроса
Нужно обработать все справочники конфигурацииПеребирайте Метаданные.Справочники в серверной процедуре
Нужно задать тип колонки или параметраПередавайте Справочники.Имя.ТипВсеСсылки() как описание типов

Проверка результата и отладка

После внедрения проверки типа убедитесь, что алгоритм ведёт себя корректно на граничных значениях. Минимальный набор тестовых случаев: ссылка нужного вида, ссылка другого справочника, ссылка на документ, пустая ссылка, значение Неопределено, примитивный тип (строка, число).

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

В отладчике тип значения виден в табло переменных в колонке «Тип». Для быстрой диагностики в журнале регистрации или сообщениях выводите XMLТипЗнч(Значение).ИмяТипа — это даёт однозначное техническое имя, не зависящее от синонимов конфигурации.

Контрольные точки

Как проверить результат

Сравнение типов в коде
Норма

Условие срабатывает для нужного справочника и не срабатывает для других ссылок

Тревожный признак

Условие истинно для любых значений или не срабатывает никогда

Проверка ССЫЛКА в запросе
Норма

В выборку попадают только записи нужного справочника

Тревожный признак

Пустой результат при заведомо существующих данных — проверьте синтаксис Справочник.Имя

Работа на тонком клиенте
Норма

Код выполняется без ошибок компиляции и выполнения

Тревожный признак

Ошибка доступа к Метаданные или менеджерам — вынесите код на сервер

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

Чем СправочникСсылка отличается от СправочникОбъект?

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

Как проверить, что ссылка принадлежит именно справочникам, а не документам?

Используйте Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)) — вернёт Истина только для ссылок на справочники. Альтернатива на сервере: Метаданные.НайтиПоТипу() с проверкой через Метаданные.Справочники.Содержит().

Почему Тип("СправочникСсылка.Номенклатура") выдаёт ошибку?

Скорее всего, справочника с таким именем нет в конфигурации или имя указано с опечаткой. Имя должно совпадать с именем в конфигураторе, а не с синонимом. Проверьте точное имя в дереве конфигурации или получите его программно через Метаданные.Справочники.

Можно ли получить тип СправочникСсылка в тонком клиенте?

Функции ТипЗнч() и Тип() работают на клиенте без ограничений. Ограничены обращения к Метаданные и ряд операций менеджеров — такой код размещайте в серверных процедурах общих модулей или модулях формы с директивой &НаСервере.

Как из ссылки получить строковое имя её типа для обмена?

Вызовите XMLТипЗнч(Ссылка).ИмяТипа — получите строку вида «CatalogRef.Номенклатура», пригодную для сериализации. Для обратного преобразования в строку-идентификатор элемента используйте Строка(Ссылка.УникальныйИдентификатор()).

Как проверить тип поля составного типа в запросе, не теряя остальные записи?

Оператор ССЫЛКА в ГДЕ отфильтрует записи. Если нужно сохранить все строки и лишь пометить тип, используйте ВЫБОР КОГДА Поле ССЫЛКА Справочник.Номенклатура ТОГДА Истина ИНАЧЕ Ложь КОНЕЦ в списке выборки.

Итог

Что важно запомнить

Тип значения получают через ТипЗнч(), описание типа справочника — через Тип() или Справочники.Имя.ТипВсеСсылки(), в запросе используют оператор ССЫЛКА, а перебор всех видов — через Метаданные.Справочники на сервере. Сравнивайте типы объектами Тип, а не строками, и отдельно проверяйте пустые ссылки.