При разработке отчетов на базе системы компоновки данных (СКД) часто возникает задача сделать интерфейс максимально удобным и компактным для конечного пользователя. Нередко требуется вынести конкретное поле отбора (например, организацию, кассу или ссылку на документ) прямо в шапку отчета отдельной строкой, где пользователь сможет быстро включать или выключать фильтрацию, выбирать вид сравнения и указывать значение. Разберем, как правильно реализовать такую настройку и избежать распространенных ошибок.
Разберем типичную ситуацию. Разработчик включает в пользовательские настройки всю коллекцию отборов или группировку. В результате на форме отчета появляется строка Отбор, при нажатии на которую открывается громоздкое окно со всеми доступными полями схемы. Если же включить пользовательскую настройку для группировки, то галочка на форме будет управлять исключительно выводом самой иерархической ветки, но не фильтрацией записей.
Важно понимать, что в стандартной модели СКД управление структурой отчета (группировками) и управление отборами — это два независимых механизма. Чтобы получить компактную строку отбора по конкретному полю, необходимо добавлять в пользовательские настройки не весь корневой узел отборов и не группировку, а именно конкретный элемент условия.
Рассмотрим по шагам правильный алгоритм настройки схемы компоновки данных в конфигураторе:
ГДЕ Документ.Организация = &Организация, система будет требовать их обязательного заполнения. Чтобы отбор применялся гибко (только тогда, когда пользователь установил флаг), уберем жесткие параметры или перенесем их в необязательную секцию компоновки {ГДЕ ...}.Ссылка или Организация). Укажем требуемый вид сравнения (например, Равно или В списке).Посмотрим на пример запроса, в котором секции компоновки данных позволяют СКД динамически накладывать условия только при их включении пользователем:
ВЫБРАТЬ
ПоступлениеТоваров.Ссылка КАК Ссылка,
ПоступлениеТоваров.Номенклатура КАК Номенклатура,
ПоступлениеТоваров.Количество КАК КоличествоПриход,
ПоступлениеТоваров.Сумма КАК СуммаПриход
{ВЫБРАТЬ
Ссылка.*,
Номенклатура.*,
КоличествоПриход,
СуммаПриход}
ИЗ
Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваров
ГДЕ
ПоступлениеТоваров.Ссылка.Проведен
{ГДЕ
ПоступлениеТоваров.Ссылка.*,
ПоступлениеТоваров.Номенклатура.*}
В данном примере условия внутри фигурных скобок {ГДЕ ...} являются необязательными. Когда пользователь включает флаг отбора на форме отчета, платформа автоматически дополняет результирующий SQL-запрос соответствующим условием.
В окне свойств пользовательской настройки доступно управление свойством РежимОтображения:
Если бизнес-логика требует, чтобы одна пользовательская галочка на форме одновременно включала группировку в структуре и активировала соответствующий отбор, стандартных настроек СКД будет недостаточно. В этом случае создадим реквизит на управляемой форме отчета и свяжем управление программно:
&НаСервере
Процедура ПрименитьФильтрИГруппировкуНаСервере(ИмяПоля, ЗначениеФлага, ЗначениеОтбора)
// 1. Управление элементом отбора
Для Каждого ЭлементОтбора Из Отчет.КомпоновщикНастроек.Настройки.Отбор.Элементы Цикл
Если ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ИмяПоля) Тогда
ЭлементОтбора.Использование = ЗначениеФлага;
Если ЗначениеФлага И ЗначениеЗаполнено(ЗначениеОтбора) Тогда
ЭлементОтбора.ПравоеЗначение = ЗначениеОтбора;
КонецЕсли;
КонецЕсли;
КонецЦикла;
// 2. Управление активностью группировки в структуре
Для Каждого ЭлементСтруктуры Из Отчет.КомпоновщикНастроек.Настройки.Структура Цикл
Если ТипЗнч(ЭлементСтруктуры) = Тип("ГруппировкаКомпоновкиДанных") Тогда
Для Каждого ПолеГруппировки Из ЭлементСтруктуры.ПоляГруппировки.Элементы Цикл
Если ПолеГруппировки.Поле = Новый ПолеКомпоновкиДанных(ИмяПоля) Тогда
ЭлементСтруктуры.Использование = ЗначениеФлага;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Таким образом, для базового сценария достаточно правильно использовать флаг Включать в пользовательские настройки на уровне конкретного элемента отбора схемы, а для нестандартных сценариев совмещения группировки и фильтрации — использовать программную обработку в коде формы.