При разработке отчетов на базе Системы компоновки данных (СКД) часто возникает задача частичной фильтрации. Например, нам нужно, чтобы в одной группировке отображались только определенные записи, а в другой — абсолютно все данные без ограничений. Ошибка многих начинающих разработчиков заключается в попытке использовать функции агрегации, такие как ВычислитьВыражение, для задач фильтрации. В этой статье мы разберем, почему это не работает, и рассмотрим правильные методики решения задачи.
Рассмотрим ситуацию, когда в отчете есть группировка ТипПарка. В этой группировке присутствуют значения "ПОР" и "Груж". Нам необходимо, чтобы для значения "ПОР" отображались только те строки, где СтанцияНазначения соответствует значению "Хабаровск 1". При этом для значения "Груж" никаких ограничений быть не должно.
Попытка использовать ВычислитьВыражение("СтанцияНазначения", "ТипПарка") в вычисляемых полях является концептуально неверной. Функция ВычислитьВыражение предназначена для получения значений из других строк или группировок, а также для расчета итогов по произвольному контексту. Она не может «скрыть» строку из результата компоновки. Если мы хотим управлять составом записей, нам нужно использовать механизмы отбора.
Это самый «чистый» и правильный метод с точки зрения архитектуры СКД. Система позволяет задавать настройки не только для всего отчета в целом, но и для каждой ветки дерева группировок индивидуально. Проанализируем, как это настроить:
ТипПарка или вложенную в нее детальную запись).СтанцияНазначения Равно "Хабаровск 1".Чтобы этот отбор применялся только к «ПОР», структуру группировок можно сделать иерархической, где для одной ветки задан жесткий фильтр, а вторая остается пустой или содержит другие условия. Рассмотрим ситуацию, когда мы разделяем вывод на две части:
Отчет
|_ Группировка: ТипПарка (Отбор: ТипПарка = "ПОР", СтанцияНазначения = "Хабаровск 1")
|_ Группировка: ТипПарка (Отбор: ТипПарка <> "ПОР")
Если мы не хотим менять структуру группировок или нам нужно сложное условие, которое зависит от нескольких параметров, оптимальным решением будет создание вычисляемого поля, которое определит «валидность» строки. Разберем этот алгоритм подробнее:
Создадим вычисляемое поле, назовем его, например, ЭтоНужнаяЗапись. В выражении этого поля пропишем логику фильтрации, используя конструктор ВЫБОР:
ВЫБОР
КОГДА ТипПарка = "ПОР" И СтанцияНазначения <> "Хабаровск 1" ТОГДА Ложь
ИНАЧЕ Истина
КОНЕЦ
После создания поля выполним следующие шаги:
ЭтоНужнаяЗапись и установим вид сравнения Равно, а значение — Да (Истина).Преимущество метода: Мы не трогаем запрос к базе данных и можем гибко менять логику фильтрации прямо в настройках компоновки, не меняя структуру отчета.
Иногда полезно «сгруппировать» все ненужные записи в одну техническую категорию, чтобы потом исключить их. Рассмотрим, как это сделать через выражение группировки:
ТипПарка нажмем правой кнопкой мыши и выберем «Установить выражение группировки».
ВЫБОР
КОГДА ТипПарка = "ПОР" И СтанцияНазначения <> "Хабаровск 1" ТОГДА "ИСКЛЮЧИТЬ"
ИНАЧЕ ТипПарка
КОНЕЦ
После этого мы можем наложить отбор на уровне всего отчета: ТипПарка Не Равно "ИСКЛЮЧИТЬ". Это позволит эффективно «отсеять» лишние данные еще на этапе формирования дерева группировок.
В редких случаях, когда нам критически важно сохранить итоги по всем записям (даже тем, которые мы не хотим показывать), можно воспользоваться Условным оформлением. Проанализируем этот подход:
Текст (устанавливаем пустую строку) или Видимость (устанавливаем Ложь).ТипПарка Равно "ПОР" И СтанцияНазначения Не Равно "Хабаровск 1".Важное замечание: Метод с Видимость = Ложь может оставлять пустые строки в некоторых версиях платформы или при определенных настройках вывода (например, в иерархии). Поэтому для реального исключения строк из отчета всегда рекомендуется использовать Отбор.
Выясним причину, по которой автор вопроса не получил желаемого результата через ВычислитьВыражение. Данная функция работает на этапе, когда данные уже выбраны из базы и сгруппированы. Она позволяет «дотянуться» до данных соседних группировок. Например, ВычислитьВыражение("Сумма(СуммаОборот)", , "ОбщийИтог") вернет общую сумму по всему отчету для каждой строки.
Если мы пишем ВычислитьВыражение("СтанцияНазначения", "ТипПарка"), мы просто просим систему вернуть значение станции в контексте текущей группировки ТипПарка. Это никак не ограничивает количество строк, возвращаемых набором данных. Для фильтрации в СКД предназначены исключительно механизмы Отбор (на уровне набора данных, группировки или компоновщика настроек).
Мы рассмотрели несколько способов фильтрации данных внутри группировок. Самым рекомендуемым является создание вычисляемого поля-флага с последующим отбором по нему. Это обеспечивает максимальную гибкость и наглядность логики отчета. Помните, что СКД — это мощный декларативный механизм, и большинство задач в нем решается через правильную настройку метаданных и параметров компоновки, а не через написание сложного программного кода.