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

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

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

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

  1. На уровне "ДокументВыпуска" — количество продукции из документа.
  2. На уровне "Материалы" — пустое значение (или 0).
  3. На уровне "Продукция" — сумма количества продукции из всех соответствующих документов.

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

Подход 1: Использование функции ВычислитьВыражениеСГруппировкойМассив

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

Пример использования:

Для уровня продукции можно попробовать следующее выражение:


Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(КоличествоПродукция)", "ДокументВыпуска"))

Разберем по шагам, как это выражение работает:

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

Ограничения функции ВычислитьВыражениеСГруппировкойМассив

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

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

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

Подход 2: Разделение наборов данных (Рекомендуемое решение)

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

Проанализируем ситуацию: у нас есть два различных показателя с разным составом аналитики:

  1. Количество продукции: Показатель — количество продукции; Аналитика — продукция, документ.
  2. Количество материалов: Показатель — количество материала; Аналитика — продукция, материал, документ.

При таком подходе выражения ресурсов становятся элементарными и не требуют сложных вычислений.

Разберем по шагам реализацию этого подхода:

  1. Создаем отдельные наборы данных:

    Для каждого состава аналитик и соответствующих показателей создадим свой набор данных типа "Запрос".

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

      
      ВЫБРАТЬ
          ВыпускПродукции.ДокументВыпуска КАК ДокументВыпуска,
          ВыпускПродукции.Продукция КАК Продукция,
          СУММА(ВыпускПродукции.КоличествоПродукция) КАК КоличествоПродукция
      ИЗ
          Документ.ВыпускПродукции.Продукция КАК ВыпускПродукцииПродукция
      СГРУППИРОВАТЬ ПО
          ВыпускПродукции.ДокументВыпуска,
          ВыпускПродукции.Продукция
      

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

    • Набор данных для материалов: Создадим запрос, который будет выбирать данные о количестве материалов в разрезе продукции, материалов и документов выпуска. Аналогично, выполним предварительную агрегацию.

      
      ВЫБРАТЬ
          ВыпускПродукции.ДокументВыпуска КАК ДокументВыпуска,
          ВыпускПродукции.Продукция КАК Продукция,
          ВыпускПродукции.Материал КАК Материал,
          СУММА(ВыпускПродукции.КоличествоМатериал) КАК КоличествоМатериал
      ИЗ
          Документ.ВыпускПродукции.Материалы КАК ВыпускПродукцииМатериалы
      СГРУППИРОВАТЬ ПО
          ВыпускПродукции.ДокументВыпуска,
          ВыпускПродукции.Продукция,
          ВыпускПродукции.Материал
      

    Помимо наборов данных типа "Запрос", в СКД также можно использовать "Объект" (для внешних данных, например, таблиц значений) и "Объединение" (для объединения нескольких наборов данных в один).

  2. Настройка ресурсов в СКД:

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

    • Для количества продукции: Сумма(КоличествоПродукция)
    • Для количества материалов: Сумма(КоличествоМатериал)

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

  3. Связывание наборов данных:

    При связывании наборов данных мы определяем один набор как основной (ведущий), а другие — как ведомые. В нашем случае, набор данных с продукцией является основным, так как материалы, как правило, не могут существовать без привязки к продукции. Набор данных с материалами будет ведомым.

    При связывании наборов данных в СКД мы используем механизм, аналогичный соединению таблиц в языке запросов. Чаще всего применяется левое соединение (ЛЕВОЕ СОЕДИНЕНИЕ), чтобы обеспечить вывод всех строк из основного набора, даже если для них нет соответствующих данных в ведомом наборе (например, продукция без материалов).

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

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

  4. Преимущества подхода с разделением наборов данных:

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

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

Общие рекомендации при работе с ресурсами СКД

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

Дополнительная настройка ресурсов в СКД

Для более тонкой настройки вывода ресурсов и их поведения мы можем использовать следующие возможности СКД:

  1. Вкладка "Ресурсы": Все настройки итогов производятся на вкладке "Ресурсы" в конфигураторе СКД. Здесь мы можем:

    • Выбрать поля из запроса, которые будут являться ресурсами.
    • Установить для них агрегатную функцию (СУММА, СРЕДНЕЕ, МАКСИМУМ, МИНИМУМ, КОЛИЧЕСТВО, КОЛИЧЕСТВО РАЗЛИЧНЫХ).
    • Комбинировать функции и писать целые формулы в поле "Выражение", хотя, как мы выяснили, это часто усложняет расчет и может приводить к ошибкам, поэтому рекомендуется максимально упрощать выражения за счет предварительной обработки данных в наборах.
  2. Поле "Рассчитывать по": Используйте это поле для точного указания группировки, по которой должен производиться расчет ресурса. Это позволяет настроить сложные схемы агрегации и выводить ресурс только для определенных уровней или в общих итогах.

  3. Вывод ресурсов на разных уровнях группировки: В СКД можно настроить вывод ресурсов только для определенных уровней иерархии или только в итоговых строках. Это делается через настройки отчета на вкладке "Настройки", где можно для каждой группировки или для общих итогов явно указать, какие ресурсы должны выводиться. Также можно использовать функцию "Итоги по" для более детальной настройки.

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

  5. Группировки по ресурсам: Помимо вывода, СКД также позволяет группировать данные по значениям ресурсов. Это может быть полезно для анализа распределения данных по определенным показателям, например, группировка всех документов по диапазонам количества выпущенной продукции.

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

← На главную