Как правильно обработать пустые значения и NULL при вычислениях в запросах и СКД 1С

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

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

Выясним причину проблемы с NULL

Основная причина появления пустых ячеек в вычисляемых полях и запросах заключается в специфике работы со значением NULL:

  1. Арифметика с NULL: В языке запросов 1С и в выражениях системы компоновки данных (СКД) любая арифметическая операция со значением NULL (например, 100 - NULL - 20) всегда возвращает NULL. В результате в отчете отображается пустота.
  2. Неявное декартово произведение (Cross Join): Перечисление таблиц через запятую в секции ИЗ с наложением условий в ГДЕ при отсутствии связей приводит к декартову произведению. Если в одной из таблиц нет записей, результат всего запроса будет абсолютно пустым.
  3. Отборы в секции ГДЕ вместо параметров виртуальных таблиц: Условия на измерения, помещенные в секцию ГДЕ, применяются уже после формирования виртуальной таблицы, что ухудшает производительность и может полностью отсекать нужные строки.

Способ 1. Правильное объединение запросов с подстановкой нулей

Проанализируем классический подход к сведению оборотов из нескольких регистров. Вместо соединений эффективнее использовать конструкцию ОБЪЕДИНИТЬ ВСЕ, где для отсутствующих в конкретной ветке числовых полей явно указывается числовой 0, а не NULL.

Посмотрим на пример текста запроса:


ВЫБРАТЬ
    СУММА(Табличка.ОбщаяКомиссияОборот) КАК ОбщаяКомиссияОборот,
    СУММА(Табличка.КомиссияМенеджераОборот) КАК КомиссияМенеджераОборот,
    СУММА(Табличка.СуммаОборот) КАК СуммаОборот,
    СУММА(Табличка.ОбщаяКомиссияОборот - Табличка.КомиссияМенеджераОборот - Табличка.СуммаОборот) КАК ИтогЧистыми
ИЗ
    (ВЫБРАТЬ
        УлетевшиеТуристыОбороты.ОбщаяКомиссияОборот КАК ОбщаяКомиссияОборот,
        УлетевшиеТуристыОбороты.КомиссияМенеджераОборот КАК КомиссияМенеджераОборот,
        0 КАК СуммаОборот
    ИЗ
        РегистрНакопления.УлетевшиеТуристы.Обороты(, , , ТипОплаты = ЗНАЧЕНИЕ(Перечисление.ТипОплаты.Безналичный)) КАК УлетевшиеТуристыОбороты

    ОБЪЕДИНИТЬ ВСЕ

    ВЫБРАТЬ
        0,
        0,
        РасходыОбороты.СуммаОборот
    ИЗ
        РегистрНакопления.Расходы.Обороты(, , , ТипОплаты = ЗНАЧЕНИЕ(Перечисление.ТипОплаты.Безналичный)) КАК РасходыОбороты) КАК Табличка

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

Способ 2. Вычисление итогов на уровне СКД

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

Разберем порядок настройки в схеме компоновки данных:

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

Способ 3. Использование нескольких наборов данных в СКД

Рассмотрим еще один архитектурный вариант СКД, исключающий необходимость ручного объединения таблиц в тексте SQL-запроса:

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

Настройка отображения нулевых значений

Если в сформированном отчете вместо нулей отображаются пустые ячейки, это поведение можно скорректировать настройками оформления:

  1. В настройках СКД на вкладке «Условное оформление» либо в свойствах конкретного поля перейдите к пункту «Оформление» -> «Формат».
  2. Задайте параметр «Форматная строка» со значением ЧЗ=0 (отображать ноль) или заполните параметр «Представление нуля».
← На главную