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