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

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

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

Почему возникают отрицательные или неверные значения?

Проанализируем основные причины, из-за которых расчет в лоб дает неверный результат:

  1. Обращение к строкам табличной части вместо итогов: Поле Товары.Сумма или ОплатаПлатежнымиКартами.Сумма возвращает значение отдельной строки табличной части, а не итоговую сумму по всему документу. Если в документе несколько строк с товарами или несколько транзакций по эквайрингу, прямое вычитание одной строки из другой дает непредсказуемый результат.
  2. Декартово произведение табличных частей: Если в одном запросе соединить табличную часть Товары и табличную часть ОплатаПлатежнымиКартами без предварительной свертки, строки перемножатся. Например, при наличии 10 строк товаров и 2 строк оплат картами результат запроса будет содержать 20 строк с многократным дублированием сумм.
  3. Дублирование реквизита шапки: При связывании реквизита шапки СуммаДокумента с табличной частью оплат значение шапки повторяется для каждой строки безналичной оплаты.
  4. Значения NULL: Если продажа была совершена только за наличный расчет, в табличной части ОплатаПлатежнымиКартами строк не будет вовсе. При левом соединении сумма безналичной оплаты примет значение NULL. Результат операции СуммаДокумента - NULL возвращает NULL, из-за чего строка пропадает из итогов или рассчитывается неверно.

Вариант 1. Предварительная группировка данных в запросе СКД

Наиболее надежный и производительный способ — выполнить агрегацию сумм табличных частей во временных таблицах или подзапросах до их соединения. Разберем по шагам построение такого запроса:

  1. Свернем табличную часть безналичных оплат по каждому документу, получив общую сумму эквайринга.
  2. Соединим результат с шапкой документа с помощью левого соединения.
  3. Обработаем возможные значения NULL через функцию ЕСТЬNULL.
  4. Вычислим оплату наличными непосредственно в тексте запроса.

Посмотрим на пример текста запроса для набора данных СКД:


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

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

Вариант 2. Использование объединения таблиц (ОБЪЕДИНИТЬ ВСЕ)

Если требуется собрать данные из нескольких табличных частей (например, при детализации по товарам и видам оплат), эффективнее использовать объединение с последующей группировкой. Рассмотрим данный подход:


ВЫБРАТЬ
    Т.Ссылка КАК Документ,
    Т.Сумма КАК СуммаВсего,
    0 КАК СуммаБезнал
ИЗ
    Документ.ОтчетОРозничныхПродажах.Товары КАК Т

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

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

Во внешнем запросе сгруппируем полученные данные по полю Документ и рассчитаем сумму наличных:


ВЫБРАТЬ
    Данные.Документ КАК Документ,
    СУММА(Данные.СуммаВсего) КАК СуммаВсего,
    СУММА(Данные.СуммаБезнал) КАК СуммаБезнал,
    СУММА(Данные.СуммаВсего) - СУММА(Данные.СуммаБезнал) КАК СуммаНаличные
ИЗ
    (ВложенныйЗапрос) КАК Данные
СГРУППИРОВАТЬ ПО
    Данные.Документ

Вариант 3. Настройка вычисляемых полей и ресурсов в СКД

Если в схему компоновки уже передаются агрегированные поля СуммаВсего и СуммаБезнал, расчет можно вынести в настройки схемы.

Разберем настройку по шагам:

  1. На вкладке Вычисляемые поля добавим поле СуммаНаличные со следующим выражением:
    СуммаВсего - ЕстьNull(СуммаБезнал, 0)
  2. На вкладке Ресурсы обязательно настроим расчет итогов для всех числовых полей. Для вычисляемого поля наличных выражение ресурса должно содержать агрегатные функции:
    Сумма(СуммаВсего) - Сумма(СуммаБезнал)

Важно: Нельзя указывать в ресурсах просто Сумма(СуммаНаличные), если поле СуммаНаличные не вычисляется на уровне детальных записей, иначе на группировках верхнего уровня возникнут расхождения.

Важные нюансы прикладной логики

При расчете наличных денег через разность общей суммы и эквайринга необходимо учитывать следующие особенности конфигураций 1С:

  1. Прочие виды оплат: В чеках ККМ и отчетах о розничных продажах могут присутствовать другие способы расчета: подарочные сертификаты, бонусные баллы, потребительские кредиты или предоплата. В этом случае формула должна вычитать все виды безналичных и альтернативных оплат.
  2. Возвраты: Если в документе есть возвраты покупателям, они могут оформляться отдельной табличной частью или отрицательными суммами. Убедимся, что возвраты корректно уменьшают как общую сумму выручки, так и сумму соответствующего типа оплаты.
  3. Использование регистров накопления: В типовых решениях (например, в 1С:Управление торговлей или 1С:Розница) для получения точных данных о наличных движениях правильнее обращаться не к табличным частям документов, а к регистрам накопления денежных средств (таким как ДенежныеСредстваККМ или ДенежныеСредстваВКассахККМ). Это исключает ошибки ручного сопоставления способов оплаты.
← На главную