Задача создания отчета, который сравнивает показатели (например, продажи или прибыль) текущего года с аналогичным периодом прошлого года — это классика управленческого учета. Подобный анализ продаж со сравнением двух периодов часто требуется в конфигурациях УТ 11, КА 2 или ERP. Казалось бы, задача тривиальная, но при реализации в Системе Компоновки Данных (СКД) разработчики часто сталкиваются с вопросом: как правильно спроектировать запрос и настройки, чтобы месяцы выстраивались в одну линию, а данные за разные годы попадали в соседние колонки?
В этой статье мы подробно разберем несколько способов решения этой задачи, проанализируем лучшие практики и составим пошаговый алгоритм действий. Мы рассмотрим как методы изменения запроса, так и настройки связей наборов данных.
Нам необходимо получить отчет, где:
Этот метод считается наиболее надежным и производительным. Суть его заключается в том, что мы приводим данные прошлого года к временной шкале текущего года непосредственно в запросе. Это позволяет в настройках СКД использовать единую группировку по периоду.
Разберем алгоритм действий:
1. Мы формируем запрос, состоящий из двух частей, объединенных конструкцией ОБЪЕДИНИТЬ ВСЕ.
2. В первой части выбираем данные за текущий период как есть.
3. Во второй части выбираем данные за прошлый период, но к полю периода применяем функцию смещения времени.
Посмотрим, как это выглядит на языке запросов 1С. Допустим, мы анализируем регистр Продажи.Обороты.
ВЫБРАТЬ
ПродажиОбороты.Номенклатура КАК Номенклатура,
ПродажиОбороты.Период КАК Период,
ПродажиОбороты.СуммаОборот КАК СуммаТекущийГод,
0 КАК СуммаПрошлыйГод
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоТекущегоГода, &КонецТекущегоГода, Месяц, ) КАК ПродажиОбороты
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ПродажиОборотыПрошлые.Номенклатура,
// Сдвигаем дату прошлого года вперед на 1 год, чтобы она совпала с текущим
ДОБАВИТЬКДАТЕ(ПродажиОборотыПрошлые.Период, ГОД, 1),
0,
ПродажиОборотыПрошлые.СуммаОборот
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПрошлогоГода, &КонецПрошлогоГода, Месяц, ) КАК ПродажиОборотыПрошлые
Почему это работает? В результате выполнения этого запроса СКД получит плоскую таблицу, где данные за январь прошлого года будут иметь дату января текущего года, но сумма будет лежать в поле СуммаПрошлыйГод. Это позволит нам сгруппировать данные по полю Период, и в одной строке группировки окажутся обе суммы.
При использовании первого способа (и простого запроса к регистру) мы сталкиваемся с распространенной проблемой: если в январе не было продаж ни в этом году, ни в прошлом, этот месяц просто исчезнет из отчета. Это нарушает визуальную структуру "календаря". Если вам важна точность по бухгалтерским данным, обратите внимание на анализ продаж по выручке, себестоимости и прибыли в разрезе номенклатурных групп, который учитывает специфику БП и ERP — для этого подойдёт отчет СКД по валовой прибыли и себестоимости.
Чтобы гарантировать наличие всех 12 месяцев в отчете, нам необходимо использовать Генератор календаря. Мы создадим таблицу со всеми месяцами года и присоединим к ней данные о продажах.
Давайте реализуем это на практике:
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(&НачалоПериода, МЕСЯЦ, aa.a * 10 + bb.b) КАК Период
ПОМЕСТИТЬ ТЗ_Месяцы
ИЗ
(ВЫБРАТЬ 0 КАК a ОБЪЕДИНИТЬ ВЫБРАТЬ 1) КАК aa
ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ 0 КАК b ОБЪЕДИНИТЬ ВЫБРАТЬ 1 ОБЪЕДИНИТЬ ВЫБРАТЬ 2 ОБЪЕДИНИТЬ ВЫБРАТЬ 3 ОБЪЕДИНИТЬ ВЫБРАТЬ 4 ОБЪЕДИНИТЬ ВЫБРАТЬ 5 ОБЪЕДИНИТЬ ВЫБРАТЬ 6 ОБЪЕДИНИТЬ ВЫБРАТЬ 7 ОБЪЕДИНИТЬ ВЫБРАТЬ 8 ОБЪЕДИНИТЬ ВЫБРАТЬ 9) КАК bb
ПО aa.a * 10 + bb.b <= РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, МЕСЯЦ)
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Календарь.Период КАК ПериодМесяц,
ЕСТЬNULL(Данные.Номенклатура, ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)) КАК Номенклатура,
СУММА(Данные.СуммаТекущийГод) КАК СуммаТекущийГод,
СУММА(Данные.СуммаПрошлыйГод) КАК СуммаПрошлыйГод
ИЗ
ТЗ_Месяцы КАК Календарь
ЛЕВОЕ СОЕДИНЕНИЕ (
// Здесь вставляем подзапрос с ОБЪЕДИНИТЬ ВСЕ из Способа №1
ВЫБРАТЬ ... ИЗ ... ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ... ИЗ ...
) КАК Данные
ПО Календарь.Период = Данные.Период
СГРУППИРОВАТЬ ПО
Календарь.Период,
Данные.Номенклатура
Таким образом, мы получаем жесткий каркас из периодов, к которому "подтягиваются" данные. Если данных нет, мы получим NULL, который с помощью функции ЕСТЬNULL превратим в 0 в ресурсах СКД.
Если вы не хотите писать сложные запросы с объединением, СКД предлагает альтернативный механизм — связи наборов данных. Этот метод может быть менее производительным на больших объемах данных, но он проще в понимании для новичков.
Разберем по шагам:
НомерМесяца). Для этого в запросах используйте функцию МЕСЯЦ(Период).НомерМесяца = НомерМесяца и Номенклатура = Номенклатура.НачалоПериода второго набора указываем выражение: ДОБАВИТЬКДАТЕ(&НачалоПериода, "ГОД", -1).После того как мы получили поля СуммаТекущийГод и СуммаПрошлыйГод, нам нужно посчитать разницу. Делать это лучше всего на вкладке Вычисляемые поля или прямо в "Ресурсах". Для комплексного контроля показателей (выручка, себестоимость, цены) в разных периодах удобно использовать решение сравнение прибыли и цен по номенклатуре в двух периодах для УТ 11.5 и КА 2.5.
Для корректного расчета процента роста необходимо предусмотреть защиту от деления на ноль. Используйте следующее выражение для ресурса:
ВЫБОР
КОГДА СУММА(СуммаПрошлыйГод) = 0 ТОГДА 0
ИНАЧЕ (СУММА(СуммаТекущийГод) - СУММА(СуммаПрошлыйГод)) / СУММА(СуммаПрошлыйГод) * 100
КОНЕЦ
Чтобы получить вид, как на скриншотах типовых отчетов (месяцы в колонках), выполним настройку варианта отчета:
Номенклатура, Контрагент.Период.
Совет: Чтобы периоды выводились словами ("Январь 2024"), настройте формат поля Период — ДФ='ММММ гггг'.
Если вы работаете в конфигурации "1С:Управление торговлей 11", "ERP" или "Комплексная автоматизация", полезно будет изучить уже готовые отчеты, встроенные в систему. Также для оперативного управления часто требуется динамика продаж и прибыли без закрытия месяца (поможет отчет по продажам и рентабельности без закрытия месяца), которая позволяет видеть результат "здесь и сейчас".
Помимо стандартных инструментов, обратите внимание на специализированные отчеты:
ПродажиСравнениеДвухПериодовПродажиСравнениеАналогичныхПериодовВы можете открыть схему компоновки этих отчетов в конфигураторе и посмотреть, как именно разработчики 1С реализовали объединение данных. Чаще всего там используется комбинированный подход с временными таблицами и объединением запросов, что обеспечивает наилучшую производительность.
Для создания отчета сравнения периодов в СКД:
ОБЪЕДИНИТЬ ВСЕ для слияния данных текущего и прошлого года в одну таблицу.ДОБАВИТЬКДАТЕ(..., ГОД, 1) для данных прошлого года, чтобы синхронизировать временную шкалу.