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