Как в запросе 1С определить, является ли объект справочником или документом через ТИПЗНАЧЕНИЯ?

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

При работе с регистрами, содержащими составные типы данных (например, регистр сведений ВерсииОбъектов или ЖурналПроводки), программисты часто сталкиваются с необходимостью классифицировать объект прямо в запросе. Основная сложность заключается в том, что функция ТИПЗНАЧЕНИЯ() возвращает конкретный тип (например, ДокументСсылка.РеализацияТоваровУслуг), но не говорит напрямую, относится ли этот тип к классу «Документы» или «Справочники».

В этой статье мы разберем несколько эффективных способов решения этой задачи, проанализируем их производительность и выберем наиболее подходящий для Системы компоновки данных (СКД).

Метод 1: Использование параметров с массивом всех типов

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

Рассмотрим по шагам реализацию этого метода:

  1. Подготовим список типов на языке 1С перед выполнением запроса.
  2. Передадим этот список в параметр.
  3. В тексте запроса используем конструкцию В (&Параметр).

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


// Получаем массив всех типов документов в конфигурации
ТипыДокументов = Документы.ТипВсеСсылки().Типы();
// Получаем массив всех типов справочников
ТипыСправочников = Справочники.ТипВсеСсылки().Типы();

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Т.Объект КАК Объект,
    |   ВЫБОР
    |       КОГДА ТИПЗНАЧЕНИЯ(Т.Объект) В (&ТипыДокументов) ТОГДА ""Документ""
    |       КОГДА ТИПЗНАЧЕНИЯ(Т.Объект) В (&ТипыСправочников) ТОГДА ""Справочник""
    |       ИНАЧЕ ""Прочее""
    |   КОНЕЦ КАК КатегорияОбъекта
    |ИЗ
    |   РегистрСведений.ВерсииОбъектов КАК Т";

Запрос.УстановитьПараметр("ТипыДокументов", ТипыДокументов);
Запрос.УстановитьПараметр("ТипыСправочников", ТипыСправочников);

Преимущества: Высокая скорость выполнения на стороне СУБД, так как сравнение типов происходит по внутренним идентификаторам (Numeric ID типа).

Метод 2: Использование справочника «Идентификаторы объектов метаданных»

Если нам нужно решение, которое будет работать полностью внутри запроса без предварительной подготовки параметров в коде (например, в динамическом списке или сложном отчете СКД), мы можем воспользоваться системным справочником ИдентификаторыОбъектовМетаданных. Этот справочник хранит иерархическую структуру всех объектов конфигурации.

Проанализируем структуру решения:

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


ВЫБРАТЬ
    ВерсииОбъектов.Объект КАК Объект,
    Идентификаторы.Имя КАК ИмяТипа,
    РодителиИдентификаторов.Имя КАК КатегорияМетаданных
ИЗ
    РегистрСведений.ВерсииОбъектов КАК ВерсииОбъектов
    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ИдентификаторыОбъектовМетаданных КАК Идентификаторы
        ПО ТИПЗНАЧЕНИЯ(ВерсииОбъектов.Объект) = Идентификаторы.ТипОплаты // Внимание: используйте поле Тип в актуальных версиях БСП
    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ИдентификаторыОбъектовМетаданных КАК РодителиИдентификаторов
        ПО Идентификаторы.Родитель = РодителиИдентификаторов.Ссылка
ГДЕ
    РодителиИдентификаторов.Имя = "Документы"

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

Метод 3: Особенности реализации в СКД

В Системе компоновки данных у нас есть дополнительные инструменты. Если задача стоит просто в отображении текста или условном оформлении, мы можем не усложнять запрос, а использовать Вычисляемые поля или Выражения ресурсов.

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


Функция ЭтоДокумент(Объект) Экспорт
    Возврат Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Объект));
КонецФункции

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

Почему нельзя просто написать ТИПЗНАЧЕНИЯ(Объект) = ТИП("Документ")?

Давайте выясним причину, по которой привычные конструкции не работают в запросах. В языке 1С «Документ» — это не конкретный тип данных, а класс объектов. В базе данных под каждый вид документа (например, ЗаказПокупателя) выделяется свой числовой идентификатор типа. Когда вы вызываете ТИПЗНАЧЕНИЯ, SQL-запрос получает конкретное число.

Поскольку общего идентификатора для «всех документов» в таблицах СУБД не существует, платформа требует точного указания типа. Именно поэтому мы используем либо конструкцию ССЫЛКА (если типов немного), либо массив всех возможных типов через параметр.

Сравнение производительности: ТИПЗНАЧЕНИЯ vs ССЫЛКА

Часто возникает вопрос: что использовать эффективнее — оператор ССЫЛКА или функцию ТИПЗНАЧЕНИЯ? Проанализируем ситуацию:

Подведем итог: Если вы работаете в СКД и вам нужно универсальное решение для определения «Справочник или Документ», лучшим вариантом будет Метод 1 (передача массивов типов в параметры). Он обеспечивает максимальную скорость выполнения и корректную работу со всеми объектами метаданных без исключения.

← На главную