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

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

1С: как получить предыдущий месяц

Как в 1С получить предыдущий месяц: ДобавитьМесяц с отрицательным значением, НачалоМесяца, КонецМесяца, работа с периодами в запросах и СКД. Примеры кода и типичные ошибки.

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

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

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

Функция ДобавитьМесяц — основной способ

Функция ДобавитьМесяц(ИсходнаяДата, ЧислоМесяцев) сдвигает дату на указанное количество месяцев. Чтобы получить предыдущий месяц, вторым параметром передают -1:

ТекущаяДата = ТекущаяДатаСеанса();

ДатаПрошлогоМесяца = ДобавитьМесяц(ТекущаяДата, -1);

Функция корректно обрабатывает переход через год: если исходная дата — 15 января, результатом будет 15 декабря предыдущего года. Вручную уменьшать номер месяца и следить за декабрём не нужно.

Важная особенность — поведение на длинных датах. Если исходная дата 31 марта, то при сдвиге на месяц назад получится 28 (или 29) февраля, потому что 31 февраля не существует. Платформа автоматически берёт последний день целевого месяца. Это нормальное поведение, но его нужно учитывать, если дальше вы снова сдвигаете дату: обратный сдвиг с 28 февраля даст 28 марта, а не 31.

Начало и конец предыдущего месяца

На практике чаще всего нужна не «та же дата месяц назад», а границы предыдущего месяца как периода. Для этого функции комбинируют:

НачалоПрошлогоМесяца = НачалоМесяца(ДобавитьМесяц(ТекущаяДата, -1));

КонецПрошлогоМесяца = КонецМесяца(ДобавитьМесяц(ТекущаяДата, -1));

НачалоМесяца() возвращает первое число месяца в 00:00:00, КонецМесяца() — последнее число в 23:59:59. Такая пара образует замкнутый интервал, который удобно подставлять в условия отборов и параметры запросов.

Есть и альтернативная запись через начало текущего месяца: конец предыдущего месяца — это одна секунда до начала текущего:

КонецПрошлогоМесяца = НачалоМесяца(ТекущаяДата) - 1; // минус 1 секунда

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

Как получить период предыдущего месяца
  1. 1
    Определите базовую дату: ТекущаяДатаСеанса() или дата из параметра отчёта
  2. 2
    Сдвиньте её на месяц назад: ДобавитьМесяц(БазоваяДата, -1)
  3. 3
    Примените НачалоМесяца() для левой границы периода
  4. 4
    Примените КонецМесяца() для правой границы
  5. 5
    Передайте обе даты в запрос или отбор и проверьте результат на границе года (январь)

Название и номер предыдущего месяца

Иногда нужен не период, а представление: номер месяца для вычислений или его название для вывода пользователю. Номер получают функцией Месяц():

НомерПрошлогоМесяца = Месяц(ДобавитьМесяц(ТекущаяДата, -1));

Для января это корректно вернёт 12 — ещё одно преимущество перед ручной арифметикой вида Месяц(Дата) - 1, которая в январе дала бы ноль.

Название месяца для отображения получают через Формат() с форматной строкой:

НазваниеМесяца = Формат(ДобавитьМесяц(ТекущаяДата, -1), "ДФ=MMMM");        // "февраль"

МесяцИГод = Формат(ДобавитьМесяц(ТекущаяДата, -1), "ДФ='MMMM yyyy'"); // "февраль 2026"

Учтите, что Формат() зависит от региональных настроек сеанса: при английской локализации название будет на английском. Если строка используется в печатных формах, проверьте её вид при тех настройках, под которыми работают пользователи.

Предыдущий месяц в запросах

В языке запросов 1С есть собственная функция ДОБАВИТЬКДАТЕ, и работать с периодами удобнее прямо в тексте запроса, не вычисляя даты в коде:

ВЫБРАТЬ

НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&Период, МЕСЯЦ, -1), МЕСЯЦ) КАК НачалоПрошлогоМесяца,

КОНЕЦПЕРИОДА(ДОБАВИТЬКДАТЕ(&Период, МЕСЯЦ, -1), МЕСЯЦ) КАК КонецПрошлогоМесяца

Функции НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА в запросах полностью аналогичны НачалоМесяца и КонецМесяца во встроенном языке. Это позволяет, например, в одном запросе сравнить продажи текущего и предыдущего месяца, сгруппировав данные по периодам.

Типовой приём — передать в запрос один параметр &Период (обычно текущую дату или дату отчёта), а все производные границы вычислить внутри запроса. Так код проще сопровождать, и границы гарантированно согласованы между собой.

Предыдущий месяц в СКД и типовых отчётах

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

Если отчёт строится программно, параметры периода задают через СтандартныйПериод или вручную рассчитанными датами:

