При разработке интерфейсов в «1С:Предприятие 8» часто возникает задача дать пользователю возможность выбирать не точную дату, а только расчетный или отчетный период — месяц и год. Разберем особенности платформы, выясним причину ограничений стандартного календаря и рассмотрим практические способы решения этой задачи.
Проанализируем, почему стандартное поле ввода типа Дата не позволяет решить задачу «из коробки»:
Формат (например, ДФ='ММММ гггг'), значение будет красиво выглядеть только тогда, когда поле не находится в фокусе. В момент начала редактирования платформа переключается на маску ввода даты, требуя ввести день, месяц и год, что сбрасывает удобное строковое представление.Для обхода этих ограничений разработчики 1С применяют несколько проверенных подходов. Рассмотрим каждый из них подробно.
Это один из самых компактных и удобных вариантов, если пользователю чаще всего требуется сдвигать период на один или несколько месяцев вперед или назад.
Разберем по шагам реализацию:
ПериодРегистрации с типом Дата.Регулирование.ДобавитьМесяц.Посмотрим на пример клиентского кода:
&НаКлиенте
Процедура ПериодРегулирование(Элемент, Направление, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Если Направление > 0 Тогда
Объект.ПериодРегистрации = ДобавитьМесяц(Объект.ПериодРегистрации, 1);
Иначе
Объект.ПериодРегистрации = ДобавитьМесяц(Объект.ПериодРегистрации, -1);
КонецЕсли;
// Приводим дату к началу месяца
Объект.ПериодРегистрации = НачалоМесяца(Объект.ПериодРегистрации);
КонецПроцедуры
Для отображения текста можно использовать заголовок поля или отформатировать поле ввода с запретом прямого редактирования текста, оставив только реакцию на стрелки.
В типовых конфигурациях (например, в «1С:Зарплата и управление персоналом») для выбора месяца на форме создается дополнительный строковый реквизит. При этом в самом объекте или документе реквизит остается полноценной датой (первое число месяца).
Рассмотрим логику работы этой схемы:
ПериодСтрокой.Формат(Объект.Период, "ДФ='ММММ гггг'").Посмотрим, как выглядит программная обработка синхронизации:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если ЗначениеЗаполнено(Объект.ПериодРегистрации) Тогда
ПериодСтрокой = Формат(Объект.ПериодРегистрации, "ДФ='ММММ гггг'");
Иначе
Объект.ПериодРегистрации = НачалоМесяца(ТекущаяДата());
ПериодСтрокой = Формат(Объект.ПериодРегистрации, "ДФ='ММММ гггг'");
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПериодСтрокойПриИзменении(Элемент)
// Передаем введенный текст на сервер для преобразования в дату
СинхронизироватьПериодНаСервере();
КонецПроцедуры
Если выбор ограничен обозримым интервалом (например, текущий год плюс/минус один год), наиболее простым решением без создания дополнительных форм будет использование выпадающего списка выбора.
Разберем настройку по шагам:
РежимВыбораИзСписка = Истина, КнопкаВыпадающегоСписка = Истина, КнопкаВыбора = Ложь.ПриСозданииНаСервере программно заполняем список выбора значениями дат начала месяцев и их строковыми представлениями.Посмотрим на пример заполнения списка выбора:
&НаСервере
Процедура ЗаполнитьСписокМесяцев()
СписокВыбора = Элементы.ПолеПериод.СписокВыбора;
СписокВыбора.Очистить();
ДатаИтерации = НачалоГода(ДобавитьМесяц(ТекущаяДата(), -12));
ДатаКонца = КонецГода(ДобавитьМесяц(ТекущаяДата(), 12));
Пока ДатаИтерации <= ДатаКонца Цикл
Представление = Формат(ДатаИтерации, "ДФ='ММММ гггг'");
СписокВыбора.Добавить(ДатаИтерации, Представление);
ДатаИтерации = ДобавитьМесяц(ДатаИтерации, 1);
КонецЦикла;
КонецПроцедуры
Если требуется предоставить пользователю визуальный выбор месяца в виде плитки (3х4 месяца) с переключением года:
КнопкаВыбора = Истина.НачалоВыбора отключаем стандартную обработку и открываем созданную форму выбора:
&НаКлиенте
Процедура ПериодНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Оповещение = Новый ОписаниеОповещения("ПослеВыбораПериода", ЭтотОбъект);
ПараметрыФормы = Новый Структура("ТекущийПериод", Объект.ПериодРегистрации);
ОткрытьФорму("ОбщаяФорма.ФормаВыбораМесяца", ПараметрыФормы, Элемент, , , , Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораПериода(РезультатВыбора, ДополнительныеПараметры) Экспорт
Если ЗначениеЗаполнено(РезультатВыбора) Тогда
Объект.ПериодРегистрации = НачалоМесяца(РезультатВыбора);
КонецЕсли;
КонецПроцедуры
Резюме: для простых задач и быстрого ввода оптимально использовать поле с кнопками регулирования (ДобавитьМесяц) либо выпадающий список выбора. Если требуется функционал, полностью аналогичный типовым конфигурациям, следует переопределять форму выбора периода или использовать синхронизацию строкового реквизита с реквизитом типа Дата.