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