Как реализовать выбор периода по месяцам кнопками регулирования на управляемой форме?

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

При разработке интерфейсов на управляемых формах часто возникает задача организовать компактный выбор расчетного или отчетного месяца. Требуется, чтобы в поле отображалось название месяца и год (например, «Ноябрь 2016»), а при нажатии на стандартные кнопки регулирования вверх и вниз период последовательно переключался с шагом ровно в один месяц, сохраняя при этом в данных корректную дату начала месяца.

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

Почему не работает стандартное поле ввода с типом Дата

Проанализируем типичные ошибки, возникающие при попытке настроить стандартное поле даты:

  1. Невозможность парсинга строкового наименования месяца в режиме редактирования. Форматная строка ДФ='ММММ гггг' содержит спецификатор ММММ, который выводит полное название месяца словом. Платформа 1С требует, чтобы в режиме ввода с клавиатуры (в свойстве ФорматРедактирования) использовались числовые шаблоны, которые парсер платформы может однозначно интерпретировать. Текстовое наименование месяца разобрать таким образом невозможно, из-за чего введенное значение обнуляется.
  2. Синтаксис формата. Указание шаблона без префикса даты (например, ММММ гггг вместо ДФ='ММММ гггг') приводит к тому, что платформа пытается разобрать строку как числовой формат или произвольный шаблон, что вызывает искажение данных и появление странных дат вида «января 0002».
  3. Поведение фокуса ввода. Элемент формы, связанный с датой, при активации переходит в режим редактирования. Даже если в обычном представлении дата отформатирована, при клике поле сбрасывает отображение к обычному вводу чисел. Кроме того, стандартный диалог выбора даты в платформе всегда ориентирован на выбор конкретного дня, а не месяца.
  4. Стандартное действие при регулировании. Если в обработчике события Регулирование не отменить платформенное действие, платформа выполняет собственный инкремент даты на один день (или по позиции курсора), затирая программный расчет с шагом в один месяц.

Основное решение: Связка реквизита даты и строкового представления на форме

Наиболее надежный и рекомендуемый способ, используемый в типовых конфигурациях (например, в 1С:ЗУП), заключается в разделении хранения данных и их визуального представления.

Рассмотрим по шагам, как настроить такую схему:

  1. В объекте или форме создаем реквизит Период с типом Дата (состав дат: Дата). Сам этот реквизит на форму не выводим — он служит для хранения реального значения (начала месяца).
  2. На форме добавляем вспомогательный строковый реквизит, например, ПериодСтрока с типом Строка (длина 20–25 символов).
  3. Перетаскиваем ПериодСтрока в элементы формы и настраиваем его свойства:
    1. Устанавливаем свойство КнопкиРегулирования в значение Включить (Истина).
    2. Снимаем флаг РедактированиеТекста (значение Ложь), чтобы пользователь не мог вручную ввести произвольный текст, ломая формат.
  4. Создаем обработчик события Регулирование для поля ввода ПериодСтрока и обработчик ПриСозданииНаСервере (или ПриОткрытии) для начальной инициализации.

Посмотрим на программную реализацию. Инициализацию периода при открытии формы выполняем следующим образом:


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

Теперь разберем обработку нажатия кнопок вверх и вниз. Событие Регулирование передает на клиент параметр Направление, который принимает значение 1 при нажатии кнопки «вверх» и -1 при нажатии кнопки «вниз». Это позволяет выполнить расчет прямо на клиенте без лишних контекстных вызовов сервера:


&НаКлиенте
Процедура ПериодСтрокаРегулирование(Элемент, Направление, СтандартнаяОбработка)
    
    // Обязательно отключаем встроенную реакцию платформы
    СтандартнаяОбработка = Ложь;
    
    // Сдвигаем дату на 1 месяц вперед или назад в зависимости от направления
    Объект.Период = ДобавитьМесяц(Объект.Период, Направление);
    
    // Обновляем строковое представление на форме
    ПериодСтрока = Формат(Объект.Период, "ДФ='ММММ гггг'");
    
КонецПроцедуры

Обратите внимание: присвоение СтандартнаяОбработка = Ложь; является ключевым. Если этого не сделать, платформа попытается применить стандартное изменение значения строкового поля.

Альтернативные варианты реализации

В зависимости от архитектуры вашего решения можно рассмотреть еще два подхода:

  1. Использование типа СтандартныйПериод. Если жесткой привязки именно к кнопкам со стрелками нет, на форму выводится реквизит типа СтандартныйПериод. Платформа 1С предоставляет для него готовый диалог с быстрым выбором любого месяца, а в коде достаточно обращаться к свойству Период.ДатаНачала.
  2. Использование механизмов БСП (модуль ЗарплатаКадрыКлиент). В конфигурациях, где внедрена зарплатная функциональность или соответствующие подсистемы Библиотеки Стандартных Подсистем, доступны готовые методы группы ВводМесяца.... Они предоставляют выбор месяца через компактное выпадающее окно с сеткой месяцев и стрелками переключения года, полностью беря на себя форматирование и обработку кнопок.

Таким образом, разделение хранения даты и строкового представления — это наиболее гибкий и стабильный метод для организации помесячного переключения в управляемом интерфейсе 1С.

← На главную