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