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