При разработке отчетов в Системе компоновки данных (СКД) часто возникает задача вывести динамическую таблицу, где колонками выступают месяцы за определенный период (например, за последние 12 месяцев от выбранной пользователем даты). Частая ошибка начинающих разработчиков — попытка зафиксировать 12 колонок в тексте запроса с помощью условий ВЫБОР КОГДА МЕСЯЦ(...) = 1.... Такой подход громоздок, снижает производительность и требует ручной верстки макета.
В этом материале мы проанализируем, как правильно и лаконично решить эту задачу средствами языка запросов 1С и механизмов СКД.
Разберем, почему не стоит писать подобные конструкции в запросе:
СУММА(ВЫБОР КОГДА МЕСЯЦ(ОтгрузкаТМЦОбороты.Период) = 1 ТОГДА ОтгрузкаТМЦОбороты.КоличествоОборот КОНЕЦ) КАК Январь,
СУММА(ВЫБОР КОГДА МЕСЯЦ(ОтгрузкаТМЦОбороты.Период) = 2 ТОГДА ОтгрузкаТМЦОбороты.КоличествоОборот КОНЕЦ) КАК Февраль
Основные недостатки этого метода:
Для того чтобы СКД самостоятельно сформировала колонки по месяцам, в запросе достаточно выбрать поле периода, приведенное к началу месяца с помощью функции НАЧАЛОПЕРИОДА, и указать верные границы интервала в параметрах виртуальной таблицы оборотов.
Рассмотрим оптимальный вариант запроса к регистру накопления:
ВЫБРАТЬ
НАЧАЛОПЕРИОДА(ОтгрузкаТМЦОбороты.Период, МЕСЯЦ) КАК ПериодМесяц,
ОтгрузкаТМЦОбороты.ТМЦ КАК Товар,
ОтгрузкаТМЦОбороты.КоличествоОборот КАК Количество
ИЗ
РегистрНакопления.ОтгрузкаТМЦ.Обороты(
НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&ВыбДата, МЕСЯЦ, -11), МЕСЯЦ),
КОНЕЦПЕРИОДА(&ВыбДата, МЕСЯЦ),
Период,
) КАК ОтгрузкаТМЦОбороты
Разберем ключевые моменты данного запроса:
Период или Месяц в параметры виртуальной таблицы оборотов заставляет платформу автоматически сгруппировать данные по выбранному интервалу. Дополнительная группировка с помощью СГРУППИРОВАТЬ ПО в запросе не требуется.ДОБАВИТЬКДАТЕ(&ВыбДата, МЕСЯЦ, -11) отсчитывает 11 месяцев назад от даты формирования. В сумме с текущим месяцем получается ровно 12 месяцев. Если требуется захватить 13 месяцев (включая аналогичный месяц прошлого года для сравнения), значение меняется на -12.01.12.2023 00:00:00, что сохранит правильную хронологическую сортировку при выводе колонок.Чтобы пользователю было удобно работать с отчетом и он не вводил начальную и конечную дату вручную, настроим расчет границ на вкладке Параметры в СКД:
ДатаОтчета с типом Дата (или СтандартныйПериод при необходимости).Для начала периода:
НачалоПериода(ДобавитьКДате(&ДатаОтчета, "Месяц", -11), "Месяц")
Для конца периода:
КонецПериода(&ДатаОтчета, "Месяц")
ДатаОтчета.Теперь перейдем на вкладку Настройки и создадим структуру отчета типа Таблица:
Товар.ПериодМесяц.Количество с функцией Сумма(Количество).Чтобы в заголовках колонок вместо полных дат (например, 01.12.2023 0:00:00) отображались понятные названия месяцев и лет (например, Декабрь 2023), настроим оформление:
ПериодМесяц и в колонке Оформление откроем настройки.ДФ='MMMM yyyy' (или ДЛФ=ММММ YYYY).Важно: не преобразуйте дату в строку внутри запроса с помощью условий или функций получения имени месяца. Если поле станет строковым, СКД отсортирует колонки по алфавиту (Август, Апрель, Декабрь...), а не в хронологическом порядке. Оставляйте поле датой и настраивайте представление через формат отображения.
Если в каком-то из 12 месяцев не было продаж, виртуальная таблица оборотов не вернет данных за этот период, и соответствующая колонка может выпасть из таблицы.
Для сохранения непрерывности шкалы месяцев можно использовать встроенный механизм СКД:
ПериодМесяц.Месяц.Использование встроенных средств СКД позволяет сократить объем кода, предотвратить ошибки сортировки и сделать отчет гибким к любым выбираемым периодам.