Как реализовать выбор даты с точностью до месяца в поле ввода 1С?

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

При разработке интерфейсов в «1С:Предприятие 8» часто возникает задача дать пользователю возможность выбирать не точную дату, а только расчетный или отчетный период — месяц и год. Разберем особенности платформы, выясним причину ограничений стандартного календаря и рассмотрим практические способы решения этой задачи.

Ограничения стандартного элемента управления

Проанализируем, почему стандартное поле ввода типа Дата не позволяет решить задачу «из коробки»:

  1. Штатный интерактивный календарь: встроенный выпадающий календарь платформы жестко ориентирован на выбор конкретного дня месяца. В платформе нет переключателя, позволяющего перевести встроенный календарь в режим отображения только сетки месяцев или лет.
  2. Форматирование при редактировании: если задать формат отображения через свойство Формат (например, ДФ='ММММ гггг'), значение будет красиво выглядеть только тогда, когда поле не находится в фокусе. В момент начала редактирования платформа переключается на маску ввода даты, требуя ввести день, месяц и год, что сбрасывает удобное строковое представление.

Для обхода этих ограничений разработчики 1С применяют несколько проверенных подходов. Рассмотрим каждый из них подробно.

Способ 1. Использование кнопок регулирования (спиннеров)

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

Разберем по шагам реализацию:

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

Посмотрим на пример клиентского кода:


&НаКлиенте
Процедура ПериодРегулирование(Элемент, Направление, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	
	Если Направление > 0 Тогда
		Объект.ПериодРегистрации = ДобавитьМесяц(Объект.ПериодРегистрации, 1);
	Иначе
		Объект.ПериодРегистрации = ДобавитьМесяц(Объект.ПериодРегистрации, -1);
	КонецЕсли;
	
	// Приводим дату к началу месяца
	Объект.ПериодРегистрации = НачалоМесяца(Объект.ПериодРегистрации);
	
КонецПроцедуры

Для отображения текста можно использовать заголовок поля или отформатировать поле ввода с запретом прямого редактирования текста, оставив только реакцию на стрелки.

Способ 2. Строковый реквизит формы с синхронизацией (подход ЗУП)

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

Рассмотрим логику работы этой схемы:

  1. В реквизитах формы создаем строку ПериодСтрокой.
  2. При открытии формы (или при чтении объекта на сервере) преобразуем дату документа в читаемый вид: Формат(Объект.Период, "ДФ='ММММ гггг'").
  3. При изменении строкового поля парсим введенное значение и записываем полученную дату обратно в реквизит объекта.

Посмотрим, как выглядит программная обработка синхронизации:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	Если ЗначениеЗаполнено(Объект.ПериодРегистрации) Тогда
		ПериодСтрокой = Формат(Объект.ПериодРегистрации, "ДФ='ММММ гггг'");
	Иначе
		Объект.ПериодРегистрации = НачалоМесяца(ТекущаяДата());
		ПериодСтрокой = Формат(Объект.ПериодРегистрации, "ДФ='ММММ гггг'");
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПериодСтрокойПриИзменении(Элемент)
	
	// Передаем введенный текст на сервер для преобразования в дату
	СинхронизироватьПериодНаСервере();
	
КонецПроцедуры

Способ 3. Выбор из предопределенного списка

Если выбор ограничен обозримым интервалом (например, текущий год плюс/минус один год), наиболее простым решением без создания дополнительных форм будет использование выпадающего списка выбора.

Разберем настройку по шагам:

  1. У поля ввода даты устанавливаем свойства: РежимВыбораИзСписка = Истина, КнопкаВыпадающегоСписка = Истина, КнопкаВыбора = Ложь.
  2. В обработчике ПриСозданииНаСервере программно заполняем список выбора значениями дат начала месяцев и их строковыми представлениями.

Посмотрим на пример заполнения списка выбора:


&НаСервере
Процедура ЗаполнитьСписокМесяцев()
	
	СписокВыбора = Элементы.ПолеПериод.СписокВыбора;
	СписокВыбора.Очистить();
	
	ДатаИтерации = НачалоГода(ДобавитьМесяц(ТекущаяДата(), -12));
	ДатаКонца = КонецГода(ДобавитьМесяц(ТекущаяДата(), 12));
	
	Пока ДатаИтерации <= ДатаКонца Цикл
		Представление = Формат(ДатаИтерации, "ДФ='ММММ гггг'");
		СписокВыбора.Добавить(ДатаИтерации, Представление);
		ДатаИтерации = ДобавитьМесяц(ДатаИтерации, 1);
	КонецЦикла;
	
КонецПроцедуры

Способ 4. Переопределение кнопки выбора и собственная форма

Если требуется предоставить пользователю визуальный выбор месяца в виде плитки (3х4 месяца) с переключением года:

  1. Создаем отдельную общую форму или форму обработки с сеткой кнопок для 12 месяцев и полем выбора года.
  2. В основном поле ввода включаем свойство КнопкаВыбора = Истина.
  3. В событии НачалоВыбора отключаем стандартную обработку и открываем созданную форму выбора:

&НаКлиенте
Процедура ПериодНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	
	Оповещение = Новый ОписаниеОповещения("ПослеВыбораПериода", ЭтотОбъект);
	ПараметрыФормы = Новый Структура("ТекущийПериод", Объект.ПериодРегистрации);
	
	ОткрытьФорму("ОбщаяФорма.ФормаВыбораМесяца", ПараметрыФормы, Элемент, , , , Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
	
КонецПроцедуры

&НаКлиенте
Процедура ПослеВыбораПериода(РезультатВыбора, ДополнительныеПараметры) Экспорт
	
	Если ЗначениеЗаполнено(РезультатВыбора) Тогда
		Объект.ПериодРегистрации = НачалоМесяца(РезультатВыбора);
	КонецЕсли;
	
КонецПроцедуры

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

← На главную