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