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