При разработке отчетов на Системе компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда на уровне детальных записей или мелких группировок (день, месяц) ресурсы рассчитываются идеально, но на уровне общих итогов или крупных периодов (год) данные либо пропадают, либо принимают совершенно нелогичные значения. Разберем по шагам, почему это происходит и какие инструменты предоставляет 1С для решения этой задачи.
Рассмотрим ситуацию: в отчете за день и месяц данные выводятся корректно, а в строке «Год» результат пуст или равен нулю. Первое, на что стоит обратить внимание — это использование функции ВычислитьВыражение в поле ресурса. Проблема заключается в том, что по умолчанию эта функция работает в контексте текущей группировки.
Если выражение настроено для уровня «Месяц» и не содержит четких инструкций по обработке вышестоящих уровней, СКД на уровне года «теряется». Система не понимает, как именно нужно агрегировать данные месяцев: сложить их, найти среднее или взять максимальное значение. Без явного указания алгоритма агрегации для вышестоящих уровней иерархии итог не будет сформирован.
Выясним причину некорректных сумм, о которой часто упоминают разработчики. Если в одном месяце значение (например, 1200) встречается 10 раз из-за особенностей ЛевоеСоединение в запросе (когда к одной записи основной таблицы цепляется несколько записей из подчиненной), то обычная функция Сумма(Поле) выдаст 12 000 вместо ожидаемых 1200.
Проанализируем ситуацию: на уровне месяца программист может «схитрить», применив функцию Максимум(Поле), которая вернет корректные 1200. Однако при переходе на уровень года простая сумма максимумов работать не будет, если не настроить выражение ресурсов специальным образом.
Это наиболее мощный и гибкий инструмент в арсенале разработчика СКД. Данная функция позволяет собрать данные из дочерних группировок в массив и затем применить к этому массиву любую агрегатную функцию (Сумма, Среднее, Максимум). Рассмотрим подробнее, как составить такое выражение для ресурса.
Допустим, наше поле называется Бал_Сотрудника, а группировка, по которой мы хотим подводить промежуточные итоги, называется ПериодМесяц. Нам нужно, чтобы в году суммировались максимальные баллы за каждый месяц. Напишем следующее выражение в колонке «Выражение» на закладке «Ресурсы»:
Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(Бал_Сотрудника)", "ПериодМесяц"))
Разберем, что делает этот код:
ПериодМесяц.Максимум(Бал_Сотрудника) (это позволяет нам отсечь те самые дубли, возникшие при соединении таблиц).Сумма складывает все элементы этого массива и выводит итоговый результат в строку «Год».Посмотрим на альтернативный способ, который не требует написания сложных формул. В СКД на закладке «Ресурсы» можно добавлять одно и то же поле несколько раз, указывая разные способы расчета для разных группировок.
Проанализируем шаги настройки:
Бал_Сотрудника с выражением Максимум(Бал_Сотрудника). В колонке «Рассчитывать по...» выбираем все уровни, кроме «Год» и «Общий итог».Бал_Сотрудника еще раз. Но в выражении пишем логику агрегации (например, через ВычислитьВыражениеСГруппировкойМассив, как описано выше). В колонке «Рассчитывать по...» указываем только «Год» и «Общий итог».Такой подход позволяет гибко управлять логикой: на нижних уровнях мы боремся с дублями, а на верхних — правильно суммируем очищенные данные.
Как справедливо замечают опытные разработчики, использование тяжелых функций в ресурсах СКД (таких как ВычислитьВыражениеСГруппировкойМассив) может существенно замедлить формирование отчета на больших объемах данных. Это происходит потому, что вычисления выполняются не на стороне SQL-сервера, а в памяти сервера приложений 1С после получения всех сырых данных.
Рассмотрим более производительный вариант — перенос логики в текст запроса. Чтобы избежать дублирования данных и проблем с итогами, рекомендуется:
СГРУППИРОВАТЬ ПО непосредственно в источнике данных, чтобы в компоновку попадали уникальные записи.ПериодМесяц правильно указана роль «Период» и определен его родитель (например, ПериодГод). Это помогает СКД автоматически строить иерархию.Мы проанализировали ситуацию, когда итоги в СКД не считаются на верхних уровнях иерархии. Основная причина — неопределенность контекста при использовании функций вычисления выражений и наличие дублей в исходных данных.
Важные моменты для запоминания:
ВычислитьВыражениеСГруппировкойМассив — ваш главный помощник, когда нужно просуммировать результаты других функций (например, сумму максимумов).Используя эти методы, вы сможете добиться корректного отображения данных на любом уровне детализации отчета, обеспечив точность и достоверность управленческой или бухгалтерской отчетности.