Разработка и Конфигурация · 13 мин
Как получить тип СправочникСсылка в 1С
Как получить тип СправочникСсылка в 1С: Тип(), ТипЗнч(), Справочники.ТипВсеСсылки(), проверка типа ссылки в запросе и на форме. Примеры кода и частые ошибки.
Тип СправочникСсылка — один из самых часто используемых типов во встроенном языке 1С. Он описывает ссылку на элемент справочника: легковесный объект, который содержит идентификатор записи, но не загружает все её данные в память. Получить или проверить этот тип требуется при написании универсальных алгоритмов, обработок обмена, проверках входных параметров процедур и в запросах.
В зависимости от задачи «получить тип» может означать разное: определить тип конкретной переменной, получить объект описания типа для конкретного справочника (например, «СправочникСсылка.Номенклатура»), получить коллекцию всех ссылочных типов справочников конфигурации или проверить тип прямо в тексте запроса. Каждая задача решается своим инструментом платформы.
Ниже разобраны все основные способы: функции Тип() и ТипЗнч(), свойство МенеджерСправочника.ТипВсеСсылки(), оператор запроса ССЫЛКА и работа с метаданными. Примеры кода применимы на платформе 8.3 как в толстом, так и в тонком клиенте, с учётом ограничений контекста сервера и клиента.
Что такое тип СправочникСсылка и зачем его получать
В 1С каждый объект базы данных имеет ссылку — уникальный идентификатор, по которому система находит запись. Для справочников ссылка имеет тип вида СправочникСсылка.<ИмяСправочника>, например СправочникСсылка.Контрагенты. Это не строка и не число, а отдельный тип данных платформы.
Отличие ссылки от объекта принципиально. СправочникСсылка — это только указатель: через него доступны реквизиты (платформа неявно обращается к базе), но изменить данные можно только через СправочникОбъект, полученный методом ПолучитьОбъект(). Поэтому проверка «является ли значение ссылкой на справочник» — стандартный приём защиты алгоритмов от некорректных входных данных.
Типичные сценарии, где нужно получить тип: универсальная процедура записи, принимающая любую ссылку; обработка заполнения табличной части с колонкой составного типа; отбор в запросе только по ссылкам определённого справочника; динамическое создание значений через описание типов.
Получение типа через Тип() и ТипЗнч()
Функция ТипЗнч(Значение) возвращает тип конкретного значения, хранящегося в переменной. Это основной способ узнать, что именно передано в процедуру:
Процедура ОбработатьЗначение(ВходноеЗначение)
Если ТипЗнч(ВходноеЗначение) = Тип("СправочникСсылка.Номенклатура") Тогда
// это ссылка на номенклатуру
Сообщить("Получена номенклатура: " + ВходноеЗначение);
КонецЕсли;
КонецПроцедуры
Функция Тип("СправочникСсылка.Номенклатура") создаёт объект типа «Тип» по строковому имени. Имя строится по шаблону: СправочникСсылка, точка, имя справочника как оно задано в конфигураторе. Ошибка в имени вызовет исключение времени выполнения, поэтому при динамическом формировании строки имя стоит брать из метаданных, а не вводить вручную.
Если нужно проверить принадлежность к любому справочнику без привязки к конкретному виду, перечислять все типы через Тип() неудобно — используйте Справочники.ТипВсеСсылки(), о котором ниже.
Проверка без привязки к виду справочника
Если Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)) Тогда
// значение — ссылка на какой-либо справочник
КонецЕсли;
Получение описания типа через менеджер справочника
У каждого менеджера справочника есть метод ТипВсеСсылки(), возвращающий объект ОписаниеТипов. Для конкретного справочника это описание содержит ровно один тип:
ОписаниеТипаНоменклатура = Справочники.Номенклатура.ТипВсеСсылки();
// ОписаниеТипов, содержащее СправочникСсылка.Номенклатура
ТипНоменклатуры = ОписаниеТипаНоменклатура.Типы()[0];
// сам объект Тип
Такое описание типов нужно, когда требуется не просто проверка, а конструирование: ограничение типа колонки таблицы значений, настройка параметра динамического списка, приведение значения через ПривестиЗначение().
ТаблицаЗначений = Новый ТаблицаЗначений;
ТаблицаЗначений.Колонки.Добавить("Товар",
Справочники.Номенклатура.ТипВсеСсылки());
Аналогично работает Справочники.ТипВсеСсылки() без указания вида — возвращается описание, включающее ссылочные типы всех справочников конфигурации. Это удобно для колонок «любая ссылка на справочник» и универсальных обработок.
Если колонка таблицы значений объявлена без типа, а затем в неё помещают ссылки разных справочников, сортировка и сравнение могут работать неожиданно. Явное задание типа через ТипВсеСсылки() снимает этот класс ошибок.
Проверка типа ссылки в запросе
В языке запросов тип проверяется без функций встроенного языка — оператором ССЫЛКА в секции ГДЕ:
ВЫБРАТЬ
Товары.Номенклатура КАК Номенклатура
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
Товары.Номенклатура ССЫЛКА Справочник.Номенклатура
Обратите внимание на синтаксис: после ССЫЛКА пишется Справочник.Имя (без слова «Ссылка»), а не привычное «СправочникСсылка.Имя». Это частая ошибка при переносе логики из кода в запрос.
Для приведения поля составного типа к конкретному типу используется функция ВЫРАЗИТЬ(... КАК Справочник.Номенклатура). Она не фильтрует записи, а позволяет обращаться к реквизитам через точку без соединений. Проверка на пустую ссылку делается сравнением с ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка).
Перебор всех справочников через метаданные
Когда нужно получить типы всех справочников конфигурации (например, для универсальной обработки поиска дублей или анализа ссылочной целостности), используется коллекция Метаданные.Справочники:
Для Каждого МетаСправочник Из Метаданные.Справочники Цикл
ИмяТипа = "СправочникСсылка." + МетаСправочник.Имя;
ТекущийТип = Тип(ИмяТипа);
Сообщить(МетаСправочник.Синоним + " -> " + ИмяТипа);
КонецЦикла;
Работа с метаданными доступна только на сервере (и в толстом клиенте). В тонком и веб-клиенте коллекция Метаданные недоступна — переносите такой код в серверные процедуры общих модулей с признаком «Сервер».
Через метаданные также проверяют, относится ли конкретная ссылка к справочникам вообще: Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)) вернёт объект метаданных, у которого можно проверить родителя или использовать Метаданные.Справочники.Содержит(ОбъектМетаданных).
- 1Получите тип значения: ТипЗнч(Ссылка)
- 2Найдите объект метаданных: Метаданные.НайтиПоТипу(ТипЗнч(Ссылка))
- 3Проверьте, что результат не Неопределено и что Метаданные.Справочники.Содержит(ОбъектМетаданных) = Истина
- 4Прочитайте имя вида: ОбъектМетаданных.Имя
- 5При необходимости получите пустую ссылку этого вида: Справочники[ОбъектМетаданных.Имя].ПустаяСсылка()
Получение ссылки и типа по строке и GUID
В обменах данными часто приходит не ссылка, а её строковое представление — уникальный идентификатор. Обратное преобразование выполняется так:
УникальныйИд = Новый УникальныйИдентификатор(СтрокаGUID);
СсылкаНаЭлемент = Справочники.Номенклатура.ПолучитьСсылку(УникальныйИд);
После ПолучитьСсылку() обязательно проверяйте существование объекта: ссылка может быть «битой», если элемент удалён. Проверка — через запрос по ссылке или через СсылкаНаЭлемент.ПолучитьОбъект() с анализом на Неопределено (само обращение к реквизиту битой ссылки вернёт неопределённые значения, но запрос надёжнее).
Строковое представление типа получают простым приведением: Строка(ТипЗнч(Ссылка)) вернёт что-то вроде «Номенклатура» (синоним), а для технического имени используйте XMLТипЗнч(Ссылка).ИмяТипа — результат вида «CatalogRef.Номенклатура», удобный для логирования и обменов.
Сравнение способов получения типа
Выбор инструмента зависит от контекста задачи. Сводное сопоставление:
| Способ | Что возвращает | Когда применять | Ограничение |
|---|---|---|---|
ТипЗнч(Значение) | Тип конкретного значения | Проверка входных параметров | Нужен сам экземпляр значения |
Тип("СправочникСсылка.Имя") | Объект Тип по строке | Сравнение с известным видом | Ошибка при неверном имени |
Справочники.Имя.ТипВсеСсылки() | ОписаниеТипов | Типизация колонок, параметров | Только сервер/толстый клиент для ряда операций |
Справочники.ТипВсеСсылки() | ОписаниеТипов всех справочников | Проверка «любой справочник» | Не даёт конкретный вид |
| Оператор ССЫЛКА в запросе | Булево условие | Отбор в запросах | Только внутри текста запроса |
Метаданные.Справочники | Коллекция видов | Универсальные обработки | Недоступно на тонком клиенте |
Как выбрать действие
Проверка результата и отладка
После внедрения проверки типа убедитесь, что алгоритм ведёт себя корректно на граничных значениях. Минимальный набор тестовых случаев: ссылка нужного вида, ссылка другого справочника, ссылка на документ, пустая ссылка, значение Неопределено, примитивный тип (строка, число).
Обратите внимание: ТипЗнч(Неопределено) возвращает тип «Неопределено», а не вызывает ошибку, поэтому явная проверка на Неопределено до анализа типа не обязательна, но улучшает читаемость. Пустая ссылка имеет тот же тип, что и заполненная, — проверку на пустоту выполняйте отдельно через Ссылка.Пустая() или сравнение с ПустаяСсылка().
В отладчике тип значения виден в табло переменных в колонке «Тип». Для быстрой диагностики в журнале регистрации или сообщениях выводите XMLТипЗнч(Значение).ИмяТипа — это даёт однозначное техническое имя, не зависящее от синонимов конфигурации.
Как проверить результат
Условие срабатывает для нужного справочника и не срабатывает для других ссылок
Условие истинно для любых значений или не срабатывает никогда
В выборку попадают только записи нужного справочника
Пустой результат при заведомо существующих данных — проверьте синтаксис Справочник.Имя
Код выполняется без ошибок компиляции и выполнения
Ошибка доступа к Метаданные или менеджерам — вынесите код на сервер
Частые вопросы
Чем СправочникСсылка отличается от СправочникОбъект?
Ссылка — это идентификатор записи, доступный только для чтения реквизитов. Объект — полная копия данных элемента в памяти, которую можно изменять и записывать методом Записать(). Объект получают вызовом Ссылка.ПолучитьОбъект(), но делать это стоит только когда действительно нужна модификация: чтение через ссылку дешевле.
Как проверить, что ссылка принадлежит именно справочникам, а не документам?
Используйте Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)) — вернёт Истина только для ссылок на справочники. Альтернатива на сервере: Метаданные.НайтиПоТипу() с проверкой через Метаданные.Справочники.Содержит().
Почему Тип("СправочникСсылка.Номенклатура") выдаёт ошибку?
Скорее всего, справочника с таким именем нет в конфигурации или имя указано с опечаткой. Имя должно совпадать с именем в конфигураторе, а не с синонимом. Проверьте точное имя в дереве конфигурации или получите его программно через Метаданные.Справочники.
Можно ли получить тип СправочникСсылка в тонком клиенте?
Функции ТипЗнч() и Тип() работают на клиенте без ограничений. Ограничены обращения к Метаданные и ряд операций менеджеров — такой код размещайте в серверных процедурах общих модулей или модулях формы с директивой &НаСервере.
Как из ссылки получить строковое имя её типа для обмена?
Вызовите XMLТипЗнч(Ссылка).ИмяТипа — получите строку вида «CatalogRef.Номенклатура», пригодную для сериализации. Для обратного преобразования в строку-идентификатор элемента используйте Строка(Ссылка.УникальныйИдентификатор()).
Как проверить тип поля составного типа в запросе, не теряя остальные записи?
Оператор ССЫЛКА в ГДЕ отфильтрует записи. Если нужно сохранить все строки и лишь пометить тип, используйте ВЫБОР КОГДА Поле ССЫЛКА Справочник.Номенклатура ТОГДА Истина ИНАЧЕ Ложь КОНЕЦ в списке выборки.
Что важно запомнить
Тип значения получают через ТипЗнч(), описание типа справочника — через Тип() или Справочники.Имя.ТипВсеСсылки(), в запросе используют оператор ССЫЛКА, а перебор всех видов — через Метаданные.Справочники на сервере. Сравнивайте типы объектами Тип, а не строками, и отдельно проверяйте пустые ссылки.