К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как в запросе 1С сгруппировать по месяцу

Как сгруппировать данные по месяцу в запросе 1С: функция Месяц(), периодичность виртуальных таблиц, примеры кода, типичные ошибки и проверка результата.

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

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

Группировка по месяцу через функцию Месяц()

Функция Месяц() принимает выражение типа «Дата» и возвращает число от 1 до 12 — номер месяца. Чтобы получить помесячные итоги, её помещают и в список выбираемых полей, и в секцию СГРУППИРОВАТЬ ПО. Все остальные поля, не входящие в группировку, должны быть обёрнуты агрегатными функциями: СУММА, КОЛИЧЕСТВО, СРЕДНЕЕ, МАКСИМУМ или МИНИМУМ.

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

ВЫБРАТЬ

Месяц(Реализация.Дата) КАК Месяц,

СУММА(Реализация.СуммаДокумента) КАК СуммаПродаж

ИЗ

Документ.РеализацияТоваровУслуг КАК Реализация

ГДЕ

Реализация.Проведен

СГРУППИРОВАТЬ ПО

Месяц(Реализация.Дата)

УПОРЯДОЧИТЬ ПО

Месяц

Обратите внимание: такой запрос корректен только в пределах одного года. Если в выборку попадают документы за несколько лет, январь одного года склеится с январём другого. Поэтому либо ограничивайте период условием ГДЕ Реализация.Дата МЕЖДУ &Начало И &Конец, либо добавляйте в группировку год.

Группировка по месяцу и году одновременно

Универсальный способ, не зависящий от диапазона данных, — добавить в группировку функцию Год(). Тогда каждая строка результата однозначно соответствует паре «год–месяц», а сортировка по двум полям даёт правильную хронологию.

ВЫБРАТЬ

Год(Реализация.Дата) КАК Год,

Месяц(Реализация.Дата) КАК Месяц,

СУММА(Реализация.СуммаДокумента) КАК Сумма

ИЗ

Документ.РеализацияТоваровУслуг КАК Реализация

СГРУППИРОВАТЬ ПО

Год(Реализация.Дата),

Месяц(Реализация.Дата)

УПОРЯДОЧИТЬ ПО

Год, Месяц

Альтернатива — функция НАЧАЛОПЕРИОДА(Дата, Месяц). Она приводит любую дату к первому числу её месяца, и группировка идёт уже по этому значению типа «Дата». Такой вариант удобнее для вывода в отчёт: поле можно напрямую показать пользователю, отформатировав как «ММ.гггг», и сортировка по нему всегда хронологическая без дополнительных полей.

ВЫБРАТЬ

НАЧАЛОПЕРИОДА(Реализация.Дата, Месяц) КАК ПериодМесяц,

СУММА(Реализация.СуммаДокумента) КАК Сумма

ИЗ

Документ.РеализацияТоваровУслуг КАК Реализация

СГРУППИРОВАТЬ ПО

НАЧАЛОПЕРИОДА(Реализация.Дата, Месяц)

УПОРЯДОЧИТЬ ПО

ПериодМесяц

Группировка через периодичность виртуальных таблиц регистров

Если данные берутся из регистра накопления или регистра бухгалтерии, группировку по месяцу выполняет сама платформа. У виртуальных таблиц «Обороты», «ОстаткиИОбороты», «ДвиженияССубконто» есть параметр «Периодичность», который принимает значения: Период, Регистратор, День, Неделя, Месяц, Квартал, Год. При значении «Месяц» платформа возвращает уже свёрнутые итоги с полем Период, равным началу месяца.

ВЫБРАТЬ

Продажи.Период КАК Месяц,

СУММА(Продажи.СуммаОборот) КАК Сумма

ИЗ

РегистрНакопления.Продажи.Обороты(&Начало, &Конец, Месяц, ) КАК Продажи

СГРУППИРОВАТЬ ПО

Продажи.Период

УПОРЯДОЧИТЬ ПО

Месяц

В конструкторе запроса параметр задаётся визуально: выделите виртуальную таблицу, откройте «Параметры виртуальной таблицы» и выберите периодичность «Месяц». Это предпочтительный способ для регистров: платформа использует предрассчитанные итоги, и запрос выполняется заметно быстрее, чем группировка по физической таблице движений.

Сравнение подходов

Месяц() + СГРУППИРОВАТЬ ПО

Подходит для документов и физических таблиц. Требует отдельной группировки по году для данных за несколько лет.

НАЧАЛОПЕРИОДА(Дата, Месяц)

Универсальный вариант: одно поле-период типа «Дата», корректная сортировка и вывод в отчёт.

Периодичность виртуальной таблицы

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

Помесячная группировка с дополнительными измерениями

На практике редко нужен просто итог по месяцам — обычно требуется разрез по контрагентам, номенклатуре или складам. В этом случае все неагрегатные поля добавляются в СГРУППИРОВАТЬ ПО вместе с месяцем. Порядок полей в группировке влияет только на логическую структуру, а вот порядок в УПОРЯДОЧИТЬ ПО определяет, как будет выглядеть результат.

ВЫБРАТЬ

НАЧАЛОПЕРИОДА(Продажи.Период, Месяц) КАК Месяц,

Продажи.Номенклатура КАК Номенклатура,

СУММА(Продажи.Количество) КАК Количество,

СУММА(Продажи.Сумма) КАК Сумма

ИЗ

РегистрНакопления.Продажи КАК Продажи

СГРУППИРОВАТЬ ПО

НАЧАЛОПЕРИОДА(Продажи.Период, Месяц),

Продажи.Номенклатура

