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

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

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

Разбор основной проблемы: почему данные «завышаются»?

Проанализируем ситуацию, описанную в исходном вопросе. Автор использовал запрос, в котором выбирал данные за два периода в разные временные таблицы, а затем соединял их следующим образом:

ИЗ Текущий КАК Текущий, Прошлый КАК Прошлый

В языке запросов 1С такое написание означает полное (декартово) произведение таблиц. Если в таблице Текущий содержится 12 строк (по месяцам года) и в таблице Прошлый также 12 строк, система перемножит каждую строку первой таблицы с каждой строкой второй. В итоге получится 144 строки, а итоговые суммы в ресурсах будут в 12 раз больше реальных. Чтобы избежать этого, необходимо использовать СОЕДИНЕНИЕ по ключевому полю, которое будет общим для обоих периодов.

Шаг 1. Подготовка параметров в СКД

Прежде чем приступать к запросу, разберем настройку параметров. Чтобы пользователю было удобно выбирать даты, мы будем использовать тип СтандартныйПериод. Выясним, как правильно связать пользовательские настройки с виртуальными таблицами запроса.

  1. Перейдем на вкладку Параметры в СКД.
  2. Создадим два параметра, например: ПериодСравнения1 и ПериодСравнения2 с типом СтандартныйПериод.
  3. Для системных параметров, которые используются в виртуальных таблицах (&НачалоТекущий, &КонецТекущий и т.д.), установим галочку Ограничение доступности, чтобы пользователь их не видел.
  4. В колонке Выражение для этих скрытых параметров пропишем обращение к датам из стандартных периодов:
    • Для &НачалоТекущий: &ПериодСравнения1.ДатаНачала
    • Для &КонецТекущий: &ПериодСравнения1.ДатаОкончания
    • Аналогично для второго периода.

Такой подход позволяет пользователю выбирать «Этот месяц», «Прошлый квартал» или произвольные даты через стандартный календарь, а запрос получит четкие границы периодов.

Шаг 2. Оптимальный запрос для сравнения периодов

Рассмотрим наиболее надежный метод получения данных для сравнения — использование ОБЪЕДИНЕНИЯ. Это позволяет избежать проблем с отсутствием данных в одном из периодов (например, если в прошлом году в марте не было продаж, ЛЕВОЕ СОЕДИНЕНИЕ может отработать некорректно без дополнительных проверок на NULL).

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


ВЫБРАТЬ
    ПродажиОбороты.Период КАК Период,
    МЕСЯЦ(ПродажиОбороты.Период) КАК НомерМесяца,
    ПРЕДСТАВЛЕНИЕПЕРИОДА(ПродажиОбороты.Период, "ФМ=Истина") КАК НазваниеМесяца,
    ПродажиОбороты.СтоимостьОборот КАК СуммаТекущий,
    0 КАК СуммаПрошлый
ИЗ
    РегистрНакопления.Продажи.Обороты({(&НачалоТекущий)}, {(&КонецТекущий)}, Месяц, ) КАК ПродажиОбороты

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

ВЫБРАТЬ
    ПродажиОбороты.Период,
    МЕСЯЦ(ПродажиОбороты.Период),
    ПРЕДСТАВЛЕНИЕПЕРИОДА(ПродажиОбороты.Период, "ФМ=Истина"),
    0,
    ПродажиОбороты.СтоимостьОборот
ИЗ
    РегистрНакопления.Продажи.Обороты({(&НачалоПрошлый)}, {(&КонецПрошлый)}, Месяц, ) КАК ПродажиОбороты

Обратите внимание на использование функции МЕСЯЦ(). Она возвращает число от 1 до 12. Это критически важно для того, чтобы в дальнейшем СКД смогла сгруппировать данные за январь прошлого года и январь текущего года в одну «точку» на диаграмме.

Шаг 3. Настройка ресурсов и вычисляемых полей

После того как запрос написан, перейдем на вкладку Ресурсы. Добавим поля СуммаТекущий и СуммаПрошлый с функцией СУММА(). Чтобы вывести разницу между периодами, создадим вычисляемое поле Разница с выражением: ЕСТЬNULL(СуммаТекущий, 0) - ЕСТЬNULL(СуммаПрошлый, 0).

Разберем важный нюанс: если мы хотим видеть процент роста, добавим еще одно поле ПроцентРоста, где используем формулу:


ВЫБОР 
    КОГДА СуммаПрошлый = 0 ТОГДА 0 
    ИНАЧЕ (СуммаТекущий - СуммаПрошлый) / СуммаПрошлый * 100 
КОНЕЦ

Шаг 4. Настройка структуры отчета (Диаграмма)

Выясним, как правильно настроить вкладку Настройки, чтобы диаграмма отображала корректное сравнение. Одна из главных ошибок — отсутствие группировок. СКД — это не просто вывод результата запроса, это мощный агрегатор, которому нужно указать, по каким полям «схлопывать» данные.

Для построения сравнительной диаграммы выполним следующие действия:

  1. В структуре отчета добавим Диаграмму.
  2. В Точки диаграммы добавим поле НомерМесяца (или НазваниеМесяца для красоты). Это обеспечит вывод месяцев по горизонтальной оси (X).
  3. В Серии диаграммы можно ничего не добавлять, если мы просто выводим два ресурса рядом.
  4. В Значения диаграммы добавим наши ресурсы: СуммаТекущий и СуммаПрошлый.

Важный совет: Чтобы месяцы в диаграмме шли по порядку (Январь, Февраль...), а не по алфавиту, используйте в качестве точки именно НомерМесяца, а в поле Выражение представления для этого поля укажите Формат(Период, "ДФ='MMMM'") или используйте дополнительное поле с названием месяца.

Шаг 5. Тонкая настройка связей (альтернативный метод)

Если запрос получается слишком громоздким, рассмотрим метод Связи наборов данных. Мы можем создать два отдельных набора данных (два разных запроса). Первый выбирает продажи за первый период, второй — за второй. В обоих запросах обязательно должно быть поле НомерМесяца.

На вкладке Связи наборов данных укажем:

Этот метод считается более «продвинутым» и позволяет легче масштабировать отчет, добавляя, например, третий период для сравнения без переписывания всего текста запроса.

Резюме

Мы проанализировали основные причины ошибок при сравнении периодов в СКД и нашли пути их решения. Главное — помнить, что прямое соединение таблиц без условий (запятая в разделе ИЗ) ведет к декартову произведению. Используйте ОБЪЕДИНИТЬ ВСЕ или грамотные связи наборов данных по идентифицирующим полям (номер месяца, код товара и т.д.). Не забывайте настраивать группировки в компоновке, так как без них ресурсы не будут агрегированы, и диаграмма не сможет корректно отобразить данные.

← На главную