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