УПОРЯДОЧИТЬ ПО

Месяц, Номенклатура

Для отчётов на СКД помесячную группировку обычно делают не в тексте запроса, а в настройках схемы: поле-период выносится в группировку строк, а в ресурсах указывается сумма. Тогда запрос может возвращать детальные записи, а свёртку по месяцам выполнит компоновщик — это даёт пользователю возможность менять разрезы без изменения запроса.

Порядок действий
  1. 1
    Определите источник: виртуальная таблица регистра или документы/физическая таблица.
  2. 2
    Для регистра задайте периодичность «Месяц» в параметрах виртуальной таблицы; для документов используйте НАЧАЛОПЕРИОДА(Дата, Месяц).
  3. 3
    Добавьте поле периода в СГРУППИРОВАТЬ ПО, остальные числовые поля оберните в СУММА() или другую агрегатную функцию.
  4. 4
    Добавьте УПОРЯДОЧИТЬ ПО по полю периода для хронологической сортировки.
  5. 5
    Выполните запрос в консоли и сверьте итоги с типовым отчётом за тот же период.

Проверка результата и типичные ошибки

После написания запроса проверьте его на контрольном примере: возьмите небольшой период, где итоги известны, и сравните суммы с типовым отчётом конфигурации. Совпадение общей суммы при правильном количестве строк-месяцев — признак корректной группировки.

Самые частые проблемы: смешение данных разных лет при группировке только по Месяц(); отсутствие в результате месяцев без движений (запрос не создаёт строки для периодов, где нет данных — для отчётов с обязательной осью месяцев используют таблицу-календарь); ошибка «Поле не входит в группу», когда поле выбрано, но не добавлено в группировку и не агрегировано.

Типичные ошибки
01
Группировка только по Месяц() без года — итоги разных лет складываются в одну строку.
02
Поле в списке выборки без агрегатной функции и без включения в СГРУППИРОВАТЬ ПО — запрос падает с ошибкой исполнения.
03
Ожидание строк за пустые месяцы — запрос вернёт только периоды, где есть данные; для непрерывной оси нужен календарь.
04
Сортировка по номеру месяца без года — декабрь прошлого года встаёт после января текущего некорректно.
05
Группировка по физической таблице регистра вместо виртуальной с периодичностью — лишняя нагрузка и медленное выполнение на больших объёмах.
Контрольные точки

Как проверить результат

Количество строк результата
Норма

Строк столько, сколько месяцев с данными в периоде

Тревожный признак

Строк существенно меньше — вероятно, склеились месяцы разных лет

Общая сумма по всем строкам
Норма

Совпадает с итогом типового отчёта за весь период

Тревожный признак

Итог не сходится — проверяйте условия отбора и агрегатные функции

Порядок строк
Норма

Месяцы идут строго по хронологии

Тревожный признак

Месяцы перемешаны — добавьте год в упорядочивание

Ограничения и альтернативные варианты

Функции Месяц() и НАЧАЛОПЕРИОДА() работают с полями типа «Дата»; применять их к строковым представлениям дат нельзя — сначала приведите значение к дате. В запросах к внешним источникам данных набор доступных функций может отличаться, поэтому для них группировку по месяцу иногда проще выполнить уже на стороне встроенного языка после выгрузки в таблицу значений.

Если нужна не только группировка, но и итоги по месяцам с детализацией внутри, используйте секцию ИТОГИ ПО с указанием поля периода — тогда одним запросом вы получите и помесячные итоги, и детальные записи. Для отчётов, где пользователь сам выбирает периодичность (день, неделя, месяц), удобнее всего схема компоновки данных с вычисляемым полем периода.

Итог

Что важно запомнить

Для регистров задавайте периодичность «Месяц» в виртуальной таблице, для документов — группируйте по НАЧАЛОПЕРИОДА(Дата, Месяц) или паре Год()+Месяц(). Всегда учитывайте год, сортируйте по полю периода и проверяйте итоги на контрольном примере.

Частые вопросы

Как получить название месяца («Январь», «Февраль») вместо номера?

В самом запросе используйте конструкцию ВЫБОР с двенадцатью ветками КОГДА Месяц(Дата) = 1 ТОГДА "Январь" и т.д. Чаще это делают при выводе: применяют функцию Формат() к полю-периоду с строкой формата "ДФ='ММММ гггг'" уже в модуле или в настройках СКД.

Почему в результате нет месяцев, в которых не было движений?

Запрос возвращает только те группы, для которых существуют исходные строки. Чтобы получить все месяцы периода, включая пустые, создайте вспомогательную таблицу-календарь (например, через последовательность дат или регистр сведений с периодами) и выполните левое соединение с данными, заменяя NULL нулём через ЕСТЬNULL().

Чем НАЧАЛОПЕРИОДА лучше пары Год() и Месяц()?

НАЧАЛОПЕРИОДА(Дата, Месяц) даёт одно поле типа «Дата», по которому корректно работают сортировка, итоги и вывод в отчёт без дополнительных полей. Пара Год()+Месяц() требует двух полей в группировке и упорядочивании, но нагляднее, если номер месяца нужен как число для дальнейших вычислений.

Можно ли группировать по месяцу в запросе к регистру сведений?

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

Как сделать помесячную группировку в отчёте на СКД без изменения запроса?

Добавьте в схеме компоновки вычисляемое поле с выражением НачалоПериода(Дата, "Месяц") или просто вынесите поле даты в группировку строк и задайте ему периодичность в настройках. Ресурсы (суммы) компоновщик свернёт автоматически по группировке месяца.