Поле «Месяц» на форме 1С 8.3: ввод, листание и отбор данных за период
Содержание
Чтобы пользователь выбирал месяц, а не конкретную дату, заведите на форме реквизит типа Дата (состав даты — «Дата»), задайте полю формат ДФ='ММММ гггг' и в обработчике ПриИзменении приводите значение к первому числу через НачалоМесяца(). Для отбора в запросе передавайте две границы: НачалоМесяца(Месяц) и КонецМесяца(Месяц).
Дальше всё сводится к деталям: как показать удобный диалог, как листать месяцы стрелками, как не потерять последний день периода в запросе и почему выборка по месяцу иногда работает медленно. Всё ниже — для управляемых форм платформы 8.3 в интерфейсе «Такси».
Как выбор месяца устроен в типовых конфигурациях
В типовых решениях встречаются три подхода. Полезно знать их, прежде чем писать своё: пользователи уже привыкли к этим паттернам.
- 📅 Месяц как дата на первое число. Так хранят «Месяц начисления» в зарплатных документах и период регламентных операций. В базе лежит
01.10.2026 0:00:00, на форме видно «Октябрь 2026». - ⬅️➡️ Строка с представлением и кнопками листания. В ЗУП поле месяца выглядит как текст «Октябрь 2026» со стрелками по бокам. Стрелки сдвигают месяц на один вперёд или назад, кнопка выбора открывает подбор.
- 🗓️ Стандартный период. В отчётах на СКД и в журналах используется тип
СтандартныйПериодс вариантами «Этот месяц», «Прошлый месяц» и произвольным интервалом. Пользователь выбирает месяц в стандартном диалоге настройки периода.
Первый вариант — основа. Второй — его удобная оболочка. Третий нужен, когда пользователь может выбрать не только месяц, но и квартал, год или произвольные даты.
| Подход | Что хранится | Когда брать |
|---|---|---|
| Дата на первое число | Дата | Документы, регистры, параметры обработок |
| Строка + листание | Дата + строковое представление | Частое переключение соседних месяцев |
| Стандартный период | СтандартныйПериод | Отчёты, где месяц — лишь один из вариантов |
ВыборДаты, ВвестиДату и ПоказатьВводДаты: получаем месяц из диалога
Глобального метода ВыборДаты в синтаксис-помощнике платформы нет. Под этим названием обычно ищут штатный диалог ввода даты. В 8.3 их два.
ВвестиДату(Дата, Подсказка, ЧастьДаты)— модальный вызов. При режиме использования модальности «Не использовать» он вызывает ошибку, поэтому в новых разработках его не применяют.ПоказатьВводДаты(ОписаниеОповещения, Дата, Подсказка, ЧастьДаты)— немодальный аналог. Результат приходит в процедуру-обработчик оповещения.
Диалог отдаёт полную дату, а не месяц. Месяц из неё получают функцией НачалоМесяца():
&НаКлиенте
Процедура ВыбратьМесяц(Команда)
Оповещение = Новый ОписаниеОповещения("ВыбратьМесяцЗавершение", ЭтотОбъект);
ПоказатьВводДаты(Оповещение, Месяц, "Укажите любой день нужного месяца", ЧастиДаты.Дата);
КонецПроцедуры
&НаКлиенте
Процедура ВыбратьМесяцЗавершение(ВыбраннаяДата, ДополнительныеПараметры) Экспорт
Если ВыбраннаяДата = Неопределено Тогда
Возврат; // пользователь закрыл диалог
КонецЕсли;
Месяц = НачалоМесяца(ВыбраннаяДата);
КонецПроцедуры
Обработчик оповещения обязательно объявляйте с Экспорт. Без этого платформа не сможет его вызвать, и выбор молча не сработает.
Выбор из списка двенадцати месяцев
Календарь заставляет щёлкать по дню, хотя день не нужен. Если месяцы ограничены одним годом, удобнее список. Его собирают в СписокЗначений и показывают методом ПоказатьВыборЭлемента:
&НаКлиенте
Процедура ПоказатьСписокМесяцев()
Список = Новый СписокЗначений;
НачалоГодаВыбора = НачалоГода(?(ЗначениеЗаполнено(Месяц), Месяц, ТекущаяДата()));
Для Номер = 0 По 11 Цикл
ДатаМесяца = ДобавитьМесяц(НачалоГодаВыбора, Номер);
Список.Добавить(ДатаМесяца, Формат(ДатаМесяца, "ДФ='ММММ гггг'"));
КонецЦикла;
Текущий = Список.НайтиПоЗначению(НачалоМесяца(Месяц));
Оповещение = Новый ОписаниеОповещения("СписокМесяцевЗавершение", ЭтотОбъект);
Список.ПоказатьВыборЭлемента(Оповещение, "Выберите месяц", Текущий);
КонецПроцедуры
&НаКлиенте
Процедура СписокМесяцевЗавершение(ВыбранныйЭлемент, ДополнительныеПараметры) Экспорт
Если ВыбранныйЭлемент <> Неопределено Тогда
Месяц = ВыбранныйЭлемент.Значение;
КонецЕсли;
КонецПроцедуры
Цикл даёт ровно 12 элементов: от 0 до 11 включительно. ДобавитьМесяц к первому января сдвигает дату на нужное число месяцев без проблем с короткими месяцами, потому что исходный день — первое число.
Стандартный диалог периода
Если нужен именно СтандартныйПериод, используйте ДиалогРедактированияСтандартногоПериода. В нём есть готовые варианты, включая «Этот месяц» и «Прошлый месяц»:
&НаКлиенте
Процедура НастроитьПериод(Команда)
Диалог = Новый ДиалогРедактированияСтандартногоПериода;
Диалог.Период = Период;
Диалог.Показать(Новый ОписаниеОповещения("НастроитьПериодЗавершение", ЭтотОбъект));
КонецПроцедуры
&НаКлиенте
Процедура НастроитьПериодЗавершение(НовыйПериод, ДополнительныеПараметры) Экспорт
Если НовыйПериод <> Неопределено Тогда
Период = НовыйПериод;
КонецЕсли;
КонецПроцедуры
Своё поле выбора месяца на управляемой форме
Готового элемента «Поле месяца» в платформе нет. Его собирают из обычного поля ввода и нескольких обработчиков событий.
Шаг 1. Реквизит и формат отображения
- Добавьте реквизит формы
Месяцс типомДата, в квалификаторах выберите состав даты «Дата». - Перетащите реквизит на форму, откройте свойства элемента.
- В свойстве «Формат» задайте
ДФ='ММММ гггг'— поле покажет «Октябрь 2026». - В свойстве «Формат редактирования» задайте
ДФ=ММ.гггг. Пользователь вводит с клавиатуры «10.2026», день платформа подставит сама. - Включите свойство «Кнопка регулирования» — у поля появятся стрелки.
Для реквизита документа или справочника всё то же самое, только реквизит создаётся в метаданных объекта, а формат можно задать прямо у реквизита в конфигурации. Тогда он подхватится на всех формах.
Шаг 2. Нормализация и листание
Пользователь всё равно может выбрать в календаре 17-е число. Приводим значение к началу месяца при каждом изменении и обрабатываем стрелки:
&НаКлиенте
Процедура МесяцПриИзменении(Элемент)
Если ЗначениеЗаполнено(Месяц) Тогда
Месяц = НачалоМесяца(Месяц);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура МесяцРегулирование(Элемент, Направление, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Если Не ЗначениеЗаполнено(Месяц) Тогда
Месяц = НачалоМесяца(ТекущаяДата());
КонецЕсли;
Месяц = ДобавитьМесяц(НачалоМесяца(Месяц), Направление);
КонецПроцедуры
Без СтандартнаяОбработка = Ложь стрелка сдвинет дату на день, а не на месяц: это поведение регулирования поля даты по умолчанию. Направление приходит как 1 или -1, его можно сразу передавать в ДобавитьМесяц.
Шаг 3. Подмена кнопки выбора
Если вместо календаря нужен список месяцев из предыдущего раздела, перехватите событие НачалоВыбора:
&НаКлиенте
Процедура МесяцНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ПоказатьСписокМесяцев();
КонецПроцедуры
Изменение реквизита из кода не вызывает событие ПриИзменении элемента. Если после выбора месяца нужно перезаполнить таблицу или обновить отбор, вызовите эту логику явно в обработчике оповещения.
Строковое представление, как в ЗУП
Вариант с текстом и стрелками делается через два реквизита: Месяц (дата, хранится) и МесяцСтрокой (строка, только для показа). На форму выводят МесяцСтрокой, кнопки выбора и регулирования меняют Месяц, а после каждого изменения пересчитывают строку:
&НаКлиенте
Процедура ОбновитьПредставлениеМесяца()
МесяцСтрокой = Формат(Месяц, "ДФ='ММММ гггг'");
КонецПроцедуры
Плюс подхода — полный контроль над видом поля. Минус — ручной ввод с клавиатуры придётся разбирать самостоятельно, например в событии ОкончаниеВводаТекста. Если ручной ввод не нужен, отключите редактирование текста в свойствах поля.
Границы месяца в запросах 1С
Самая частая ошибка — передать в запрос одну дату и сравнить с ней поле Дата. Документ от 15.10.2026 14:30:00 не равен 01.10.2026, и выборка вернётся пустой.
Правильно передавать две границы:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Реализация.Ссылка,
| Реализация.Дата
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
| Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода";
Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(Месяц));
Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(Месяц));
КонецМесяца() возвращает последний день месяца со временем 23:59:59. Поэтому документы последнего дня попадают в выборку. Если вместо этого подставить ДобавитьМесяц(Месяц, 1) - 1, получите то же значение, но код читается хуже.
Группировка по месяцам внутри запроса
Когда нужен свод по нескольким месяцам, используйте функцию языка запросов НАЧАЛОПЕРИОДА(Поле, МЕСЯЦ) в секции ВЫБРАТЬ и СГРУППИРОВАТЬ ПО:
ВЫБРАТЬ
НАЧАЛОПЕРИОДА(Реализация.Дата, МЕСЯЦ) КАК Месяц,
КОЛИЧЕСТВО(Реализация.Ссылка) КАК Документов
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода
СГРУППИРОВАТЬ ПО
НАЧАЛОПЕРИОДА(Реализация.Дата, МЕСЯЦ)
Регистры: обороты и остатки на конец месяца
У виртуальной таблицы оборотов есть параметр периодичности. Указав Месяц, вы получите поле Период с первым числом каждого месяца:
ВЫБРАТЬ
Обороты.Период,
Обороты.Номенклатура,
Обороты.КоличествоОборот
ИЗ
РегистрНакопления.ТоварыНаСкладах.Обороты(&НачалоПериода, &КонецПериода, Месяц, ) КАК Обороты
Имя регистра здесь условное — подставьте свой. Для остатков на конец выбранного месяца передайте границу, которая включает последний момент периода:
Запрос.УстановитьПараметр("НаДату", Новый Граница(КонецМесяца(Месяц), ВидГраницы.Включая));
Для периодического регистра сведений срез на месяц берут через СрезПоследних(&НаДату), где в параметр передают КонецМесяца(Месяц).
Месяц как параметр отчёта на СКД
В отчёте на системе компоновки поле месяца на форме часто делают отдельным реквизитом, а в схему передают уже границы. Так пользователь видит одно поле «Октябрь 2026», а запрос получает привычные &НачалоПериода и &КонецПериода.
Параметры передают через настройки компоновщика перед формированием:
&НаСервере
Процедура ПередатьМесяцВОтчет()
Параметры = Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных;
Параметры.УстановитьЗначениеПараметра("НачалоПериода", НачалоМесяца(Месяц));
Параметры.УстановитьЗначениеПараметра("КонецПериода", КонецМесяца(Месяц));
КонецПроцедуры
Имена параметров должны совпадать с именами в схеме компоновки. Если в схеме параметр не найден, значение просто не установится, а отчёт выведет данные за пустой период. Поэтому после переименования параметров в схеме проверьте и этот код.
Сами параметры НачалоПериода и КонецПериода в схеме лучше скрыть от пользователя: снимите у них флажок доступности в настройках. Иначе на форме окажутся два способа задать период, и они начнут спорить друг с другом.
Проверка выбранного месяца
Пустой месяц или месяц не с первого числа ломают расчёты тихо: отчёт просто покажет нули. Проверяйте значение до записи.
Обязательность и сообщение у поля
Для реквизита объекта проще всего включить свойство «Проверка заполнения» → «Выдавать ошибку». Если правила сложнее, проверяйте в модуле объекта:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Если ЗначениеЗаполнено(Месяц) И Месяц <> НачалоМесяца(Месяц) Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Месяц должен быть указан на первое число";
Сообщение.Поле = "Месяц";
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Привязка через Поле и УстановитьДанные подсветит именно поле месяца на форме.
Защита от будущих и закрытых периодов
- 🚫 Месяц в будущем. Сравнивайте с
НачалоМесяца(ТекущаяДатаСеанса())на сервере, а не с датой компьютера пользователя. - 🔒 Закрытый период. В типовых конфигурациях на БСП для этого есть механизм дат запрета изменения. Не дублируйте его своей проверкой, а настройте дату запрета.
- 🧹 Нормализация при записи. Даже если форма приводит значение к первому числу, данные могут прийти через обмен или загрузку. Добавьте
Месяц = НачалоМесяца(Месяц)вПередЗаписьюобъекта.
Не исправляйте массово старые записи, где месяц лежит не на первое число, без резервной копии базы. Такие правки меняют движения и могут сдвинуть итоги закрытых периодов.
Как ускорить выборку данных за месяц
Месяц — удобная единица для итогов, и платформа этим пользуется. Важно не мешать ей.
| Приём | Почему работает |
|---|---|
Условие Дата МЕЖДУ &Начало И &Конец | Используется индекс по полю даты |
Отбор в параметрах виртуальной таблицы, а не в ГДЕ | Отбор применяется до соединений и расчёта |
Периодичность Месяц у таблицы оборотов | Данные берутся из итогов, а не из всех движений |
| Остатки на границу месяца, а не расчёт по движениям | Меньше строк для обработки |
Чего избегать:
- ❌
ГДЕ МЕСЯЦ(Дата) = 10 И ГОД(Дата) = 2026— функция над полем не даёт использовать индекс, СУБД перебирает таблицу целиком. - ❌
ГДЕ НАЧАЛОПЕРИОДА(Дата, МЕСЯЦ) = &Месяц— та же проблема. - ❌ Запрос в цикле по месяцам. Двенадцать запросов за год медленнее одного с группировкой по
НАЧАЛОПЕРИОДА. - ❌ Отбор по
Периодпосле получения всей виртуальной таблицы вместо её параметров.
Если отчёт за месяц по регистру накопления строится долго, проверьте в Конфигураторе, включены ли итоги регистра. Пересчёт итогов выполняйте вне рабочего времени: он нагружает базу и замедляет работу пользователей.
Частые вопросы
Как вывести месяц в родительном падеже, например «октября»?
ДФ='д ММММ гггг' выведет «1 октября 2026». Без дня ММММ даёт именительный падеж.Можно ли хранить месяц числом от 1 до 12?
Как по умолчанию подставить прошлый месяц?
ПриСозданииНаСервере присвойте Месяц = ДобавитьМесяц(НачалоМесяца(ТекущаяДатаСеанса()), -1).Почему в отчёте на СКД нет выбора одного месяца?
СтандартныйПериод и вариант по умолчанию «Этот месяц» или «Прошлый месяц». Пользователь переключит его в диалоге периода.Работает ли ПоказатьВводДаты в веб-клиенте?
ВвестиДату в веб-клиенте лучше не использовать.