Как правильно рассчитать процент исполнения в итогах запроса 1С?

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

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

Анализ проблемы: почему СУММА(Процент) не работает

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


ВЫБОР
    КОГДА ВТ_ИмпортФормаКПиКР.СкорректированныйБюджет <> 0
        ТОГДА (ВТ_ИмпортФормаКПиКР.ОбщееИсполнение * 100) / ВТ_ИмпортФормаКПиКР.СкорректированныйБюджет
    ИНАЧЕ 0
КОНЕЦ КАК ИсполнениеПроцент

Когда мы переходим к секции ИТОГИ, ошибочно хочется написать СУММА(ИсполнениеПроцент). Это главная методологическая ошибка. Платформа 1С в этом случае просто сложит все проценты из детальных записей. Если у вас 10 строк, в каждой из которых исполнение составляет 50%, то в итоге вы получите 500%. Очевидно, что итоговое исполнение по всей группе должно оставаться 50%, если объемы данных в строках сопоставимы.

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

Правильный расчет в секции ИТОГИ

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

Вместо простого суммирования поля ИсполнениеПроцент, в блоке ИТОГИ мы должны прописать формулу:


ИТОГИ
    СУММА(ОбщееИсполнение),
    СУММА(СкорректированныйБюджет),
    ВЫБОР
        КОГДА СУММА(СкорректированныйБюджет) <> 0
            ТОГДА СУММА(ОбщееИсполнение) / СУММА(СкорректированныйБюджет) * 100
        ИНАЧЕ 0
    КОНЕЦ КАК ИсполнениеПроцент
ПО
    Бюджет,
    НомерРаздела

Проанализируем этот фрагмент кода. Обратите внимание, что внутри функции ВЫБОР мы используем СУММА(...) для каждого поля. Это заставляет систему выполнять расчет на уровне итогов для каждой группировки (Бюджет, Номер раздела и т.д.), используя уже накопленные итоги по суммам исполнения и бюджета.

Типичные ошибки при написании формул в итогах

Рассмотрим ситуацию, с которой столкнулся автор темы при попытке исправить код. При написании формулы в итогах без использования агрегатных функций возникает ошибка: "Поле итогов должно либо присутствовать в списке группировок итогов, либо находиться в агрегатной функции итога".

Это происходит, если вы пытаетесь написать так:

(ОбщееИсполнение * 100) / СкорректированныйБюджет КАК ИсполнениеПроцент

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

Обработка пустых значений и деления на ноль

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

  1. Всегда проверяйте знаменатель на равенство нулю через КОГДА СУММА(Поле) <> 0.
  2. Если данные поступают из левых соединений, используйте ЕСТЬNULL(Поле, 0) в основной части запроса, чтобы агрегатные функции в итогах работали корректно.
  3. Для повышения точности и удобства чтения отчета полезно ограничивать количество знаков после запятой с помощью функции ВЫРАЗИТЬ.

Пример продвинутого расчета в итогах:


ИТОГИ
    СУММА(ОбщееИсполнение),
    СУММА(СкорректированныйБюджет),
    ВЫРАЗИТЬ(
        ВЫБОР
            КОГДА СУММА(СкорректированныйБюджет) <> 0
                ТОГДА СУММА(ОбщееИсполнение) / СУММА(СкорректированныйБюджет) * 100
            ИНАЧЕ 0
        КОНЕЦ 
    КАК ЧИСЛО(15, 2)) КАК ИсполнениеПроцент
ПО
    ОБЩИЕ,
    Бюджет

Альтернатива: расчет в Системе компоновки данных (СКД)

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

Чтобы рассчитать процент в СКД правильно:

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

Заключение

Мы проанализировали ситуацию и выяснили, что процент — это относительный показатель, который нельзя просто суммировать. Для получения корректных данных в отчетах 1С необходимо соблюдать правило: в итогах процент вычисляется как отношение суммы числителей к сумме знаменателей. Использование конструкции ВЫБОР КОГДА СУММА(...) <> 0 гарантирует стабильную работу кода без ошибок деления на ноль, а функция ВЫРАЗИТЬ обеспечит опрятный вид чисел в итоговой таблице.

← На главную