Как программно установить отбор в динамическом списке на управляемой форме?

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

При разработке на платформе 1С:Предприятие 8.3 с использованием управляемых форм часто возникает задача фильтрации данных в списках. Это может потребоваться, когда нам нужно открыть форму списка документов и показать только документы конкретного контрагента, или при открытии формы выбора номенклатуры ограничить список определенной группой или видом номенклатуры. В этой статье мы подробно разберем, как программно управлять отборами в объекте ДинамическийСписок.

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

Рассмотрим два основных подхода к решению этой задачи, которые обсуждались специалистами:

  1. Установка отбора через параметры открытия формы (подходит для форм выбора и форм списка при их открытии).
  2. Прямая манипуляция настройками компоновщика списка (подходит для изменения отбора "на лету" в уже открытой форме).

Способ 1: Передача отбора при открытии формы

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

Разберем, как это работает. Метод ОткрытьФорму принимает вторым параметром структуру параметров. Если в этой структуре есть ключ "Отбор", который сам является структурой, то платформа автоматически попытается применить эти значения как фильтры к основному динамическому списку открываемой формы.

Посмотрим на пример кода, где мы открываем форму выбора справочника "Номенклатура" и фильтруем её по виду номенклатуры:


// Создаем структуру для параметров отбора
ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("ВидНоменклатуры", НужныйВидНоменклатуры);
ПараметрыОтбора.Вставить("Услуга", Ложь); // Пример отбора по булевому полю

// Создаем структуру параметров формы
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Отбор", ПараметрыОтбора);
ПараметрыФормы.Вставить("РежимВыбора", Истина); // Указываем, что открываем для выбора

// Открываем форму
ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", ПараметрыФормы, Элемент);

Обратите внимание на важный нюанс: данный метод работает "жестко" на равенство. То есть вы не можете передать через простой параметр вид сравнения "В Списке" или "Больше". Для более сложных условий необходимо использовать второй способ.

Способ 2: Работа с КомпоновщикомНастроек (SettingsComposer)

Если вам нужно установить сложный отбор (например, "В Списке", "Содержит", "Больше или равно") или изменить отбор в уже открытой форме (например, при изменении галочки на форме), нам необходимо работать с объектом КомпоновщикНастроек динамического списка.

В управляемых формах настройки динамического списка разделяются на:

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

Предположим, у нас на форме есть список Список (тип ДинамическийСписок). Нам нужно отобрать документы по Складу.


// 1. Очищаем старые фиксированные отборы, если это необходимо
// Это важно, чтобы отборы не накапливались при многократном вызове кода
Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Очистить();

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

// 3. Указываем левое значение - поле, по которому фильтруем
// Используем Новый ПолеКомпоновкиДанных, передавая ИмяПоля как в запросе динамического списка
НовыйЭлемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Склад");

// 4. Указываем вид сравнения
НовыйЭлемент.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
// Можно использовать: .ВСписке, .Больше, .Содержит и т.д.

// 5. Указываем правое значение - то, с чем сравниваем
НовыйЭлемент.ПравоеЗначение = Объект.Склад;

// 6. Включаем использование отбора
НовыйЭлемент.Использование = Истина;

Важный момент: если вы используете произвольный запрос в динамическом списке, убедитесь, что поле, по которому вы делаете отбор (в примере выше — Склад), выбрано в этом запросе или доступно в полях компоновки данных.

Использование стандартных подсистем (БСП)

Если ваша конфигурация построена на базе БСП (Библиотека Стандартных Подсистем), например, 1С:ERP, УТ 11, КА 2 или Бухгалтерия 3.0, то в ней существуют готовые процедуры общего модуля для упрощения этой задачи. Это позволяет писать меньше кода и делает его более читаемым.

Рассмотрим пример использования модуля ОбщегоНазначенияКлиентСервер для установки отбора:


// Устанавливаем отбор по Организации
// Параметры: (Список, ИмяПоля, Значение, ВидСравнения, ПодробноеПредставление, ЗаменятьСуществующий)
ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(
    Список, 
    "Организация", 
    Объект.Организация, 
    ВидСравненияКомпоновкиДанных.Равно, 
    "Отбор по организации", 
    Истина
);

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

Работа с группой отборов (Группа И / ИЛИ)

Иногда возникают задачи, когда нужно установить условие "ИЛИ". Например, показать документы, где Склад равен "Склад 1" ИЛИ "Склад 2" (хотя для этого лучше использовать "В Списке", но для примера логики разберем группы).

Для этого в коллекцию элементов нужно добавлять не ЭлементОтбораКомпоновкиДанных, а ГруппаЭлементовОтбораКомпоновкиДанных. Разберем пример:


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

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

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

Подводные камни и частые ошибки

Проанализируем типичные ошибки, с которыми сталкиваются разработчики при работе с отборами:

  1. Неверное имя поля. Поле ЛевоеЗначение должно строго соответствовать имени поля в источнике данных динамического списка. Если в запросе списка поле называется Ссылка.Контрагент, а вы пишете просто Контрагент (и псевдонима нет), отбор не сработает или вызовет ошибку.
  2. Забытое свойство "Использование". При создании элемента отбора программно свойство Использование по умолчанию может быть Ложь. Всегда явно устанавливайте Использование = Истина.
  3. Конфликт с пользовательскими настройками. Если вы устанавливаете отбор в ФиксированныеНастройки, пользователь не сможет его снять через стандартный интерфейс. Если вам нужно просто "предустановить" фильтр, но дать возможность пользователю его отключить, следует работать с ПользовательскиеНастройки, но это требует более сложного алгоритма поиска нужного идентификатора настройки.

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

← На главную