Как программно перенести отбор из СКД в динамический список на форме?

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

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

Анализ проблемы

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

Простое копирование ссылки на элемент отбора из настроек СКД в отбор списка не приведет к желаемому результату. Необходимо создать новый экземпляр элемента отбора в коллекции отборов динамического списка и перенести в него значения свойств из исходного элемента отбора СКД.

Основное решение: перебор и копирование элементов отбора

Наиболее правильный и универсальный способ — это организовать цикл, который будет перебирать все элементы отбора в настройках по умолчанию схемы компоновки данных. Для каждого найденного элемента мы будем создавать новый элемент в отборе нашего динамического списка и копировать в него все необходимые свойства.

Давайте разберем этот процесс по шагам на примере кода.

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

Посмотрим на готовый код, который реализует этот алгоритм. Предположим, что у нас на форме есть реквизит Список типа ДинамическийСписок, а схема компоновки данных получается из макета.


// Предполагается, что переменная "Схема" уже содержит объект
// типа СхемаКомпоновкиДанных.
// Например, ее можно получить из макета:
// Схема = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");

// Очистим текущие отборы списка, если нужно начать с чистого листа
// Список.Отбор.Элементы.Очистить();

// Перебираем элементы отбора из настроек по умолчанию в СКД
Для каждого ЭлементОтбораСКД Из Схема.НастройкиПоУмолчанию.Отбор.Элементы Цикл

    // Проверяем, что элемент отбора - это не группа
    Если ТипЗнч(ЭлементОтбораСКД) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда

        // Создаем новый элемент отбора в коллекции отборов динамического списка
        ЭлементОтбораСписка = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
        
        // Копируем свойства из элемента СКД в новый элемент списка
        ЭлементОтбораСписка.ЛевоеЗначение  = ЭлементОтбораСКД.ЛевоеЗначение;
        ЭлементОтбораСписка.ВидСравнения   = ЭлементОтбораСКД.ВидСравнения;
        ЭлементОтбораСписка.ПравоеЗначение = ЭлементОтбораСКД.ПравоеЗначение;
        ЭлементОтбораСписка.Использование  = ЭлементОтбораСКД.Использование;
        
    КонецЕсли;

КонецЦикла;

Этот код корректно добавит все отборы из настроек СКД к уже существующим отборам в динамическом списке. Если вам нужно полностью заменить отборы, перед циклом вызовите метод Список.Отбор.Элементы.Очистить().

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

Создание отбора с нуля

Иногда требуется не копировать отбор, а создать его полностью программно. Принцип тот же: создаем элемент и заполняем его свойства. Важный момент касается свойства ЛевоеЗначение. Его нужно создавать как объект типа ПолеКомпоновкиДанных, указывая в конструкторе имя поля из запроса динамического списка.

Пример: установим отбор по полю "Автор" для документов.


// Получаем отбор динамического списка
ОтборСписка = Список.Отбор;

// Создаем новый элемент отбора
НовыйОтбор = ОтборСписка.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));

// Устанавливаем флаг использования
НовыйОтбор.Использование = Истина;

// Задаем левое значение (поле для фильтрации)
НовыйОтбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Автор");

// Устанавливаем вид сравнения
НовыйОтбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;

// Устанавливаем правое значение (значение для фильтрации)
НовыйОтбор.ПравоеЗначение = ПараметрыСеанса.ТекущийПользователь;

Работа с группами отборов

Система компоновки данных позволяет создавать сложные группы условий (например, "ИЛИ", "НЕ"). Для этого в коллекцию элементов отбора добавляется не ЭлементОтбораКомпоновкиДанных, а ГруппаЭлементовОтбораКомпоновкиДанных. Затем уже в эту группу добавляются конечные элементы отбора.

Пример: отберем документы, где Автор - текущий пользователь ИЛИ Ответственный - текущий пользователь.


// Создаем группу с условием "ИЛИ"
ГруппаИЛИ = Список.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
ГруппаИЛИ.ТипГруппы = ТипГруппыЭлементовКомпоновкиДанных.ГруппаИли;
ГруппаИЛИ.Использование = Истина;

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

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

Ключевые выводы

  1. Для программного добавления фильтра в динамический список необходимо работать с коллекцией ИмяСписка.Отбор.Элементы.
  2. Чтобы добавить новый отбор, используйте метод Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных")).
  3. После создания элемента обязательно заполните его свойства: ЛевоеЗначение (как Новое ПолеКомпоновкиДанных("ИмяПоля")), ВидСравнения, ПравоеЗначение и Использование.
  4. Простое копирование или присваивание элементов из других коллекций не работает. Нужно создавать новые элементы и переносить в них значения свойств.

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

← На главную