Как правильно рассчитать итоги по вычисляемым полям в СКД при использовании функции ВычислитьВыражение?

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

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

Почему не считаются итоги в стандартном вычисляемом поле?

Выясним причину такого поведения системы. Когда мы прописываем формулу в вычисляемом поле, СКД пытается применить её на каждом уровне группировки. Если формула выглядит так:


Оборот / ВычислитьВыражение("Сумма(Оборот)", "Контрагент", "Группировка") * Параметр

то на уровне строки «Номенклатура» она работает корректно, так как родительская группировка Контрагент определена однозначно. Но как только компоновщик переходит к расчету итога по уровню «Менеджер», контекст группировки Контрагент «размывается». Система не понимает, сумму какого именно контрагента брать для расчета, так как у одного менеджера их может быть множество. В результате функция возвращает NULL или 0.

Решение 1: Использование ресурсов вместо вычисляемых полей

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

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


Сумма(ВычислитьВыражениеСГруппировкойМассив("Оборот / ВычислитьВыражение(""Сумма(Оборот)"", ""Контрагент"") * Параметр", "Номенклатура"))

Разберем по шагам, как это работает:

  1. Функция ВычислитьВыражениеСГруппировкойМассив обходит все записи группировки Номенклатура.
  2. Для каждой записи она вычисляет пропорцию относительно Контрагента.
  3. Все полученные результаты собираются в массив.
  4. Внешняя функция Сумма складывает элементы этого массива, что дает корректный итог для Менеджера и Общего итога.

Решение 2: Разделение формул по уровням группировок

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

Настройка будет выглядеть следующим образом:

  1. Для группировки Номенклатура указываем прямую формулу расчета доли.
  2. Для группировок Менеджер и Общий итог указываем выражение Сумма(НазваниеВашегоПоля).
  3. В колонке «Рассчитывать по...» для каждой строки выбираем соответствующую группировку.

Это исключает попытки СКД применить логику с контекстом контрагента там, где этот контекст недоступен.

Решение 3: Добавление дополнительного набора данных

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

В этом случае в основном наборе данных у вас всегда будет доступно поле ОборотПоКонтрагенту, которое будет одинаковым для всех строк номенклатуры этого контрагента. Тогда формула превращается в простую арифметику:

Оборот / ОборотПоКонтрагенту * Параметр

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

Важные рекомендации по оформлению

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

  1. Используйте функцию ЕстьNULL(Значение, 0) в формулах ресурсов, чтобы избежать пустых ячеек в итогах.
  2. В условном оформлении можно настроить «Формат» для числовых полей, чтобы вместо нулей выводились прочерки или другие символы, что поможет визуально отличить рассчитанный ноль от отсутствия данных.
  3. Всегда проверяйте порядок расчета: вычисляемые поля рассчитываются до ресурсов. Если вы используете агрегатные функции в самом вычисляемом поле, это накладывает ограничения на дальнейшее суммирование этого поля в итогах.
← На главную