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

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

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

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

Решение 1. Использование функции ВычислитьВыражениеСГруппировкойМассив и колонки "Рассчитывать по"

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

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

  1. Для группировки по подразделению:

    Задаем агрегатное выражение, которое выбирает уникальное значение лимита подразделения:

    Максимум(СуммаПоПодразделению)

    В колонке Рассчитывать по... выбираем группировку Подразделение.

  2. Для вышестоящих группировок и Общего итога:

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

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

    В колонке Рассчитывать по... указываем вышестоящие группировки или оставляем значение Общий итог.

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

Решение 2. Разделение наборов данных в СКД

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

  1. Набор данных 1 (План/Лимиты): Выбираем поля Подразделение и СуммаПоПодразделению без соединения с детальными таблицами документов.
  2. Набор данных 2 (Факт/Документы): Выбираем детализированные данные — Подразделение, Документ и СуммаДокумента.
  3. Связи наборов данных: Настраиваем связь между наборами по полю Подразделение.

В этом случае плановые лимиты хранятся строго в одной строке на уровне подразделения. Стандартный ресурс Сумма(СуммаПоПодразделению) начинает рассчитываться корректно на всех уровнях иерархии без дополнительных функций в ресурсах.

Решение 3. Разделение данных через ОБЪЕДИНИТЬ ВСЕ в одном запросе

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


ВЫБРАТЬ
    Лимиты.Подразделение КАК Подразделение,
    NULL КАК Документ,
    Лимиты.СуммаПоПодразделению КАК СуммаПоПодразделению,
    0 КАК СуммаДокумента
ИЗ
    РегистрСведений.ЛимитыПодразделений КАК Лимиты

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    Документы.Подразделение КАК Подразделение,
    Документы.Ссылка КАК Документ,
    0 КАК СуммаПоПодразделению,
    Документы.Сумма КАК СуммаДокумента
ИЗ
    Документ.ПрочийРасход КАК Документы

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

Тонкости и рекомендации по работе с функциями СКД

Рассмотри дополнительные особенности, которые нужно учитывать при работе с функциями группы ВычислитьВыражение:

  1. Учет иерархии справочника: Если группировка Подразделение используется с иерархией, для правильного расчета итогов передайте четвертый параметр "Иерархия" в функцию:
    
    Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(СуммаПоПодразделению)", "Подразделение", , "Иерархия"))
    
  2. Защита от пустых значений: Для предотвращения ошибок расчета при отсутствии документов или не зафиксированных лимитах оберните выражение в функцию ЕСТЬNULL:
    
    Сумма(ЕСТЬNULL(ВычислитьВыражениеСГруппировкойМассив("Максимум(СуммаПоПодразделению)", "Подразделение"), 0))
    
  3. Влияние на производительность: Обратите внимание, что расчеты через ВычислитьВыражениеСГруппировкойМассив выполняются в оперативной памяти при компоновке макета. На больших объемах данных (десятки тысяч строк) этот метод может замедлять формирование отчета. В таких ситуациях рекомендуется отдавать предпочтение разнесению данных по наборам данных или использованию конструкции ОБЪЕДИНИТЬ ВСЕ в запросе.
← На главную