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