Как рассчитать и вывести процент потребления в отчетах СКД с отбором по нему для вышестоящих группировок?

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

При создании сложных отчетов в системе компоновки данных (СКД) 1С часто возникает задача, когда необходимо вычислить агрегированный показатель (например, процент) на одном уровне группировки, отобразить его выборочно и затем использовать этот показатель для отбора данных на вышестоящих уровнях группировок. Разберем эту ситуацию на примере расчета "процента потребления", который должен быть виден только для промежуточной группировки, а затем использоваться для фильтрации данных по родительским группам.

Представим себе следующую структуру отчета:

  1. Детальные записи: План и Потребление (например, по "Яблокам" и "Огурцам").
  2. Промежуточная группировка: "Виды продовольствия" (например, "Фрукты", "Овощи"). На этом уровне нам нужно суммировать план и потребление по каждому виду и рассчитать процент выполнения (Потребление / План).
  3. Вышестоящие группировки: "ФИО", "Пол", "Возрастные группы". На этих уровнях нам не нужен сам процент, но необходимо иметь возможность отбирать данные (например, "показать всех, кто потребил фруктов или овощей больше 100%").

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

1. Расчет процента потребления в СКД

Существует несколько подходов к расчету процента потребления. Мы рассмотрим наиболее распространенные и гибкие для СКД.

1.1. Расчет процента как ресурса СКД

Этот метод является предпочтительным, поскольку он позволяет СКД самостоятельно выполнять агрегацию и расчет на нужных уровнях.

  1. Создаем вычисляемое поле: Прежде всего, убедимся, что у нас есть поля "План" и "Потребление" (или "Приход" и "Расход" как в примере форума). Добавим новое вычисляемое поле в схему компоновки данных, например, ПроцентПотребления.
  2. Настраиваем ресурс для промежуточной группировки:

    Для группировки, где нам нужен фактический процент (в нашем случае это "Виды продовольствия" или "ФруктыОвощи"), мы указываем простую формулу отношения потребления к плану. Переходим на вкладку "Ресурсы" и для поля ПроцентПотребления задаем выражение:

    СУММА(Потребление) / СУММА(План) * 100

    Или, если используются поля "Расход" и "Приход" из регистра накопления:

    СУММА(Расход) / СУММА(Приход) * 100

    На этом же шаге очень важно в свойстве ресурса "Рассчитывать по" указать только те группировки, для которых этот расчет имеет смысл и должен быть выведен. В нашем случае это будет группировка "Вид продовольствия". Для всех остальных группировок (ФИО, Пол и т.д.) мы можем пока оставить "Авто" или "Ничего", но в дальнейшем нам потребуется более тонкая настройка.

  3. Настраиваем ресурс для вышестоящих группировок с использованием ВычислитьВыражениеСГруппировкойМассив:

    Чтобы иметь возможность использовать процент, рассчитанный на уровне "Вид продовольствия", для отбора или отображения на вышестоящих уровнях, нам потребуется специальная функция СКД: ВычислитьВыражениеСГруппировкойМассив. Эта функция позволяет вычислить выражение для определенной группировки и получить массив результатов, из которого затем можно выбрать агрегированное значение (например, максимум, минимум, среднее). Это особенно полезно, когда нам нужен не общий суммарный процент, а, например, максимальный процент потребления для любого вида продовольствия внутри группы "ФИО".

    Добавим в ресурсы еще одно поле, например, ПроцентДляОтбора. Для этого поля в выражении ресурса мы используем следующую конструкцию:

    
    МАКСИМУМ(ВычислитьВыражениеСГруппировкойМассив("СУММА(Расход)/СУММА(Приход) * 100","ВидПродовольствия"))
    

    Здесь:

    • "СУММА(Расход)/СУММА(Приход) * 100" – это выражение, которое мы хотим вычислить для каждой подгруппы.
    • "ВидПродовольствия" – это имя группировки, для которой должно быть вычислено это выражение.
    • МАКСИМУМ(...) – агрегирующая функция, которая берет максимальное значение из полученного массива процентов для данной вышестоящей группировки (например, для конкретного ФИО). Вы можете выбрать МИНИМУМ, СРЕДНЕЕ или другую агрегатную функцию в зависимости от вашей бизнес-логики.

    Для этого нового ресурса ПроцентДляОтбора мы устанавливаем "Рассчитывать по" на уровне, который должен его использовать для отбора (например, "ФИО", "Пол", "Возрастные группы"), но не на уровне "Вид продовольствия" или детальных записей, если там он не нужен.

