Разработка и Конфигурация · 10 мин
1С: как получить прошлый месяц в коде и запросах
Как в 1С получить прошлый месяц: ДобавитьМесяц, НачалоМесяца, КонецМесяца, представление периода строкой. Примеры кода, запросы, типовые ошибки и FAQ.
Задача получить прошлый месяц возникает в 1С постоянно: при формировании отчётов за предыдущий период, при автоматическом закрытии месяца, при подстановке дат в документы и при сравнении показателей с прошлым периодом. Во встроенном языке 1С для этого есть готовые функции работы с датами, и правильный их выбор зависит от того, что именно нужно: дата начала прошлого месяца, его конец, представление в виде строки или период для запроса.
Ключевая функция — ДобавитьМесяц(), которая сдвигает дату на заданное количество месяцев, в том числе назад при отрицательном аргументе. В сочетании с НачалоМесяца() и КонецМесяца() она покрывает практически все сценарии. Ниже разобраны конкретные примеры кода, работа с запросами, получение названия месяца и типичные ошибки, из-за которых период рассчитывается неверно.
Получение даты прошлого месяца функцией ДобавитьМесяц
Функция ДобавитьМесяц(ИсходнаяДата, ЧислоМесяцев) возвращает дату, смещённую на указанное количество месяцев. Чтобы получить прошлый месяц, второй параметр должен быть отрицательным: -1. Функция корректно обрабатывает переход через год: если текущая дата в январе, результат попадёт в декабрь предыдущего года, дополнительных проверок писать не нужно.
ТекущаяДата = ТекущаяДата();
ДатаПрошлогоМесяца = ДобавитьМесяц(ТекущаяДата, -1);
Важная особенность: функция сохраняет номер дня, если он существует в целевом месяце. Если текущая дата — 31 марта, то при сдвиге на месяц назад результатом будет 28 или 29 февраля (последний день месяца), а не «31 февраля». Это стандартное поведение, но его нужно учитывать, если от номера дня зависит дальнейшая логика — например, график платежей.
Для сдвига на произвольное количество месяцев назад просто меняйте параметр: ДобавитьМесяц(Дата, -3) вернёт дату тремя месяцами ранее. Это удобно в отчётах, где пользователь выбирает глубину анализа.
Как получить начало и конец прошлого месяца
Чаще всего нужна не просто «та же дата месяц назад», а границы периода: первое и последнее число прошлого месяца. Для этого функции комбинируются:
НачалоПрошлогоМесяца = НачалоМесяца(ДобавитьМесяц(ТекущаяДата(), -1));
КонецПрошлогоМесяца = КонецМесяца(ДобавитьМесяц(ТекущаяДата(), -1));
НачалоМесяца() возвращает дату с временем 00:00:00 первого числа, а КонецМесяца() — 23:59:59 последнего числа. Пара этих значений подходит для отбора документов, установки периода в отчёте или параметров запроса. Обратите внимание: если сравнивать даты документов условием «меньше или равно концу периода», составная дата 23:59:59 корректно захватывает все документы последнего дня.
НачалоПрошлогоМесяца = НачалоМесяца(ДобавитьМесяц(ТекущаяДата(), -1));
КонецПрошлогоМесяца = КонецМесяца(ДобавитьМесяц(ТекущаяДата(), -1));
Сообщить("Период: " + НачалоПрошлогоМесяца + " - " + КонецПрошлогоМесяца);Альтернативный приём без ДобавитьМесяц: конец прошлого месяца — это начало текущего минус одна секунда. Вариант НачалоМесяца(ТекущаяДата()) - 1 тоже даёт последнюю секунду прошлого месяца. Оба способа рабочие, но комбинация с ДобавитьМесяц читается понятнее и реже вызывает вопросы при сопровождении кода.
Получение прошлого месяца в запросе
Если период нужен внутри запроса, есть два пути: вычислить даты в коде и передать их параметрами, либо использовать функции языка запросов. Первый способ предпочтительнее: параметры проще отлаживать, и запрос не зависит от серверной текущей даты.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Продажи.СуммаОборот КАК Сумма
|ИЗ
| РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК Продажи";
Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ДобавитьМесяц(ТекущаяДата(), -1)));
Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(ДобавитьМесяц(ТекущаяДата(), -1)));
Если вычисление требуется непосредственно в тексте запроса, используйте функцию ДОБАВИТЬКДАТЕ(&ТекущаяДата, МЕСЯЦ, -1). Также в языке запросов доступны НАЧАЛОПЕРИОДА(Дата, МЕСЯЦ) и КОНЕЦПЕРИОДА(Дата, МЕСЯЦ), которые выполняют ту же роль, что и НачалоМесяца/КонецМесяца во встроенном языке.
Как получить название и номер прошлого месяца
Для заголовков отчётов, печатных форм и сообщений пользователю часто нужно не значение даты, а строка вида «Сентябрь» или число месяца. Номер месяца возвращает функция Месяц(), год — Год():
ДатаПрошлогоМесяца = ДобавитьМесяц(ТекущаяДата(), -1);
НомерМесяца = Месяц(ДатаПрошлогоМесяца);
ГодПериода = Год(ДатаПрошлогоМесяца);
Название месяца удобно получать через Формат() с форматной строкой: Формат(ДатаПрошлогоМесяца, "ДФ=MMMM") вернёт полное название месяца с учётом региональных настроек, а Формат(ДатаПрошлогоМесяца, "ДФ='MMMM yyyy'") — строку вида «сентябрь 2026». Функция ПредставлениеПериода(НачалоПрошлогоМесяца, КонецПрошлогоМесяца, "ФП=Истина") даёт готовое локализованное представление периода целиком.
- 1Определите опорную дату: ТекущаяДата() или дата из параметров задачи
- 2Сместите её на месяц назад: ДобавитьМесяц(Дата, -1)
- 3При необходимости получите границы: НачалоМесяца() и КонецМесяца()
- 4Для строки используйте Формат() с ДФ=MMMM или ПредставлениеПериода()
- 5Проверьте результат на границе года: дата в январе должна дать декабрь прошлого года
Использование в типовых механизмах: отчёты и СКД
В отчётах на СКД прошлый месяц обычно задаётся не кодом, а стандартными периодами. В пользовательских настройках доступен вариант «Прошлый месяц», который платформа вычисляет автоматически относительно текущей даты. Если отчёт строится программно, период можно установить через СтандартныйПериод с вариантом ВариантСтандартногоПериода.ПрошлыйМесяц.
Период = Новый СтандартныйПериод(ВариантСтандартногоПериода.ПрошлыйМесяц);
// Период.ДатаНачала и Период.ДатаОкончания уже заполнены
Для регламентных заданий (например, ежемесячная рассылка отчёта первого числа) вычисляйте период в коде через ДобавитьМесяц, а не храните даты в константах — иначе период придётся обновлять вручную. Это же правило касается обменов и выгрузок: период всегда должен вычисляться в момент выполнения.
Сравнение вариантов
Универсальный способ для кода и параметров запроса. Полный контроль над результатом.
Подходит для отчётов и СКД. Не подходит, если нужна произвольная опорная дата, а не текущая.
Когда вычисление должно выполняться на уровне запроса. Сложнее отлаживать, чем параметры.
Частые ошибки при расчёте прошлого месяца
Самая распространённая ошибка — вычитание фиксированного числа дней (30 или 31) вместо ДобавитьМесяц. Месяцы имеют разную длину, поэтому ТекущаяДата() - 30*86400 в марте даст конец января, а не начало февраля. Такой код работает «почти всегда» и ломается в самый неподходящий момент.
Вторая ошибка — использование ТекущаяДата() на клиенте в толстом клиенте или в мобильном приложении там, где важна серверная дата. Если клиент и сервер находятся в разных часовых поясах, на границе месяца можно получить неверный период. В серверном коде применяйте ТекущаяДатаСеанса() — она учитывает часовой пояс сеанса и корректнее для учётных задач.
Третья группа проблем — неправильные границы периода в запросах: передача начала месяца без времени, сравнение «меньше конца периода» вместо «меньше или равно», из-за чего из выборки выпадают документы последней секунды. Всегда проверяйте граничные документы: первый и последний документ месяца должны попадать в выборку.
Проверка результата и отладка
Проверять вычисление периода удобнее всего в консоли кода (внешняя обработка «Консоль кода» или аналогичный инструмент из вашего инструментария разработчика) либо через Сообщить() в отладочном запуске. Выведите начало и конец периода и сверьте с календарём: первое число, время 00:00:00 и 23:59:59, корректный год при переходе через январь.
Для запросов контролируйте результат по эталонным данным: возьмите документ с известной датой в прошлом месяце и убедитесь, что он попадает в выборку, а документ текущего месяца — нет. Если период вычисляется в регламентном задании, добавьте запись рассчитанных границ в журнал регистрации — это сильно упрощает разбор инцидентов, когда отчёт «внезапно» пришёл за не тот месяц.
Как проверить результат
Первое число прошлого месяца, время 00:00:00
Дата со смещением на несколько дней или ненулевое время
Последнее число прошлого месяца, 23:59:59
Первое число текущего месяца или время 00:00:00
Для января получен декабрь предыдущего года
Месяц 0, 13 или ошибка преобразования даты
FAQ
Как получить прошлый месяц от произвольной даты, а не от текущей?
Передайте нужную дату первым параметром: ДобавитьМесяц(ПроизвольнаяДата, -1). Логика не меняется — функция работает с любым значением типа Дата, включая даты из реквизитов документов и параметров.
Что вернёт ДобавитьМесяц для 31 числа, если в прошлом месяце 30 дней?
Функция вернёт последний день целевого месяца. Например, ДобавитьМесяц(31.05, -1) даст 30.04. Это штатное поведение, ошибкой оно не является.
Как получить прошлый месяц в запросе без параметров?
Используйте функции языка запросов: ДОБАВИТЬКДАТЕ(&ТекущаяДата, МЕСЯЦ, -1) для сдвига и НАЧАЛОПЕРИОДА/КОНЕЦПЕРИОДА с типом МЕСЯЦ для границ. Однако передача готовых дат параметрами предпочтительнее для отладки.
Чем ТекущаяДатаСеанса лучше ТекущейДаты?
ТекущаяДатаСеанса учитывает часовой пояс сеанса и возвращает согласованное время сервера, тогда как ТекущаяДата на клиенте берёт время компьютера пользователя. Для расчёта учётных периодов безопаснее ТекущаяДатаСеанса.
Как вывести прошлый месяц в заголовке отчёта?
Используйте Формат(ДобавитьМесяц(ТекущаяДатаСеанса(), -1), "ДФ='MMMM yyyy'") — получите строку вида «сентябрь 2026». Для полного периода подойдёт ПредставлениеПериода с флагом ФП=Истина.
Как получить аналогичный месяц прошлого года?
Примените ДобавитьМесяц(Дата, -12). Это частый приём для сравнения показателей год к году: сдвиг на 12 месяцев корректно обрабатывает високосные годы и границы периодов.
Что важно запомнить
Прошлый месяц в 1С получают через ДобавитьМесяц(Дата, -1), границы периода — через НачалоМесяца и КонецМесяца. В запросах передавайте вычисленные даты параметрами, в отчётах используйте стандартный период «Прошлый месяц». Не вычитайте дни вручную и применяйте ТекущаяДатуСеанса для учётных расчётов.