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