Как рассчитать разность между колонками и настроить правильные итоги в СКД

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

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

Разбор ситуации: Почему простые формулы не всегда работают

Рассмотрим ситуацию, когда отчет строится на основе нескольких наборов данных, объединенных через операцию Объединение (Union). В этом случае поля, которые присутствуют в одном наборе, но отсутствуют в другом, будут содержать значение NULL. Проанализируем, к чему это приводит: если попытаться просто вычесть одно поле из другого, любая операция с NULL даст в результате NULL. В итоге целые строки отчета могут оказаться пустыми.

Для решения этой проблемы необходимо всегда использовать функцию ЕСТЬNULL. Разберем, как это реализовать на уровне ресурсов. Вместо простого вычитания полей, мы должны убедиться, что система оперирует числами даже там, где данных нет.

Правильный расчет разности в ресурсах

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


Сумма(ЕСТЬNULL(ФормаПриемаКоличество, 0)) - Сумма(ЕСТЬNULL(ФормаПриемаКоличествоСр, 0))

Важный нюанс: Обратите внимание, что агрегатная функция Сумма должна стоять над каждым операндом отдельно. Это гарантирует, что система сначала просуммирует все данные по группировке (игнорируя или заменяя NULL на 0), а затем выполнит вычитание. Если написать Сумма(Поле1 - Поле2), результат в итогах может быть неверным, если в детальных записях отсутствуют пары значений.

Использование функции ВычислитьВыражение

Иногда стандартных агрегатных функций недостаточно, особенно когда нужно обратиться к данным других группировок или выполнить расчет в контексте конкретного набора данных. Рассмотрим применение функции ВычислитьВыражение, которая часто выручает в сложных отчетах:

ВычислитьВыражение("Сумма(РазницаКоличество)", "ФормаПриема")

Здесь мы указываем системе, что расчет суммы должен производиться строго в контексте группировки или набора данных ФормаПриема. Это помогает избежать "смешивания" данных, если логика отчета подразумевает сложную иерархию.

Реализация сложной логики (проценты и безопасное деление)

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


ВЫБОР 
    КОГДА Сумма(СуммаСр) <> 0 
        ТОГДА Сумма(ЕСТЬNULL(Сумма, 0)) / Сумма(СуммаСр) * 100 
    ИНАЧЕ 
        ВЫБОР 
            КОГДА Сумма(Сумма) <> 0 ТОГДА 100 
            ИНАЧЕ 0 
        КОНЕЦ 
КОНЕЦ

В данном примере мы сначала проверяем, не равен ли знаменатель СуммаСр нулю. Если он равен нулю, но при этом числитель Сумма заполнен, бизнес-логика может требовать вывода 100% (или 0%, в зависимости от задачи). Такая вложенная проверка делает отчет устойчивым к любым входящим данным.

Проблема общих итогов для несуммируемых величин

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

Для решения этой задачи в СКД в поле ресурса "Рассчитывать по..." можно указать конкретные группировки. Но есть более универсальный и мощный способ — использование функции ВычислитьВыражениеСГруппировкойМассив.

Рассмотрим ситуацию: нам нужно просуммировать результаты вычислений, сделанных на уровне вложенных группировок. Выясним причину, почему обычная Сумма не сработает — она будет суммировать детальные записи, а нам нужны итоги по группам. Используем следующую схему:


Сумма(ВычислитьВыражениеСГруппировкойМассив("Сумма(Числитель) / Сумма(Знаменатель)", "Номенклатура"))

Проанализируем, как работает эта конструкция:

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

Это позволяет получить "сумму средних" или "сумму процентов", если того требует управленческий учет. Если же в общем итоге вам нужно просто пересчитать процент по общим суммам, достаточно просто оставить ту же формулу (с делением сумм) для поля "Общий итог", не используя суммирование массива.

Рекомендации по настройке вычисляемых полей

При работе с вычисляемыми полями и ресурсами придерживайтесь следующих правил, чтобы избежать ошибок:

Таким образом, комбинируя использование ЕСТЬNULL, правильную агрегацию в ресурсах и мощные функции СКД вроде ВычислитьВыражениеСГруппировкойМассив, вы сможете решить практически любую задачу по расчету сложных показателей в отчетах 1С.

← На главную