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

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

При разработке документов и отчетов в среде 1С:Предприятие 8.3 часто возникает задача предоставить пользователю удобный интерфейс для выбора интервала дат. В управляемых формах это реализуется иначе, чем в обычных, и требует понимания механизмов работы с типом данных СтандартныйПериод и событийными моделями платформы.

Рассмотрим ситуацию: в документе (или ином объекте) существуют два реквизита — НачалоПериода и ОкончаниеПериода (тип Дата). Нам необходимо разместить на форме кнопку или поле, при нажатии на которое откроется стандартный календарь выбора периода, а результат запишется в наши реквизиты. Разберем три основных способа реализации этой задачи: от простого реквизита формы до сложного программного вызова диалога.

Способ 1. Использование реквизита формы типа СтандартныйПериод

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

  1. Перейдем на вкладку Реквизиты в редакторе управляемой формы.
  2. Добавим новый реквизит формы (не объекта!), назовем его, например, ПериодДляВыбора.
  3. Установим ему тип СтандартныйПериод.
  4. Перетащим этот реквизит на визуальную схему формы. Платформа автоматически создаст поле ввода с кнопкой выбора (лупой или календарем).

Теперь выясним, как связать этот реквизит с данными документа. Поскольку СтандартныйПериод — это составной объект, содержащий ДатаНачала и ДатаОкончания, нам нужно синхронизировать их программно. Рассмотрим код в модуле формы:


&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
    // Заполняем реквизит формы данными из документа при открытии
    ПериодДляВыбора.ДатаНачала   = ТекущийОбъект.НачалоПериода;
    ПериодДляВыбора.ДатаОкончания = ТекущийОбъект.ОкончаниеПериода;
КонецПроцедуры

&НаКлиенте
Процедура ПериодДляВыбораПриИзменении(Элемент)
    // Передаем данные из формы обратно в объект при изменении пользователем
    Объект.НачалоПериода    = ПериодДляВыбора.ДатаНачала;
    Объект.ОкончаниеПериода = ПериодДляВыбора.ДатаОкончания;
КонецПроцедуры

Важный момент: если мы хотим, чтобы выбранный вариант периода (например, «Прошлый месяц» или «Этот квартал») сохранялся, можно завести в документе дополнительный реквизит, так как обычные даты хранят только границы интервала.

Способ 2. Программный вызов диалога редактирования периода (современный метод)

Иногда создание лишнего реквизита на форме избыточно, и мы хотим просто вызывать окно выбора по нажатию на кнопку или при активации поля даты. Для этого в платформе существует объект ДиалогРедактированияСтандартногоПериода. Проанализируем, как реализовать это без использования устаревших модальных окон, что критично для работы в веб-клиенте и современных конфигурациях.

Разберем алгоритм по шагам. Создадим команду на форме, назовем ее ВыбратьПериод, и пропишем следующий код:


&НаКлиенте
Процедура ВыбратьПериод(Команда)
    // Инициализируем диалог
    Диалог = Новый ДиалогРедактированияСтандартногоПериода;
    
    // Заполняем текущими значениями из документа
    Диалог.Период.ДатаНачала   = Объект.НачалоПериода;
    Диалог.Период.ДатаОкончания = Объект.ОкончаниеПериода;
    
    // Подготавливаем описание оповещения (Callback-функцию)
    Оповещение = Новый ОписаниеОповещения("ПослеВыбораПериода", ЭтотОбъект);
    
    // Показываем диалог асинхронно
    Диалог.Показать(Оповещение);
КонецПроцедуры

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

Этот метод считается наиболее лаконичным и правильным с точки зрения архитектуры управляемого приложения. Мы не перегружаем форму лишними реквизитами, а используем временный объект диалога, который существует только в момент выбора.

Способ 3. Сложная реализация «как в типовых» (БП 3.0, ERP)

В крупных типовых конфигурациях (например, Бухгалтерия предприятия 3.0) часто используется более сложная схема. Там выбор периода реализован через перечисление ДоступныеПериодыОтчета и набор общих модулей. Это позволяет пользователю выбирать не только даты, но и «Вид периода» (День, Неделя, Декада и т.д.) из выпадающего списка.

Рассмотрим структуру такой реализации. Она включает в себя:

Посмотрим на пример логики подбора периода, которую можно заимствовать из типовых модулей:


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

Такой подход оправдан в сложных аналитических отчетах, где пользователю важна скорость ввода. Однако для обычного документа (например, Счета на оплату) достаточно первого или второго способа.

Особенности работы в мобильном клиенте и веб-интерфейсе

Проанализируем ситуацию работы с периодами на мобильных устройствах. Важно помнить, что объект СтандартныйПериод в мобильном приложении может отображаться иначе или иметь ограниченный функционал. Часто разработчики предпочитают заменять его двумя отдельными полями ввода дат (Начало и Конец), так как это более удобно для сенсорного ввода пальцами.

В веб-клиенте критически важно использовать именно метод Показать() с оповещением, так как модальные окна в современных браузерах блокируются или работают некорректно. Использование синхронного метода Редактировать() приведет к ошибке выполнения в среде, где запрещены модальные вызовы.

Дополнительные советы по юзабилити

Выясним, как сделать интерфейс еще удобнее для пользователя:

  1. Быстрые настройки: Если вы используете реквизит формы СтандартныйПериод, в свойствах элемента формы можно включить отображение быстрых настроек. Пользователь увидит список предустановленных интервалов прямо под полем ввода.
  2. Форматирование: При программной установке дат всегда используйте НачалоДня для даты начала и КонецДня для даты окончания. Это исключит ошибки в запросах, которые могут не подхватить данные из-за разницы в секундах (например, если документ создан в середине дня 31-го числа).
  3. Стандартные команды: Если период нужен только для фильтрации списка, рассмотрите возможность выноса стандартной команды УстановитьПериод в командную панель динамического списка — есть готовый интерфейс фильтрации списков через панель кнопок. Это вообще не требует написания кода.

Таким образом, выбор метода зависит от сложности задачи. Вы можете применить программное изменение форм для быстрой реализации (Способ 2) или создать полноценный реквизит формы (Способ 1) для отчетов с глубокой аналитикой.

← На главную