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

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

При построении отчетов в 1С часто возникает необходимость не просто вывести список документов, а получить агрегированные данные (суммы, количества) в разрезе определенных периодов, чаще всего — месяцев. Это стандартная задача для управленческого анализа и бухгалтерской отчетности. В этой статье мы подробно разберем несколько способов реализации такой группировки, изучим технические нюансы работы с периодами и выясним, как сделать отчет гибким для пользователя.

Метод 1. Использование функции НачалоПериода в тексте запроса

Самый распространенный и надежный способ сгруппировать данные по месяцам — это привести дату каждого документа к началу соответствующего месяца. Для этого в языке запросов 1С используется функция НачалоПериода. Проанализируем, как это работает на практике.

Когда мы передаем в функцию НачалоПериода(Дата, МЕСЯЦ) произвольную дату, система «округляет» ее до первого числа месяца, 00:00:00. Например, «15.03.2023 14:20:00» превратится в «01.03.2023 00:00:00». Это позволяет объединить все записи одного месяца в одну группу.

Рассмотрим пример запроса для получения сумм продаж из документов РеализацияТоваровУслуг:


ВЫБРАТЬ
    НачалоПериода(РеализацияТоваровУслуг.Дата, МЕСЯЦ) КАК Месяц,
    СУММА(РеализацияТоваровУслуг.СуммаДокумента) КАК Сумма
ИЗ
    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
ГДЕ
    РеализацияТоваровУслуг.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
СГРУППИРОВАТЬ ПО
    НачалоПериода(РеализацияТоваровУслуг.Дата, МЕСЯЦ)
УПОРЯДОЧИТЬ ПО
    Месяц

Важный нюанс: Обратите внимание, что мы используем НачалоПериода не только в списке выбора, но и в секции СГРУППИРОВАТЬ ПО. Это обязательное требование языка запросов при использовании агрегатных функций (таких как СУММА).

Метод 2. Использование итогов с дополнением периодов

Иногда простой группировки недостаточно. Если в каком-то месяце не было продаж, обычный запрос просто пропустит этот месяц, и в результате получится «дырка» в хронологии. Чтобы избежать этого и вывести «нулевые» месяцы, воспользуемся конструкцией ИТОГИ ... ПЕРИОДАМИ.

Рассмотрим синтаксис этого решения:


ВЫБРАТЬ
    Продажи.Дата КАК Дата,
    Продажи.СуммаДокумента КАК Сумма
ИЗ
    Документ.РеализацияТоваровУслуг КАК Продажи
ГДЕ
    Продажи.Дата МЕЖДУ &НачалоПериода И &КонецПериода
ИТОГИ
    СУММА(Сумма)
ПО
    Дата ПЕРИОДАМИ(МЕСЯЦ, &НачалоПериода, &КонецПериода)

В данном случае система сама создаст временные интервалы. Если в данных отсутствует запись за конкретный месяц, 1С все равно добавит строку в выборку итогов, что крайне полезно для построения графиков и динамических таблиц.

Метод 3. Группировка в Системе компоновки данных (СКД)

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

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

  1. В схеме компоновки данных выберем поле с датой (например, ПериодМесяц из виртуальной таблицы оборотов).
  2. Перейдем на вкладку «Настройки».
  3. Добавим новую группировку и выберем наше поле периода.
  4. Чтобы сделать группировку опциональной, вынесем ее в «Пользовательские настройки». Теперь пользователь сможет флажком включать или выключать детализацию по месяцам прямо в форме отчета.

Также в СКД на вкладке «Наборы данных» для поля даты рекомендуется настроить Роль. Укажите тип «Период» и выберите соответствующий уровень (например, дополнительный период для месяца). Это позволит корректно использовать функции дополнения дат.

Сравнение подходов: ГОД(Дата) + МЕСЯЦ(Дата) vs НАЧАЛОПЕРИОДА

Разберем типичную ошибку начинающих разработчиков. Часто пытаются группировать данные, используя отдельные функции для года и месяца:


// Не самый удачный вариант
СГРУППИРОВАТЬ ПО
    ГОД(Дата),
    МЕСЯЦ(Дата)

Выясним, почему этот метод проигрывает использованию НачалоПериода:

Оптимизация: использование виртуальных таблиц

Рассмотрим ситуацию с точки зрения производительности. Если ваша база данных содержит сотни тысяч документов, запрос к таблице Документ.РеализацияТоваровУслуг будет работать медленно, так как системе придется просканировать все записи за период.

Выгоднее использовать виртуальные таблицы регистров накопления (например, Продажи.Обороты). Проанализируем параметры этой таблицы:


ВЫБРАТЬ
    ПродажиОбороты.Период КАК Месяц,
    ПродажиОбороты.СуммаОборот КАК Сумма
ИЗ
    РегистрНакопления.Продажи.Обороты(&Начало, &Конец, Месяц, ) КАК ПродажиОбороты

Третий параметр виртуальной таблицы — Периодичность. Установив значение Месяц, мы заставляем платформу 1С выдавать уже сгруппированные данные. Это в десятки раз быстрее, так как используются заранее рассчитанные итоги регистров.

Полезные советы по форматированию

Чтобы отчет выглядел профессионально, используйте функцию ПРЕДСТАВЛЕНИЕПЕРИОДА. Она позволяет автоматически преобразовать дату начала месяца в красивую строку. Например:

ПРЕДСТАВЛЕНИЕПЕРИОДА(НачалоПериода(Дата, МЕСЯЦ), "L=ru_RU; DF='MMMM yyyy'")

Это преобразует «01.05.2023 00:00:00» в «Май 2023». Однако помните, что результат функции — это строка. Если вы планируете выполнять сортировку в запросе, обязательно оставьте исходное поле с типом Дата для правильного хронологического порядка, а строку используйте только для вывода на экран.

Таким образом, мы выяснили, что для группировки по месяцам в 1С наиболее эффективным является использование виртуальных таблиц с установленной периодичностью, либо применение функции НачалоПериода в сочетании с корректной настройкой ролей полей в СКД.

← На главную