При разработке отчетов на системе компоновки данных (СКД) программисты часто сталкиваются с задачей, когда расчет итогов должен отличаться в зависимости от уровня вложенности группировок. Классический пример: отчет по монтажникам и их заказам. В группировке по заказам нам нужно видеть просто сумму документа, а в итогах по монтажнику — сумму всех его заказов плюс фиксированную надбавку или фиксированные расходы (например, 8000 рублей).
Разберем подробно, почему стандартные подходы через вычисляемые поля могут не сработать и как правильно настроить ресурсы СКД для решения этой задачи.
Рассмотрим ситуацию, которую часто пытаются реализовать новички. Создается вычисляемое поле с выражением СуммаЗаказа + 8000. На первый взгляд, это кажется логичным, но на практике приводит к ошибке в расчетах. Проанализируем причину: если у монтажника есть 10 заказов, то система прибавит 8000 к каждой строке (к каждому заказу). В итоге в общих итогах по монтажнику мы получим СуммаВсехЗаказов + (10 * 8000), что составит 80000 вместо ожидаемых 8000.
СКД работает по принципу агрегации. Если поле не является ресурсом, оно выводится "как есть" в детальных записях. Если мы делаем его ресурсом с функцией Сумма(), СКД суммирует все значения, полученные на уровне детальных записей. Именно поэтому для решения задачи необходимо использовать возможности вкладки Ресурсы.
Самый эффективный способ — настроить разные формулы расчета для одного и того же ресурса в зависимости от того, для какой группировки рассчитывается итог. Разберем этот процесс по шагам.
СуммаЗаказа в список ресурсов.
Сумма(СуммаЗаказа)
В колонке Рассчитывать по... выберем группировку Заказ (или укажем все группировки, кроме монтажника).СуммаЗаказа. В колонке Выражение напишем формулу с учетом надбавки:
Сумма(СуммаЗаказа) + 8000
В колонке Рассчитывать по... выберем только группировку Монтажник.Таким образом, когда СКД будет формировать строку по конкретному заказу, она применит первую формулу. Когда же дело дойдет до формирования итоговой строки по монтажнику, система возьмет вторую формулу, которая прибавит 8000 к уже накопленной сумме всех заказов этого монтажника.
Иногда возникает специфическое требование: в группировках нижнего уровня (заказы) поле должно быть пустым или содержать 0, а в группировке верхнего уровня (монтажник) — отображать полную сумму с надбавкой. Выясним, как это реализовать.
Для этого в ресурсах для группировки Заказ мы просто указываем в выражении 0. Настройка будет выглядеть следующим образом:
0
Сумма(СуммаЗаказа) + 8000
Сумма(СуммаЗаказа) + Количество(Различные Монтажник) * 8000
Если надбавка не является статичной (например, она должна рассчитываться динамически или зависеть от данных других уровней), можно прибегнуть к более мощному инструменту — функции ВычислитьВыражение. Рассмотрим пример:
В выражении ресурса мы можем написать конструкцию, которая обращается к контексту группировки:
ВычислитьВыражение("Сумма(СуммаЗаказа)", "Монтажник") + 8000
Этот метод гарантирует, что расчет будет привязан именно к итоговым значениям указанной иерархии. Функция ВычислитьВыражение позволяет гибко управлять тем, на каком уровне и какие данные мы хотим получить для расчетов.
При проектировании таких отчетов следует учитывать несколько критически важных моментов, которые помогут избежать ошибок в данных:
1. Обработка пустых значений (NULL)
В выражениях СКД, особенно если данные берутся из левых соединений в запросе, рекомендуется всегда использовать функцию ЕстьNull. Если СуммаЗаказа окажется NULL, то прибавление к нему любого числа в результате даст NULL, и данные в отчете могут просто исчезнуть. Правильное выражение:
Сумма(ЕстьNull(СуммаЗаказа, 0)) + 8000
2. Использование параметров вместо констант
Вместо того чтобы жестко прописывать число 8000 в схеме компоновки, лучше создать параметр &ФиксированнаяНадбавка. Это позволит пользователю менять сумму через настройки отчета без привлечения программиста. Выражение в ресурсах примет вид:
Сумма(СуммаЗаказа) + &ФиксированнаяНадбавка
3. Настройка Общего итога
По умолчанию СКД считает Общий итог как агрегат по всем детальным записям. Если у нас 5 монтажников, и к каждому должна добавиться надбавка, то в общем итоге мы должны увидеть Сумма всех заказов + 5 * 8000. Чтобы это работало корректно, для поля "Общий итог" в ресурсах нужно прописать специальную формулу, использующую агрегат по группировкам:
Сумма(СуммаЗаказа) + ВычислитьВыражениеАгрегат("Количество(Различные Монтажник)", "ОбщийИтог") * 8000
Мы проанализировали ситуацию и выяснили, что гибкость СКД позволяет решать задачи любой сложности с расчетом итогов. Основной секрет кроется в понимании того, как работают ресурсы. Помните: вкладка "Ресурсы" — это основной инструмент управления итоговыми значениями. Использование разных формул для разных уровней группировок (колонки "Рассчитывать по") — это наиболее надежный и прозрачный способ настройки отчетов в 1С.