В практике разработки отчетов на базе Системы компоновки данных (СКД) часто возникают задачи, выходящие за рамки стандартных календарных периодов. Одной из таких задач является расчет прироста или разницы показателей по сравнению с предыдущим годом, особенно когда отчетный год начинается не с 1 января, а, например, с 1 августа. В этой статье мы подробно разберем, как реализовать подобную логику, проанализируем типичные ошибки и рассмотрим два эффективных метода решения.
Прежде чем приступать к расчету разницы, необходимо корректно определить границы отчетного периода. Если год у клиента начинается с 1 августа, то все даты с августа текущего года по июль следующего должны попадать в один "финансовый год".
Рассмотрим более изящный способ вычисления такого периода в запросе, чем громоздкие конструкции ВЫБОР. Мы можем использовать математическое смещение даты. Если мы вычтем из текущей даты 7 месяцев, то август (8-й месяц) станет январем (1-м месяцем) в расчетном периоде. Проанализируем пример кода:
ВЫБРАТЬ
ПродажиОбороты.Программа КАК Программа,
ПродажиОбороты.КоличествоОборот КАК Количество,
НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(ПродажиОбороты.ПериодМесяц, МЕСЯЦ, -7), ГОД) КАК ГодПродажДляГруппировки,
ПродажиОбороты.ПериодМесяц КАК ПериодМесяц
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, Авто, ) КАК ПродажиОбороты
В данном примере поле ГодПродажДляГруппировки будет содержать дату начала календарного года, который фактически соответствует нашему "смещенному" финансовому году. Это позволит стандартным механизмам группировки СКД корректно объединять данные. Чтобы в заголовке отчета пользователь видел привычные даты, можно при выводе в вычисляемом поле добавить эти 7 месяцев обратно.
Это самый современный и гибкий способ в СКД. Функция ВычислитьВыражение позволяет обращаться к значениям других группировок, не усложняя текст запроса. Однако здесь программисты часто допускают ошибку, передавая имя поля без агрегатной функции.
Разберем по шагам настройку ресурса для расчета разницы. Перейдем на закладку "Ресурсы" и добавим новое поле. В выражении для расчета разницы нам нужно из текущей суммы вычесть сумму предыдущего периода.
Правильный синтаксис выражения:
Сумма(Количество) - ЕстьNull(ВычислитьВыражение("Сумма(Количество)", "ГодПродаж", , "Предыдущая", "Предыдущая"), 0)
Проанализируем параметры этой функции:
Сумма, Максимум и т.д.).Использование ЕстьNull крайне важно, так как для самой первой колонки в отчете (например, 2019 год) предыдущего значения не существует, и функция вернет NULL, что сделает результат вычитания пустым.
Если логика отчета слишком сложна для использования функций ресурсов, можно применить архитектурный подход на уровне запроса. Суть метода заключается в том, чтобы "подтянуть" данные прошлого года в ту же строку, где находятся данные текущего года.
Разберем алгоритм реализации:
ГодПродаж.ДОБАВИТЬКДАТЕ(Период, ГОД, 1). Это поле называем так же — ГодПродаж.Программа (аналитика) и ГодПродаж (период).Теперь в каждой строке группировки по году у нас будут доступны два поля: Количество и КоличествоПрошлыйГод. Разница вычисляется простым арифметическим действием в вычисляемых полях или ресурсах: Количество - КоличествоПрошлыйГод.
При реализации любого из методов стоит обратить внимание на следующие моменты:
1. Контекст вычислений. Если вы используете ВычислитьВыражение в итоговых записях, убедитесь, что имя группировки в параметрах функции совпадает с реальным именем в настройках отчета. Если имя будет указано неверно или не указано вовсе, СКД может начать считать разницу не по годам (горизонтально), а по строкам (вертикально).
2. Пустые периоды. Выясним причину, по которой расчет может "перескакивать" через год. Если в 2021 году продаж не было, и этот год отсутствует в выборке, то для 2022 года "предыдущим" станет 2020 год. Чтобы этого избежать, в настройках группировки (вкладка "Иерархия и группировка") для поля периода нужно установить флаг "Дополнять периоды". Это заставит отчет выводить пустую колонку 2021 года, и разница для 2022 года будет рассчитана корректно (относительно нуля).
3. Форматирование. Для первой колонки разница часто выглядит нелепо (повторяет основное значение или равна 0). Рекомендуем использовать Условное оформление, чтобы скрыть текст в ресурсе "Разница" для первой колонки периода, так как сравнение для нее не имеет смысла.
Подводя итог, можно сказать, что для простых табличных отчетов наиболее оптимальным является Метод 2 с использованием ресурсов. Он требует минимум правок в запросе и легко масштабируется. Метод со смещением периодов (Метод 3) лучше подходит для сложных аналитических панелей, где требуется глубокая постобработка данных прошлого периода.