Как правильно установить отбор по списку значений при открытии формы выбора в 1С?

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

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

В чем заключалась ошибка в исходном коде

Проанализируем фрагмент кода, с которого началось обсуждение проблемы:


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

Здесь допущены две критические ошибки, из-за которых отбор не применяется:

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

Способ 1. Простая передача списка через системный параметр «Отбор»

Самый простой и быстрый способ наложить условие «В списке» — использовать стандартное поведение платформы. Если в структуру Отбор передать массив или список значений, платформа автоматически применит к полю вид сравнения ВСписке без лишнего кода:


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

Обратите внимание на третий параметр метода ОткрытьФорму: если передать туда Элемент (параметр события выбора), то после выбора строки в открывшейся форме значение вернется прямо в редактируемую ячейку. Если же передать ЭтаФорма, значение по умолчанию не заполнит поле, и разработчику потребуется описывать обработчик события ОбработкаВыбора.

Способ 2. Использование настроек компоновки данных (ФиксированныеНастройки)

Второй рабочий вариант, к которому пришел автор темы, заключается в формировании объекта НастройкиКомпоновкиДанных и передаче его в параметр формы ФиксированныеНастройки. Разберем этот код подробно:


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

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

У данного подхода есть важные особенности, о которых необходимо помнить:

  1. Недоступность для пользователя: Отборы, установленные через ФиксированныеНастройки, накладываются на уровне платформы поверх всех пользовательских настроек. Пользователь не сможет увидеть их в окне настройки списка или случайно отключить флажком.
  2. Перезапись существующих настроек: Если форма выбора уже содержала свои жестко заданные в конфигураторе фиксированные настройки, передача нового объекта целиком перетрет их.

Способ 3. Альтернатива без переопределения стандартной обработки

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

  1. Связи параметров выбора: В свойствах реквизита или элемента формы можно настроить связь, например Отбор.Владелец(РасшифровкаПлатежа.Контрагент). В таком случае платформа автоматически фильтрует данные как в форме выбора, так и при быстром вводе по строке.
  2. Динамическая установка ПараметрыВыбора: В событии ПриАктивизацииСтроки таблицы можно программно заполнять свойство элемента ПараметрыВыбора, передавая туда массив объектов ПараметрВыбора. Это сохраняет стандартное поведение формы и избавляет от необходимости вручную вызывать ОткрытьФорму.
← На главную