При разработке сложных отчетов или динамическом изменении настроек компоновки данных часто возникает задача программного анализа установленных отборов. Простое использование функции ТипЗнч() для правого значения отбора не всегда дает желаемый результат, особенно если нам нужно определить категорию объекта: является ли выбранное значение справочником, перечислением или примитивным типом (например, булево).
В этой статье мы разберем несколько подходов к определению типа отбора, проанализируем нюансы различных видов сравнения и выясним, как получить описание типов, даже если значение в отборе еще не заполнено.
Если в элементе отбора уже выбрано конкретное значение, мы можем использовать объект Метаданные для определения его принадлежности к той или иной коллекции. Рассмотрим ситуацию, когда нам нужно понять, является ли значение в ПравоеЗначение перечислением.
Для этого воспользуемся методом НайтиПоТипу(), который возвращает объект метаданных для конкретного типа значения. Проанализируем пример кода:
// Предположим, ЭлементОтбора — это ЭлементОтбораКомпоновкиДанных
ТипЗначенияОтбора = ТипЗнч(ЭлементОтбора.ПравоеЗначение);
ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗначенияОтбора);
Если ОбъектМетаданных <> Неопределено Тогда
Если Метаданные.Перечисления.Содержит(ОбъектМетаданных) Тогда
// Это перечисление
ИначеЕсли Метаданные.Справочники.Содержит(ОбъектМетаданных) Тогда
// Это справочник
КонецЕсли;
КонецЕсли;
Важный нюанс: этот метод сработает только в том случае, если в поле ПравоеЗначение уже содержится объект. Если отбор установлен, но значение не выбрано (пустая ссылка или Неопределено), этот подход может вернуть ошибку или некорректный результат.
Более надежный и профессиональный способ — обратиться к свойству ДоступныеПоляОтбора компоновщика настроек. Этот метод позволяет узнать ожидаемый тип данных поля, даже если пользователь еще ничего не ввел в правое значение. Система компоновки данных заранее знает, какие типы разрешены для каждого поля.
Разберем, как это реализовать по шагам:
ОписаниеТипов.
// Получаем поле компоновки, которое указано в левой части отбора
ПолеОтбора = ЭлементОтбора.ЛевоеЗначение;
// Ищем соответствующее доступное поле
ДоступноеПоле = КомпонентНастроек.Настройки.ДоступныеПоляОтбора.НайтиПоле(ПолеОтбора);
Если ДоступноеПоле <> Неопределено Тогда
ОписаниеТиповПоля = ДоступноеПоле.Тип;
// Теперь у нас есть полное описание типов (TypeDescription)
// Можно проверить на наличие конкретных типов или категорий
Если ОписаниеТиповПоля.СодержитТип(Тип("Булево")) Тогда
// Поле может принимать булево значение
КонецЕсли;
КонецЕсли;
Проанализируем ситуацию, когда тип данных в ПравоеЗначение меняется в зависимости от выбранного оператора сравнения. Программисту важно учитывать следующие моменты:
ПравоеЗначение всегда будет содержать объект типа СписокЗначений. Чтобы узнать тип данных самих элементов, нужно проверить свойство ТипЗначения этого списка или проанализировать первый элемент коллекции.ДоступныеПоляОтбора, описанный выше.ПравоеЗначение будет находиться объект типа ПолеКомпоновкиДанных.Если поле в схеме компоновки имеет составной тип (например, «ДокументСсылка.Реализация» и «ДокументСсылка.Поступление»), функция ТипЗнч(ПравоеЗначение) вернет тип только того значения, которое выбрано в данный момент. Если же вы хотите узнать все возможные типы, которые разрешено выбирать в этот отбор, необходимо обращаться к ОписаниеТипов через метаданные схемы или доступные поля компоновщика.
Выясним, как проверить, является ли тип ссылочным, с помощью встроенных функций общих модулей (если они есть в вашей типовой конфигурации) или через метаданные:
МетаданныеОбъекта = Метаданные.НайтиПоТипу(ТипЗнч(ЭлементОтбора.ПравоеЗначение));
Если Метаданные.Справочники.Содержит(МетаданныеОбъекта)
ИЛИ Метаданные.Документы.Содержит(МетаданныеОбъекта) Тогда
// Обработка ссылочного типа
КонецЕсли;
Таким образом, для получения максимально точной информации о типе отбора рекомендуется комбинировать анализ ПравогоЗначения (для текущего выбора) и ДоступныхПолейОтбора (для понимания природы самого поля в схеме СКД).