Сравнение показателей текущего периода с аналогичными показателями прошлого периода — это одна из самых частых задач при разработке аналитических отчетов в системе компоновки данных (СКД). Однако при реализации такого функционала начинающие разработчики часто сталкиваются с тем, что данные в отчете начинают многократно дублироваться («раздуваться») или вовсе не выводятся. В этой статье мы подробно разберем, как правильно построить запрос, настроить параметры и оформить диаграмму для наглядного сравнения продаж.
Проанализируем ситуацию, описанную в исходном вопросе. Автор использовал запрос, в котором выбирал данные за два периода в разные временные таблицы, а затем соединял их следующим образом:
ИЗ Текущий КАК Текущий, Прошлый КАК Прошлый
В языке запросов 1С такое написание означает полное (декартово) произведение таблиц. Если в таблице Текущий содержится 12 строк (по месяцам года) и в таблице Прошлый также 12 строк, система перемножит каждую строку первой таблицы с каждой строкой второй. В итоге получится 144 строки, а итоговые суммы в ресурсах будут в 12 раз больше реальных. Чтобы избежать этого, необходимо использовать СОЕДИНЕНИЕ по ключевому полю, которое будет общим для обоих периодов.
Прежде чем приступать к запросу, разберем настройку параметров. Чтобы пользователю было удобно выбирать даты, мы будем использовать тип СтандартныйПериод. Выясним, как правильно связать пользовательские настройки с виртуальными таблицами запроса.
ПериодСравнения1 и ПериодСравнения2 с типом СтандартныйПериод.&НачалоТекущий, &КонецТекущий и т.д.), установим галочку Ограничение доступности, чтобы пользователь их не видел.&НачалоТекущий: &ПериодСравнения1.ДатаНачала&КонецТекущий: &ПериодСравнения1.ДатаОкончанияТакой подход позволяет пользователю выбирать «Этот месяц», «Прошлый квартал» или произвольные даты через стандартный календарь, а запрос получит четкие границы периодов.
Рассмотрим наиболее надежный метод получения данных для сравнения — использование ОБЪЕДИНЕНИЯ. Это позволяет избежать проблем с отсутствием данных в одном из периодов (например, если в прошлом году в марте не было продаж, ЛЕВОЕ СОЕДИНЕНИЕ может отработать некорректно без дополнительных проверок на NULL).
Проанализируем пример запроса, который собирает данные в одну плоскую структуру с признаком периода:
ВЫБРАТЬ
ПродажиОбороты.Период КАК Период,
МЕСЯЦ(ПродажиОбороты.Период) КАК НомерМесяца,
ПРЕДСТАВЛЕНИЕПЕРИОДА(ПродажиОбороты.Период, "ФМ=Истина") КАК НазваниеМесяца,
ПродажиОбороты.СтоимостьОборот КАК СуммаТекущий,
0 КАК СуммаПрошлый
ИЗ
РегистрНакопления.Продажи.Обороты({(&НачалоТекущий)}, {(&КонецТекущий)}, Месяц, ) КАК ПродажиОбороты
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ПродажиОбороты.Период,
МЕСЯЦ(ПродажиОбороты.Период),
ПРЕДСТАВЛЕНИЕПЕРИОДА(ПродажиОбороты.Период, "ФМ=Истина"),
0,
ПродажиОбороты.СтоимостьОборот
ИЗ
РегистрНакопления.Продажи.Обороты({(&НачалоПрошлый)}, {(&КонецПрошлый)}, Месяц, ) КАК ПродажиОбороты
Обратите внимание на использование функции МЕСЯЦ(). Она возвращает число от 1 до 12. Это критически важно для того, чтобы в дальнейшем СКД смогла сгруппировать данные за январь прошлого года и январь текущего года в одну «точку» на диаграмме.
После того как запрос написан, перейдем на вкладку Ресурсы. Добавим поля СуммаТекущий и СуммаПрошлый с функцией СУММА(). Чтобы вывести разницу между периодами, создадим вычисляемое поле Разница с выражением: ЕСТЬNULL(СуммаТекущий, 0) - ЕСТЬNULL(СуммаПрошлый, 0).
Разберем важный нюанс: если мы хотим видеть процент роста, добавим еще одно поле ПроцентРоста, где используем формулу:
ВЫБОР
КОГДА СуммаПрошлый = 0 ТОГДА 0
ИНАЧЕ (СуммаТекущий - СуммаПрошлый) / СуммаПрошлый * 100
КОНЕЦ
Выясним, как правильно настроить вкладку Настройки, чтобы диаграмма отображала корректное сравнение. Одна из главных ошибок — отсутствие группировок. СКД — это не просто вывод результата запроса, это мощный агрегатор, которому нужно указать, по каким полям «схлопывать» данные.
Для построения сравнительной диаграммы выполним следующие действия:
НомерМесяца (или НазваниеМесяца для красоты). Это обеспечит вывод месяцев по горизонтальной оси (X).СуммаТекущий и СуммаПрошлый.Важный совет: Чтобы месяцы в диаграмме шли по порядку (Январь, Февраль...), а не по алфавиту, используйте в качестве точки именно НомерМесяца, а в поле Выражение представления для этого поля укажите Формат(Период, "ДФ='MMMM'") или используйте дополнительное поле с названием месяца.
Если запрос получается слишком громоздким, рассмотрим метод Связи наборов данных. Мы можем создать два отдельных набора данных (два разных запроса). Первый выбирает продажи за первый период, второй — за второй. В обоих запросах обязательно должно быть поле НомерМесяца.
На вкладке Связи наборов данных укажем:
НомерМесяца = НомерМесяцаЭтот метод считается более «продвинутым» и позволяет легче масштабировать отчет, добавляя, например, третий период для сравнения без переписывания всего текста запроса.
Мы проанализировали основные причины ошибок при сравнении периодов в СКД и нашли пути их решения. Главное — помнить, что прямое соединение таблиц без условий (запятая в разделе ИЗ) ведет к декартову произведению. Используйте ОБЪЕДИНИТЬ ВСЕ или грамотные связи наборов данных по идентифицирующим полям (номер месяца, код товара и т.д.). Не забывайте настраивать группировки в компоновке, так как без них ресурсы не будут агрегированы, и диаграмма не сможет корректно отобразить данные.