Как исправить ошибку «Деление на 0» в вычисляемых полях СКД?

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

При разработке отчетов в системе компоновки данных (СКД) разработчики часто сталкиваются с ситуацией, когда формула вычисляемого поля вида ((Поле1 + Поле2) / (Поле3 + Поле4)) приводит к ошибке «Деление на 0» во всех или некоторых строках отчета. При этом исходные данные могут казаться корректными, а сумма полей знаменателя визуально никогда не равна нулю.

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

Почему возникает ошибка деления на ноль в СКД

Выделим ключевые причины, из-за которых СКД выдает ошибку деления на ноль при вычислении выражений:

  1. Значения NULL в исходных полях: Если числовые поля приходят из левых соединений запроса или пустых реквизитов, они содержат значение NULL, а не числовой 0. Любая арифметическая операция со значением NULL (например, NULL + 0) в выражениях СКД приводит к неопределенному результату или ошибке приведения типов, что в операции деления провоцирует ошибку «Деление на 0».
  2. Расчет формулы на уровне группировок и итогов: Если поле создано на вкладке «Вычисляемые поля», но не настроено на вкладке «Ресурсы», СКД пытается рассчитать формулу не только для детальных записей, но и для итоговых строк. В группировочных строках поля детальных записей недоступны без агрегатных функций и принимают значение NULL, что сразу вызывает ошибку.
  3. Жадное вычисление выражений: Процессор компоновки данных может рассчитывать выражение для всех строк исходной выборки еще до наложения пользовательских отборов. Если в скрытых строках знаменатель равен нулю или NULL, отчет выдаст ошибку.

Способ 1. Использование функций ЕСТЬNULL и ВЫБОР в вычисляемом поле

Разберем базовое решение проблемы непосредственно в выражении вычисляемого поля. Нам необходимо обернуть каждое числовое поле в функцию ЕСТЬNULL() с подстановкой нуля, а также добавить явную проверку знаменателя через конструкцию ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ.

Перейдем на вкладку «Вычисляемые поля» и укажем следующее выражение для поля:


ВЫБОР 
    КОГДА (ЕСТЬNULL(Поле3, 0) + ЕСТЬNULL(Поле4, 0)) = 0 ТОГДА 0 
    ИНАЧЕ (ЕСТЬNULL(Поле1, 0) + ЕСТЬNULL(Поле2, 0)) / (ЕСТЬNULL(Поле3, 0) + ЕСТЬNULL(Поле4, 0)) 
КОНЕЦ

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

Способ 2. Обработка значений NULL в тексте запроса

Рассмотрим более производительный вариант. Перенос обработки NULL на уровень СУБД снижает нагрузку на процессор компоновки данных и исключает проблемы с неопределенными типами данных.

В тексте запроса набора данных оборачиваем числовые поля функцией ЕСТЬNULL:


ВЫБРАТЬ
    ЕСТЬNULL(Таблица.Поле1, 0) КАК Поле1,
    ЕСТЬNULL(Таблица.Поле2, 0) КАК Поле2,
    ЕСТЬNULL(Таблица.Поле3, 0) КАК Поле3,
    ЕСТЬNULL(Таблица.Поле4, 0) КАК Поле4
ИЗ
    РегистрНакопления.Продажи КАК Таблица

После такой подготовки в вычисляемом поле СКД достаточно оставить только проверку деления на ноль:


ВЫБОР 
    КОГДА (Поле3 + Поле4) = 0 ТОГДА 0 
    ИНАЧЕ (Поле1 + Поле2) / (Поле3 + Поле4) 
КОНЕЦ

Способ 3. Корректный расчет показателя на вкладке «Ресурсы»

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

Разберем правильную настройку ресурса по шагам:

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

ВЫБОР 
    КОГДА (Сумма(Поле3) + Сумма(Поле4)) = 0 ТОГДА 0 
    ИНАЧЕ (Сумма(Поле1) + Сумма(Поле2)) / (Сумма(Поле3) + Сумма(Поле4)) 
КОНЕЦ

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

Способ 4. Использование функций общих модулей

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

ОбщегоНазначенияКлиентСервер.Разделить(Поле1 + Поле2, Поле3 + Поле4)

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

← На главную