Период = Новый СтандартныйПериод(ВариантСтандартногоПериода.ПрошлыйМесяц);

// или вручную:

Период = Новый СтандартныйПериод;

Период.ДатаНачала = НачалоМесяца(ДобавитьМесяц(ТекущаяДатаСеанса(), -1));

Период.ДатаОкончания = КонецМесяца(ДобавитьМесяц(ТекущаяДатаСеанса(), -1));

В схеме компоновки выражения с ДОБАВИТЬКДАТЕ работают так же, как в обычных запросах, поэтому вычисляемые поля «Продажи прошлого месяца» строятся без кода на встроенном языке.

Способы получить предыдущий месяц

ДобавитьМесяц(Дата, -1) в коде

Универсально, подходит для любой логики; границы периода нужно дополнительно получать через НачалоМесяца/КонецМесяца

ДОБАВИТЬКДАТЕ в запросе

Удобно, когда расчёт нужен только в выборке; не применимо вне текста запроса

Стандартный период «Прошлый месяц»

Самый простой вариант для отчётов и настроек пользователя; не подходит для произвольной программной логики

Типичные ошибки и как их проверить

Самая частая ошибка — вычитание фиксированного числа секунд: Дата - 30*24*60*60. Для марта это даст начало марта вместо конца января, для февраля — сдвиг почти на два месяца. Такой код проходит поверхностное тестирование и ломается в конкретные календарные даты.

Вторая ошибка — ручное уменьшение номера месяца через Месяц(Дата) - 1 с последующей сборкой даты через Дата(Год, Месяц, День). В январе номер месяца становится нулём, и функция Дата() либо вернёт некорректное значение, либо вызовет ошибку.

Третья группа проблем — границы периода: использование КонецДня(Дата) вместо КонецМесяца при сравнении периодов, забытое время в дате после ДобавитьМесяц, сравнение дат на точное равенство вместо попадания в интервал. Все они проявляются как «потерянные» документы последнего дня месяца.

Типичные ошибки
01
Вычитание 30 дней вместо ДобавитьМесяц(Дата, -1) — результат неверен для февраля и месяцев разной длины
02
Ручной расчёт Месяц(Дата) - 1 — в январе даёт нулевой месяц и ошибку при сборке даты
03
Игнорирование времени в дате после сдвига — документы за последний день месяца выпадают из отбора
04
Сравнение дат оператором «равно» вместо проверки попадания в период — граничные документы теряются
Контрольные точки

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

Переход через год: базовая дата в январе
Норма

Предыдущий месяц — декабрь, год уменьшился на 1

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

Месяц 0, 13 или ошибка при формировании даты

Длинная дата: 31 марта
Норма

Результат — последний день февраля

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

Ошибка или дата, съехавшая на март

Границы периода
Норма

Начало — 1-е число 00:00:00, конец — последнее число 23:59:59

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

Начало или конец содержат время базовой даты

FAQ

Как получить предыдущий месяц от произвольной даты, а не от текущей?

Тем же способом: ДобавитьМесяц(ПроизвольнаяДата, -1). Функция не привязана к текущей дате — она сдвигает любую переданную дату. Для границ периода оберните результат в НачалоМесяца() или КонецМесяца().

Что вернёт ДобавитьМесяц для 31 марта при сдвиге на месяц назад?

Последний день февраля (28 или 29 число в зависимости от високосности года), потому что 31 февраля не существует. Платформа автоматически берёт последний доступный день целевого месяца.

Как получить несколько месяцев назад, например три?

Передайте в ДобавитьМесяц нужное отрицательное число: ДобавитьМесяц(Дата, -3). В запросе аналогично: ДОБАВИТЬКДАТЕ(&Период, МЕСЯЦ, -3).

Как в запросе отобрать документы только за предыдущий месяц?

Используйте условие: ГДЕ Документ.Дата МЕЖДУ НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&Период, МЕСЯЦ, -1), МЕСЯЦ) И КОНЕЦПЕРИОДА(ДОБАВИТЬКДАТЕ(&Период, МЕСЯЦ, -1), МЕСЯЦ). В параметр &Период передайте любую дату текущего месяца.

Чем ТекущаяДатаСеанса() отличается от ТекущаяДата() при расчёте периода?

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

Как вывести название предыдущего месяца в печатной форме?

Через функцию Формат: Формат(ДобавитьМесяц(Дата, -1), "ДФ='MMMM yyyy'") — получится строка вида «февраль 2026». Учтите, что язык названия зависит от региональных настроек сеанса.

Итог

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

Предыдущий месяц в 1С получают через ДобавитьМесяц(Дата, -1), его границы — через НачалоМесяца и КонецМесяца. В запросах используются ДОБАВИТЬКДАТЕ, НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА. Никогда не вычитайте фиксированное число дней и проверяйте код на январе и на датах вроде 31 марта.