Как правильно рассчитать вычисляемые поля в группировках и итогах запроса?

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

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

Выясним причину ошибки: математический аспект

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

  1. Изделие 1: Прибыль 100 руб., Площадь 10 м2. ПрибМ2 = 10.
  2. Изделие 2: Прибыль 1000 руб., Площадь 1000 м2. ПрибМ2 = 1.

Если в запросе мы укажем СУММА(ПрибМ2), система просто сложит 10 и 1, получив 11. Однако правильный расчет для всей группы должен выглядеть иначе: общая прибыль (1100) делится на общую площадь (1010), что дает результат примерно 1.08. Важный вывод: для корректного расчета в итогах нельзя суммировать результат формулы, нужно применять формулу к итоговому результату сумм.

Решение проблемы через секцию ИТОГИ в запросе

Рассмотрим стандартный запрос 1С. В исходном коде автора была допущена ошибка: в секции ИТОГИ использовалась агрегатная функция СУММА(ПрибМ2). Чтобы исправить расчет в группировках (например, по материалу или городу) и в общих итогах, нам необходимо прописать формулу расчета непосредственно в блоке итогов.

Проанализируем исправленный вариант запроса:


ВЫБРАТЬ
    Производство.Заказчик.Город КАК ЗаказчикГород,
    Производство.Материал КАК Материал,
    СУММА(Производство.ПлощадьИзделия) КАК ПлощадьИзделия,
    СУММА(Производство.ЦенаИзделия - Производство.Себестоимость) КАК Прибыль,
    // В детальных записях тоже считаем правильно
    ВЫБОР
        КОГДА Производство.ПлощадьИзделия <> 0
            ТОГДА (Производство.ЦенаИзделия - Производство.Себестоимость) / Производство.ПлощадьИзделия
        ИНАЧЕ 0
    КОНЕЦ КАК ПрибМ2
ИЗ
    Документ.Производство.ТабличнаяЧасть1 КАК Производство
ГДЕ
    Производство.Ссылка.Проведен = ИСТИНА
СГРУППИРОВАТЬ ПО
    Производство.Заказчик.Город,
    Производство.Материал
ИТОГИ
    СУММА(ПлощадьИзделия),
    СУММА(Прибыль),
    // КРИТИЧЕСКИ ВАЖНЫЙ МОМЕНТ:
    ВЫБОР
        КОГДА СУММА(ПлощадьИзделия) <> 0
            ТОГДА СУММА(Прибыль) / СУММА(ПлощадьИзделия)
        ИНАЧЕ 0
    КОНЕЦ КАК ПрибМ2
ПО
    ОБЩИЕ,
    ЗаказчикГород

В данном примере мы указали системе, что для поля ПрибМ2 на каждом уровне итогов (и для каждого города, и для всего отчета в целом) нужно сначала сложить всю прибыль, затем сложить всю площадь, и только потом выполнить деление. Это гарантирует математическую точность отчета.

Решение проблемы в Системе Компоновки Данных (СКД)

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

Разберем по шагам, как настроить расчет коэффициента в СКД:

  1. Перейдем на закладку Ресурсы.
  2. Добавим поле ПрибМ2 в список ресурсов.
  3. В колонке Выражение вместо стандартного Сумма(ПрибМ2) напишем: Сумма(Прибыль) / Сумма(ПлощадьИзделия).
  4. Для предотвращения ошибки деления на ноль можно использовать функцию ЕстьNull или условие: ВЫБОР КОГДА Сумма(ПлощадьИзделия) = 0 ТОГДА 0 ИНАЧЕ Сумма(Прибыль) / Сумма(ПлощадьИзделия) КОНЕЦ.

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

Использование регистров вместо табличных частей

Проанализируем еще один важный аспект, затронутый в обсуждении. Обращение напрямую к табличным частям документов, таким как Документ.Производство.ТабличнаяЧасть1, является плохой практикой (антипаттерном) в разработке на 1С.

Рассмотрим причины, по которым стоит использовать регистры накопления:

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

Для корректного отображения вычисляемых полей при группировке данных необходимо соблюдать принцип «Сначала сумма, потом деление». Независимо от того, используете ли вы секцию ИТОГИ в классическом запросе или настраиваете ресурсы в СКД, формула должна оперировать агрегатными значениями СУММА(...), а не пытаться суммировать уже вычисленные в детальных записях коэффициенты.

← На главную