Как в СКД скрыть строки, в которых значения ресурсов во всех колонках одинаковы?

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

При построении отчетов в системе компоновки данных (СКД) разработчики часто сталкиваются с необходимостью формирования двумерных таблиц (кросс-таблиц). Типичный пример: строки по Номенклатуре, колонки по Складам, а на пересечении — ресурс КоличествоОстаток. Иногда возникает специфическая задача: нужно скрыть те строки, где значения ресурса во всех колонках (по всем складам) совпадают. Например, если на всех складах остаток товара равен 10 единицам, такая строка неинформативна и ее нужно убрать из отчета.

Сложность заключается в том, что в кросс-таблице состав колонок динамический и зависит от данных в базе. Мы не можем заранее прописать в отборе условие типа Склад1 = Склад2, так как количество складов и их названия заранее неизвестны. В этой статье мы разберем несколько эффективных методов решения этой задачи: от настроек в пользовательском режиме до оптимизации запроса.

Способ 1: Использование агрегатных функций в отборе группировки

Это наиболее элегантный и «чистый» способ решения задачи средствами самой СКД. Система позволяет накладывать условия не только на детальные записи, но и на целые группировки, используя агрегатные функции. Проанализируем логику: если значения ресурса во всех колонках (ячейках) строки одинаковы, то минимальное значение в этой строке будет равно максимальному.

Для реализации этого метода выполним следующие шаги:

  1. Откроем настройки отчета в конфигураторе или в режиме «1С:Предприятие».
  2. Выберем группировку, для которой нужно применить фильтр (в нашем примере это Номенклатура).
  3. Перейдем на вкладку Отбор именно для этой группировки (не общий отбор отчета!).
  4. Добавим новое условие. В качестве левого значения выберем наш ресурс, но обернем его в агрегатную функцию. В интерфейсе это выглядит как выбор поля Максимум(Остаток).
  5. Установим вид сравнения Не равно.
  6. В качестве правого значения выберем поле Минимум(Остаток).

Таким образом, СКД сначала рассчитает все ресурсы по строке, а затем выведет только те строки, где Максимум <> Минимум. Если остатки по всем складам одинаковы, строка будет скрыта.

Способ 2: Использование функции Количество(Различные ...)

Разберем еще один вариант настройки отбора, который базируется на подсчете уникальных значений. Если во всех колонках строки стоит одно и то же число, то количество различных значений в этой строке будет равно единице.

Рассмотрим настройку отбора для группировки Номенклатура:

  1. Добавим условие отбора.
  2. В левой части укажем выражение: Количество(Различные Остаток).
  3. Вид сравнения: Больше.
  4. Правое значение: 1.

Важный нюанс: при использовании этого метода нужно быть внимательными с пустыми значениями (NULL). Если по какому-то складу движения отсутствуют, СКД может не учитывать это поле в подсчете различных значений, или наоборот, посчитать NULL как отдельное уникальное значение. Чтобы избежать ошибок, рекомендуется в схеме компоновки данных для ресурса использовать выражение ЕстьNull(Остаток, 0).

Способ 3: Фильтрация на уровне запроса

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

Проанализируем пример кода запроса, который подготовит данные для СКД:


ВЫБРАТЬ
    Остатки.Номенклатура КАК Номенклатура,
    Остатки.Склад КАК Склад,
    Остатки.КоличествоОстаток КАК КоличествоОстаток
ПОМЕСТИТЬ ВТ_Данные
ИЗ
    РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Данные.Номенклатура
ИЗ
    ВТ_Данные КАК Данные
СГРУППИРОВАТЬ ПО
    Данные.Номенклатура
ИМЕЮЩИЕ
    МАКСИМУМ(Данные.КоличествоОстаток) <> МИНИМУМ(Данные.КоличествоОстаток)

После этого мы можем соединить полученный список «изменившейся» номенклатуры с исходными данными. Это гарантирует, что в СКД попадут только те строки, которые имеют различия между складами. Этот метод работает быстрее на огромных объемах данных, так как уменьшает количество записей, передаваемых в процессор компоновки.

Способ 4: Использование вычисляемых полей и агрегата Массив()

В более сложных случаях, когда сравнение Минимум/Максимум недостаточно (например, если нужно сравнивать не числа, а строки или сложные объекты), мы можем воспользоваться функцией Массив(). Рассмотрим этот продвинутый метод.

В СКД можно создать вычисляемое поле, выражение которого будет собирать все значения ресурсов в одну коллекцию. Затем мы можем передать этот массив в функцию общего модуля для анализа.

Пример выражения для ресурса в СКД:

ВычислитьВыражение("Массив(Остаток)", "Номенклатура")

Далее в общем модуле (с флагом "Сервер") создадим функцию:


Функция ЕстьРазличияВМассиве(МассивЗначений) Экспорт
    Если МассивЗначений.Количество() < 2 Тогда
        Возврат Ложь;
    КонецЕсли;
    
    ПервоеЗначение = МассивЗначений[0];
    Для Каждого ТекущееЗначение Из МассивЗначений Цикл
        Если ТекущееЗначение <> ПервоеЗначение Тогда
            Возврат Истина;
        КонецЕсли;
    КонецЦикла;
    
    Возврат Ложь;
КонецФункции

Этот метод позволяет реализовать практически любую логику сравнения, включая игнорирование определенных складов или учет допустимой погрешности (например, если разница меньше 0.001, то считать значения одинаковыми).

Особенности работы с иерархией

Проанализируем ситуацию, когда в отчете используется иерархия номенклатуры. Нужно помнить, что агрегатные функции в СКД работают на каждом уровне группировки. Если мы наложим условие Максимум(Остаток) <> Минимум(Остаток) на иерархическую группу, результат может быть непредсказуемым, так как значения ресурсов в группах — это суммы их дочерних элементов.

Рекомендация: Чтобы отбор корректно работал только для конечных элементов номенклатуры, в настройках отбора СКД на уровне группировки укажите тип записи. В поле "Использование" выберите "Только для элементов" или проверьте условие ЭтоГруппа = Ложь, если такое поле есть в вашем наборе данных.

Резюме

Мы рассмотрели несколько способов решения задачи фильтрации одинаковых значений в кросс-таблице СКД. Выбор конкретного метода зависит от ваших целей:

  1. Способ с отбором Минимум/Максимум — самый быстрый в реализации и не требует изменения кода.
  2. Способ с запросом — наиболее производительный для больших отчетов.
  3. Способ с функциями общего модуля — самый гибкий, позволяющий реализовать сложную бизнес-логику.

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

← На главную