При разработке на платформе «1С:Предприятие» часто возникает задача ограничить список значений, который видит пользователь при выборе элемента справочника (или другого объекта). Стандартный механизм для этого — использование события НачалоВыбора и установка свойства ПараметрыВыбора. Однако нередко разработчики сталкиваются с ситуацией, когда код написан верно, ошибок нет, но форма выбора открывается с полным списком элементов, игнорируя установленные отборы.
В этой статье мы подробно разберем, почему так происходит, проанализируем пример из практики и рассмотрим надежные способы решения этой задачи.
Рассмотрим типичную ситуацию. У нас есть реквизит на форме, и мы хотим, чтобы при нажатии на кнопку выбора открывался список, отфильтрованный по определенному массиву ссылок. Разработчик пишет следующий код в обработчике события НачалоВыбора:
&НаКлиенте
Процедура РеквизитНачалоВыбора(Элемент, ДанныеВыбора, ВыборДобавлением, СтандартнаяОбработка)
// Подготовка массива значений для отбора
НовыйМассив = Новый Массив;
НовыйМассив.Добавить(Новый ПараметрВыбора("Отбор.Ссылка", ПолучитьЗначенияДляВыбора()));
НовыйМассив.Добавить(Новый ПараметрВыбора("Отображение", "Список")); // Необязательно, но допустимо
// Установка параметров выбора элементу
НовыеПараметры = Новый ФиксированныйМассив(НовыйМассив);
Элемент.ПараметрыВыбора = НовыеПараметры;
КонецПроцедуры
Казалось бы, логика верна: мы создаем массив параметров выбора, передаем туда условие отбора по ссылке и присваиваем это элементу формы. Однако на практике форма выбора открывается без отбора.
В ходе обсуждения проблемы выяснилось несколько важных моментов:
Если параметры выбора игнорируются, в 90% случаев причина кроется в модуле формы выбора конкретного справочника или документа. Это так называемая «мутная» форма, как выразились участники обсуждения.
Давайте разберем, что может происходить внутри открываемой формы выбора в событии ПриСозданииНаСервере:
// Плохая практика, блокирующая внешние параметры
Список.Отбор.Элементы.Очистить();
ДинамическийСписок с произвольным запросом, и у него снята галочка «Автозаполнение стандартных полей», платформа может просто не понять, к какому полю применять переданный параметр Отбор.Ссылка.В рассмотренном случае проблема решилась именно анализом формы выбора объекта. Она была сильно модифицирована, и стандартные механизмы платформы по наложению отборов там не срабатывали.
Хотя установка Элемент.ПараметрыВыбора допустима, более надежным и гибким способом является программное открытие формы с отключением стандартной обработки. Это дает полный контроль над процессом.
Давайте перепишем код, используя этот подход. Мы будем использовать структуру параметров и функцию ОткрытьФорму.
&НаКлиенте
Процедура РеквизитНачалоВыбора(Элемент, ДанныеВыбора, ВыборДобавлением, СтандартнаяОбработка)
// 1. Отключаем стандартную обработку, чтобы форма не открылась сама "как обычно"
СтандартнаяОбработка = Ложь;
// 2. Готовим параметры отбора
ЗначенияДляОтбора = ПолучитьЗначенияДляВыбора(); // Возвращает Массив ссылок
ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("Ссылка", ЗначенияДляОтбора);
// 3. Формируем общие параметры открытия формы
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Отбор", ПараметрыОтбора);
// Можно добавить режим выбора, если открываем не специфическую форму выбора
ПараметрыФормы.Вставить("РежимВыбора", Истина);
// 4. Открываем форму
// Важно передать "Элемент" четвертым параметром (Владелец),
// чтобы при выборе значение вернулось в это поле ввода.
ОткрытьФорму("Справочник.ВашСправочник.ФормаВыбора", ПараметрыФормы, Элемент);
КонецПроцедуры
Почему этот способ лучше:
Отбор, которая применяется к расширению формы динамического списка.ПараметрыВыбора элемента интерфейса.Если ваш отбор зависит от другого поля на этой же форме (например, выбираем Договор, и нужно показать только договоры конкретного Контрагента), не стоит писать код в модуле. Используйте механизм Связи параметров выбора в свойствах реквизита.
Отбор.Владелец (поле справочника) = Объект.Контрагент (поле вашей формы).Это самый «чистый» способ, который работает на уровне платформы и не требует поддержки кода.
В теме затрагивался вопрос: можно ли передавать массив в отбор? Да, можно.
Если вы передаете в структуру отбора или в ПараметрВыбора значение типа Массив, платформа 1С автоматически применяет вид сравнения ВСписке (In List). Вам не нужно явно указывать вид сравнения, система догадается сама.
Однако, будьте внимательны: если массив пустой, поведение может зависеть от версии платформы и настроек. Обычно пустой массив в отборе приводит к пустому списку (ничего не найдено), что логично.
Если у вас не работает отбор при открытии, пройдите по шагам:
Элемент.ПараметрыВыбора на СтандартнаяОбработка = Ложь и ОткрытьФорму с параметрами.ПриСозданииНаСервере) и настройки динамического списка. Убедитесь, что там нет принудительной очистки отборов или установки фиксированных настроек.