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