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