Как в 1С:Предприятие 8 определить тип объекта или его принадлежность к справочникам и документам

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет IT и автоматизация бизнеса
← На главную

В процессе разработки на платформе 1С:Предприятие 8 программисты часто сталкиваются с необходимостью динамически определять, к какому классу относится тот или иной объект. Это особенно актуально при работе с реквизитами составного типа, универсальными обработками или когда требуется анализ зависимостей конфигурации. Рассмотрим подробнее все существующие способы решения этой задачи, проанализируем их производительность и выберем наиболее оптимальные подходы.

Метод 1. Использование функции ТипЗнч и прямое сравнение

Самый простой и быстрый способ узнать тип конкретной ссылки — использовать встроенную функцию ТипЗнч. Этот метод работает на уровне идентификаторов типов в оперативной памяти, что делает его крайне производительным. Разберем пример, когда нам нужно проверить, является ли переменная ссылкой на конкретный справочник.


Если ТипЗнч(ВыбранныйОбъект) = Тип("СправочникСсылка.Номенклатура") Тогда
    // Выполняем действия, специфичные для номенклатуры
    Сообщить("Это номенклатура");
КонецЕсли;

Важно помнить, что функция Тип принимает строковое имя типа. Для ссылочных объектов формат всегда будет КлассОбъектаСсылка.ИмяОбъекта. Если мы работаем с документами, условие будет выглядеть как Тип("ДокументСсылка.РеализацияТоваровУслуг"). Для быстрой проверки таких конструкций удобно использовать консоль кода с ИИ-помощником.

Метод 2. Проверка через коллекцию ТипВсеСсылки

Часто возникает вопрос: как определить, является ли объект документом или справочником вообще, не привязываясь к конкретному виду (например, любая накладная или любой элемент справочника)? Для этого в глобальном контексте существуют коллекции Справочники, Документы, ПланыВидовХарактеристик и другие, у которых есть свойство ТипВсеСсылки.

Проанализируем пример кода для такой проверки:


ТипОбъекта = ТипЗнч(ВыбранныйОбъект);

Если Справочники.ТипВсеСсылки().СодержитТип(ТипОбъекта) Тогда
    Сообщить("Переданное значение — это ссылка на какой-то справочник");
ИначеЕсли Документы.ТипВсеСсылки().СодержитТип(ТипОбъекта) Тогда
    Сообщить("Переданное значение — это ссылка на какой-то документ");
КонецЕсли;

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

Метод 3. Анализ через объект метаданных

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


ТекущийТип = ТипЗнч(ОбъектСсылка);
ОбъектМетаданных = Метаданные.НайтиПоТипу(ТекущийТип);

Если ОбъектМетаданных = Неопределено Тогда
    Возврат; // Тип не найден в метаданных (например, число или строка)
КонецЕсли;

Если Метаданные.Справочники.Содержит(ОбъектМетаданных) Тогда
    Сообщить("Это справочник: " + ОбъектМетаданных.Имя);
ИначеЕсли Метаданные.Документы.Содержит(ОбъектМетаданных) Тогда
    Сообщить("Это документ: " + ОбъектМетаданных.Имя);
КонецЕсли;

Важное замечание по производительности: Обращение к ОбъектСсылка.Метаданные() является достаточно "дорогой" операцией, так как заставляет платформу обращаться к структуре конфигурации. Если вам нужно просто сравнить типы в цикле, всегда отдавайте предпочтение ТипЗнч.

Метод 4. Работа со строковыми именами типов (ПолноеИмя)

Если вам нужно получить строковое представление типа для логирования или динамического формирования запросов, удобно использовать свойство ПолноеИмя. Оно возвращает строку вида Справочник.Валюты или Документ.ПоступлениеТоваровУслуг.

Посмотрим, как можно реализовать проверку через анализ строки:


ПолноеИмя = ОбъектСсылка.Метаданные().ПолноеИмя();
// Проверяем первые символы строки
Если СтрНачинаетсяС(ПолноеИмя, "Справочник") Тогда
    Сообщить("Объект относится к справочникам");
ИначеЕсли СтрНачинаетсяС(ПолноеИмя, "Документ") Тогда
    Сообщить("Объект относится к документам");
КонецЕсли;

В старых версиях платформы (до появления СтрНачинаетсяС) программисты использовали функцию Лев(ПолноеИмя, 5), но современный подход делает код более читаемым и защищенным от ошибок. Также можно использовать СтрРазделить(ПолноеИмя, ".")[0], чтобы получить только имя базового класса (Справочник, Документ, РегистрСведений).

Метод 5. Использование возможностей БСП (Библиотеки стандартных подсистем)

Если ваша конфигурация построена на базе БСП (как большинство современных типовых решений: УТ 11, ERP, БП 3.0), задачу определения типа можно решить одной строкой, используя общий модуль ОбщегоНазначения.

Разберем основные функции:

  1. ОбщегоНазначения.ЭтоСсылка(ТипЗнч(Значение)) — возвращает Истина, если переданный тип является ссылочным.
  2. ОбщегоНазначения.ИмяБазовогоТипаПоОбъектуМетаданных(Значение.Метаданные()) — вернет строковое значение, например, "Справочники".

Использование функций БСП гарантирует, что ваш код будет соответствовать стандартам разработки фирмы "1С" и корректно отработает во всех типовых сценариях.

Метод 6. Быстрое получение типа через XMLТип

Существует "хитрый" и очень быстрый способ получить информацию о типе без обращения к тяжелым объектам метаданных — использование функции XMLТип. Это полезно для высоконагруженных участков кода.


ДанныеТипа = XMLТип(ТипЗнч(ОбъектСсылка));
// ДанныеТипа.ИмяТипа вернет "CatalogRef.Номенклатура"
// ДанныеТипа.URIПространстваИмена вернет схему данных

Этот метод удобен тем, что возвращает фиксированную структуру, из которой легко извлечь англоязычное имя базового класса (например, CatalogRef, DocumentRef).

Метод 7. Определение типа на уровне запроса

Иногда эффективнее определить тип объекта еще на этапе получения данных из базы, не выгружая сами объекты в память сервера приложений. В языке запросов 1С для этого предусмотрены специальные операторы.

Проанализируем пример запроса:


ВЫБРАТЬ
    ВЫБОР
        КОГДА Ссылка ССЫЛКА Справочник.Номенклатура ТОГДА "Это товар"
        КОГДА Ссылка ССЫЛКА Справочник.Услуги ТОГДА "Это услуга"
        ИНАЧЕ "Прочее"
    КОНЕЦ КАК ВидОбъекта
ИЗ
    Документ.РеализацияТоваровУслуг.Товары

Функция ТИПЗНАЧЕНИЯ(Поле) в запросе позволяет получить идентификатор типа, который можно сравнивать с эталонным с помощью оператора ТИП(Справочник.Склады). Это самый быстрый способ обработки больших массивов данных.

Итоги и рекомендации

Подводя итог нашему разбору, можно выделить следующие правила выбора метода:

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

Помните также о существовании других ссылочных типов, таких как Планы счетов, Задачи, Бизнес-процессы и Перечисления. Все описанные выше методы (кроме специфических для БСП) применимы и к ним.

← На главную