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