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