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