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

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

При разработке отчетов в Системе компоновки данных (СКД) разработчики часто сталкиваются с ситуацией, когда математические выражения в вычисляемых полях или ресурсах не выводят результат и остаются пустыми. Проанализируем типичную задачу из практики: требовалось построить реестр чеков ККМ за смену с разделением на наличные и безналичные платежи в конфигурации «Управление торговлей 11». При вычитании суммы безналичной оплаты из общей суммы документа итоговая разность возвращала пустое значение.

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

Выясним причину: почему математические выражения возвращают пустое значение?

В языке запросов 1С и языке выражений СКД действует жесткое правило работы со значением NULL: любая арифметическая операция (сложение, вычитание, умножение, деление) с участием NULL всегда возвращает NULL.

Рассмотрим ситуацию, когда в документе «Чек ККМ» оплата производилась исключительно наличными деньгами. В этом случае табличная часть ОплатаПлатежнымиКартами оказывается пустой. При выполнении левого или полного соединения данных по табличным частям поле БезналичныйПлатеж получает значение NULL.

Попытка выполнить арифметическое вычисление вида:

СуммаДокумента - БезналичныйПлатеж

приводит к тому, что выражение принимает вид 1000 - NULL, результатом которого становится NULL. В отчете такое поле отображается как абсолютно пустое.

Решение проблемы через вычисляемые поля с использованием функции ЕСТЬNULL

Для корректного расчета наличного платежа необходимо гарантировать, что вместо отсутствующего значения (значения NULL) будет подставляться числовой ноль (0). В СКД это достигается с помощью функции ЕСТЬNULL (или IsNull).

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

  1. Откроем схему компоновки данных и перейдем на закладку Вычисляемые поля.
  2. Добавим новое поле с именем Наличные.
  3. В колонке Выражение пропишем безопасное математическое выражение:

ЕстьNull(СуммаДокумента, 0) - ЕстьNull(БезналичныйПлатеж, 0)

Функция ЕСТЬNULL(Значение, Замена) проверяет передаваемый параметр. Если значение первого аргумента равно NULL, функция возвращает второй аргумент (в нашем случае 0). Таким образом, расчет 1000 - 0 корректно вернет значение 1000.

  1. Перейдем на закладку Настройки и в ветке Выбранные поля добавим созданное вычисляемое поле Наличные.

Настройка итогов на закладке «Ресурсы»

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

  1. Перейдем на закладку Ресурсы схемы компоновки данных.
  2. Перенесём вычисляемое поле Наличные в список ресурсов.
  3. В поле Выражение укажем стандартную агрегатную функцию:

Сумма(Наличные)

Если для какого-либо поля набора данных значение по-прежнему может приходить в виде NULL, в выражении ресурса также рекомендуется использовать явную обработку нулевых значений, например: Сумма(ЕСТЬNULL(Наличные, 0)).

Альтернативный подход: оптимизация запроса набора данных

Использование ПОЛНОГО СОЕДИНЕНИЯ в запросах 1С (особенно по вложенным запросам с группировками) создает значительную нагрузку на СУБД. Проанализируем более эффективную архитектуру запроса для построения такого отчета с помощью оператора ОБЪЕДИНИТЬ ВСЕ.

Данный подход исключает появления значений NULL еще на этапе формирования набора данных и работает существенно быстрее:


ВЫБРАТЬ
	ИсходныеДанные.Ссылка КАК ЧекККМ,
	СУММА(ИсходныеДанные.СуммаДокумента) КАК СуммаДокумента,
	СУММА(ИсходныеДанные.БезналичныйПлатеж) КАК БезналичныйПлатеж,
	СУММА(ИсходныеДанные.СуммаДокумента - ИсходныеДанные.БезналичныйПлатеж) КАК НаличныйПлатеж
ИЗ
	(ВЫБРАТЬ
		ЧекТовары.Ссылка КАК Ссылка,
		ЧекТовары.Сумма КАК СуммаДокумента,
		0 КАК БезналичныйПлатеж
	ИЗ
		Документ.ЧекККМ.Товары КАК ЧекТовары
	ГДЕ
		ЧекТовары.Ссылка.Статус = &Статус

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

	ВЫБРАТЬ
		ЧекКарты.Ссылка КАК Ссылка,
		0 КАК СуммаДокумента,
		ЧекКарты.Сумма КАК БезналичныйПлатеж
	ИЗ
		Документ.ЧекККМ.ОплатаПлатежнымиКартами КАК ЧекКарты
	ГДЕ
		ЧекКарты.Ссылка.Статус = &Статус) КАК ИсходныеДанные

СГРУППИРОВАТЬ ПО
	ИсходныеДанные.Ссылка

Подводя итог, отметим: при разработке отчетов в СКД всегда учитывайте возможность появления NULL в результатах объединений и соединений. Обработка таких полей с помощью функции ЕСТЬNULL гарантирует правильный расчет всех математических выражений и итоговых ресурсов отчета.

← На главную