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