1.2. Расчет процента в запросе

Вы можете рассчитать процент непосредственно в запросе к регистрам накопления, например, как Расход / Приход. Однако, при таком подходе могут возникнуть сложности с агрегацией на разных уровнях группировок. Процент, рассчитанный для детальных записей, не всегда корректно суммируется или агрегируется на верхних уровнях. Если вы рассчитываете процент в запросе, он будет являться полем, а не ресурсом, и тогда его агрегация на разных уровнях будет определяться функцией агрегации для этого поля в СКД.


ВЫБРАТЬ
    Регистр.Измерение1,
    Регистр.Измерение2,
    Регистр.План,
    Регистр.Потребление,
    ВЫБОР КОГДА Регистр.План = 0 ТОГДА 0 ИНАЧЕ Регистр.Потребление / Регистр.План * 100 КОНЕЦ КАК ПроцентВЗапросе
ИЗ
    РегистрНакопления.МойРегистр КАК Регистр

Если вы идете этим путем, то поле ПроцентВЗапросе затем нужно будет либо агрегировать как МАКСИМУМ(ПроцентВЗапросе) или СРЕДНЕЕ(ПроцентВЗапросе) на нужных уровнях, либо использовать ВычислитьВыражениеСГруппировкойМассив с этим полем.

1.3. Виртуальные вложенные поля для процентов

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

2. Скрытие процента в ненужных группировках

После того как мы рассчитали процент, нам необходимо решить проблему его отображения. Согласно задаче, процент должен выводиться только для промежуточной группировки ("Виды продовольствия"), а для вышестоящих группировок (ФИО, Пол, ВозрастныеГруппы) его отображать не нужно.

2.1. Использование условного оформления

Это наиболее гибкий и часто используемый метод для выборочного отображения данных.

  1. Открываем настройки условного оформления: Перейдите на вкладку "Условное оформление" в настройках отчета.
  2. Создаем элемент условного оформления:
    • В поле "Оформляемые поля" выберите ваш ресурс ПроцентПотребления (или ПроцентДляОтбора, если вы его используете для отображения).
    • В поле "Условие" нам нужно указать, когда процент не должен отображаться. Для этого мы можем использовать системное поле УровеньГруппировки или ТипГруппировки.

      Если вы хотите скрыть процент на всех уровнях, кроме уровня "Вид продовольствия", условие может выглядеть так:

      Не СТРОКА(УровеньГруппировки) = "ВидПродовольствия"

      Или, если мы хотим скрыть для конкретных уровней:

      
      УровеньГруппировки В (<ИмяГруппировкиФИО>, <ИмяГруппировкиПол>, <ИмяГруппировкиВозраст>)
      

      В более старых версиях СКД или при сложных группировках может быть удобнее использовать условие на "Не выбрана группировка".

    • В поле "Оформление" установите свойство "Текст" в пустую строку (`""`). Это заставит СКД не выводить значение в ячейке. Также можно установить "Цвет текста" в цвет фона, чтобы сделать его невидимым.

Важно: При использовании кросс-таблиц (когда у нас есть группировки строк и группировки колонок), условное оформление часто является основным инструментом для управления отображением ячеек, так как стандартные настройки вывода ресурса могут вести себя непредсказуемо.

2.2. Настройки вывода ресурса ("Рассчитывать по") и дублирование ресурсов

Этот подход был упомянут на форуме и может быть использован в некоторых случаях:

  1. Добавляем ресурс несколько раз:

    Первый раз добавляем ресурс ПроцентПотребления с выражением СУММА(Расход) / СУММА(Приход) * 100 и указываем для него "Рассчитывать по" только нужную группировку ("Вид продовольствия").

    Второй раз добавляем тот же ресурс (или его копию с другим именем) с выражением 0 или просто NULL (пустое значение) и указываем "Рассчитывать по" для всех остальных группировок (ФИО, Пол, Возрастные группы). Это позволит вывести нужные значения только там, где это требуется, а в остальных местах показать 0 или пустоту.

  2. Отключение поля в группировке:

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

3. Отбор по проценту для верхних группировок

Это, пожалуй, наиболее сложная часть задачи. Нам нужно отобрать, например, всех "ФИО", у которых хотя бы один "Вид продовольствия" (например, фрукты) был потреблен на 100% или более. Прямой отбор по ресурсу ПроцентПотребления на уровне вышестоящей группировки не всегда работает корректно или вообще не доступен.

