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