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