3.1. Использование вычисляемого поля для отбора

Наиболее надежный способ — создать специальное вычисляемое поле, которое будет "подтягивать" агрегированный процент с нижнего уровня группировки на верхний и по которому затем можно будет установить отбор. Здесь нам снова пригодится ВычислитьВыражениеСГруппировкойМассив.

  1. Создаем новое вычисляемое поле: Перейдите на вкладку "Вычисляемые поля" в СКД. Добавьте новое поле, назовем его, например, ПроцентДляФильтрации.
  2. Задаем выражение для вычисляемого поля:

    Выражение должно получать процент из целевой группировки ("Виды продовольствия") и агрегировать его для вышестоящего уровня. Например, если нам нужно отбирать ФИО, у которых *хотя бы один* вид продовольствия потреблен больше 100%, мы используем:

    
    МАКСИМУМ(ВычислитьВыражениеСГруппировкойМассив("СУММА(Расход)/СУММА(Приход) * 100","ВидПродовольствия"))
    

    Это выражение вернет максимальный процент потребления по любому виду продовольствия для текущей вышестоящей группировки (например, для конкретного ФИО). Если нам нужен был бы минимальный, использовали бы МИНИМУМ.

    Убедитесь, что это вычисляемое поле доступно на том уровне, где вы планируете устанавливать отбор (например, в группировке "ФИО").

  3. Устанавливаем отбор по новому вычисляемому полю:

    Перейдите на вкладку "Отбор" в настройках отчета. Добавьте новый элемент отбора:

    • В поле "Поле" выберите созданное вычисляемое поле ПроцентДляФильтрации.
    • В поле "Вид сравнения" выберите "Больше или равно".
    • В поле "Значение" укажите 100 (или 1, если вы не умножали на 100).

    Этот отбор можно установить на корневом уровне отчета или непосредственно на уровне той группировки, которую вы хотите фильтровать (например, на группировке "ФИО").

Важно: Отбор по группировкам (в настройках группировки, а не на вкладке "Отбор" отчета) будет фильтровать записи, выводимые в самой группировке, и распространяться на вложенные группировки. Но он не влияет на другие группировки в отчете. Если установить отбор по проценту в группировке "Вид продовольствия", то эта группировка не будет выведена, если не попала в отбор. Однако, вышестоящий уровень может выводиться, так как его отбор не затрагивает. Именно поэтому нам и нужно вычисляемое поле, которое поднимает агрегированное значение на верхний уровень.

3.2. Использование пользовательских полей

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

  1. Создаем пользовательское поле: Перейдите на вкладку "Пользовательские поля" в СКД. Добавьте новое поле.
  2. Задаем выражение: Пользовательское поле может содержать более сложное выражение для расчета процента или для его получения из другой группировки, возможно, с дополнительной логикой. Например, вы можете создать пользовательское поле, которое напрямую проверяет условие:
  3. 
    Выбор Когда МАКСИМУМ(ВычислитьВыражениеСГруппировкойМассив("СУММА(Расход)/СУММА(Приход)","ВидПродовольствия")) > 1 Тогда Истина Иначе Ложь Конец
    

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

Этот подход дает большую гибкость, но требует более глубокого понимания логики СКД и синтаксиса выражений.

4. Особенности работы с кросс-таблицами

Как было упомянуто в ходе обсуждения, в кросс-таблицах (отчетах, где есть как группировки строк, так и группировки колонок) стандартные подходы к скрытию и отбору могут работать иначе. В таких случаях:

Заключительные рекомендации

Создание сложных отчетов в СКД требует внимательности и поэтапной отладки. Мы рекомендуем:

  1. Поэтапная проверка: Всегда проверяйте расчеты на различных уровнях группировок, убеждаясь в их корректности перед переходом к следующему шагу.
  2. Конструктор настроек СКД: Активно используйте конструктор настроек СКД и режим отладки для пошаговой проверки результатов расчетов и отборов.
  3. Документация ИТС: Обращайтесь к документации ИТС для получения актуальной информации о функциях и возможностях СКД, особенно по новым версиям платформы.
  4. Проблемы платформы: Имейте в виду, что в более старых версиях платформы (например, 8.3.13 – 8.3.17) могли существовать проблемы с наложением отборов на несуществующие поля в запросах объединения, которые могли приводить к некорректной работе отборов (например, СКД добавляла в секции "ГДЕ" NULL=&П). Эти проблемы обычно исправлялись в последующих релизах (например, в 8.3.18).

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

← На главную