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

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

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

Анализируем причину проблемы: механизм работы контекста в СКД

Рассмотрим ситуацию: в отчете за день и месяц данные выводятся корректно, а в строке «Год» результат пуст или равен нулю. Первое, на что стоит обратить внимание — это использование функции ВычислитьВыражение в поле ресурса. Проблема заключается в том, что по умолчанию эта функция работает в контексте текущей группировки.

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

Проблема «размножения» данных при соединениях

Выясним причину некорректных сумм, о которой часто упоминают разработчики. Если в одном месяце значение (например, 1200) встречается 10 раз из-за особенностей ЛевоеСоединение в запросе (когда к одной записи основной таблицы цепляется несколько записей из подчиненной), то обычная функция Сумма(Поле) выдаст 12 000 вместо ожидаемых 1200.

Проанализируем ситуацию: на уровне месяца программист может «схитрить», применив функцию Максимум(Поле), которая вернет корректные 1200. Однако при переходе на уровень года простая сумма максимумов работать не будет, если не настроить выражение ресурсов специальным образом.

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

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

Допустим, наше поле называется Бал_Сотрудника, а группировка, по которой мы хотим подводить промежуточные итоги, называется ПериодМесяц. Нам нужно, чтобы в году суммировались максимальные баллы за каждый месяц. Напишем следующее выражение в колонке «Выражение» на закладке «Ресурсы»:


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

Разберем, что делает этот код:

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

Решение №2: Тонкая настройка расчета по группировкам

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

Проанализируем шаги настройки:

  1. Для детальных записей и месяцев: Добавляем ресурс Бал_Сотрудника с выражением Максимум(Бал_Сотрудника). В колонке «Рассчитывать по...» выбираем все уровни, кроме «Год» и «Общий итог».
  2. Для итогов по году: Добавляем ту же колонку Бал_Сотрудника еще раз. Но в выражении пишем логику агрегации (например, через ВычислитьВыражениеСГруппировкойМассив, как описано выше). В колонке «Рассчитывать по...» указываем только «Год» и «Общий итог».

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

Решение №3: Исправление архитектуры запроса

Как справедливо замечают опытные разработчики, использование тяжелых функций в ресурсах СКД (таких как ВычислитьВыражениеСГруппировкойМассив) может существенно замедлить формирование отчета на больших объемах данных. Это происходит потому, что вычисления выполняются не на стороне SQL-сервера, а в памяти сервера приложений 1С после получения всех сырых данных.

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

Подведение итогов

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

Важные моменты для запоминания:

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

← На главную