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