Почему не работает отбор в динамическом списке 1С и как его правильно настроить?

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

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

Рассмотрим по шагам основные причины возникновения такой проблемы и разберем практические способы реализации фильтрации в динамических списках.

Анализ частых ошибок при программной установке отбора

Проанализируем типичный сценарий, при котором отбор работает не так, как ожидается:

  1. Накопление дублирующих элементов отбора. Вызов метода Список.Отбор.Элементы.Добавить(...) при каждом изменении реквизита формы добавляет новый элемент в коллекцию Отбор.Элементы. Если пользователь несколько раз меняет организацию, в списке формируется несколько условий, соединяемых по логическому «И» (например, Владелец = Организация1 И Владелец = Организация2). В результате динамический список возвращает пустой результат.
  2. Избыточные запросы к базе данных. Выполнение отдельного объекта Запрос для получения массива или списка значений с последующей передачей их в отбор вида ВСписке снижает производительность и усложняет код. Платформа 1С позволяет накладывать отборы и устанавливать параметры напрямую в динамическом списке.

Способ 1. Фильтрация через произвольный запрос и параметр (Рекомендуемый)

Самым простым и производительным решением является использование произвольного запроса в свойствах динамического списка.

Разберем порядок действий:

1. В конфигураторе открываем свойства динамического списка Список, устанавливаем флаг Произвольный запрос и в поле Текст запроса прописываем условие с параметром:


ВЫБРАТЬ
	ПодразделенияОрганизаций.Ссылка КАК Ссылка,
	ПодразделенияОрганизаций.Владелец КАК Владелец,
	ПодразделенияОрганизаций.Родитель КАК Родитель,
	ПодразделенияОрганизаций.Код КАК Код,
	ПодразделенияОрганизаций.Наименование КАК Наименование
ИЗ
	Справочник.ПодразделенияОрганизаций КАК ПодразделенияОрганизаций
ГДЕ
	ПодразделенияОрганизаций.Владелец = &Владелец

Если требуется, чтобы при пустом значении организации список показывал все элементы без ограничений, используем синтаксис расширения языка запросов СКД (заключаем условие в фигурные скобки):


ВЫБРАТЬ
	ПодразделенияОрганизаций.Ссылка КАК Ссылка,
	ПодразделенияОрганизаций.Владелец КАК Владелец,
	ПодразделенияОрганизаций.Код КАК Код,
	ПодразделенияОрганизаций.Наименование КАК Наименование
ИЗ
	Справочник.ПодразделенияОрганизаций КАК ПодразделенияОрганизаций
{ГДЕ
	ПодразделенияОрганизаций.Владелец = &Владелец}

2. В модуле формы в событии ПриИзменении для поля Организация вызываем серверную процедуру и устанавливаем значение параметра:


&НаКлиенте
Процедура ОрганизацияПриИзменении(Элемент)
	ОрганизацияПриИзмененииНаСервере();
КонецПроцедуры

&НаСервере
Процедура ОрганизацияПриИзмененииНаСервере()
	Список.Параметры.УстановитьЗначениеПараметра("Владелец", Организация);
КонецПроцедуры

Способ 2. Корректное программное добавление отбора

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

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


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

Способ 3. Декларативная настройка связи параметров выбора

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

  1. Открываем свойства элемента формы, в котором выбирается значение.
  2. Находим свойство Связи параметров выбора.
  3. Добавляем связь: указываем реквизит Организация и путь к данным отбора Отбор.Владелец.

Платформа автоматически применит фильтр по владельцу при открытии формы выбора или выпадающего списка.

Важные нюансы и чек-лист проверки

Выясним дополнительные причины, по которым отбор может не срабатывать:

← На главную