Как передать результат запроса в отбор формы выбора в 1С

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

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

Способ 1. Использование стандартного параметра формы «Отбор»

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

Рассмотрим, как правильно получить массив ссылок из результата запроса и передать его в форму выбора. Для этого выгрузим нужную колонку таблицы значений в массив с помощью метода ВыгрузитьКолонку():


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

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

Проанализируем преимущества данного способа:

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

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

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

Посмотрим на реализацию передачи произвольного параметра при вызове формы:


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

Теперь разберем код обработчика в модуле самой формы выбора:


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

Способ 3. Переопределение выбора через событие «НачалоВыбора»

Если выбор физлица осуществляется непосредственно в поле формы, целесообразно переопределить стандартную обработку события НачалоВыбора, чтобы исключить открытие стандартного списка без фильтра:


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

Ограничения производительности и рекомендации

При передаче списков значений в отборы динамических списков важно учитывать следующие технические нюансы:

  1. Размер массива: не рекомендуется передавать в отбор массивы, содержащие тысячи элементов. Это приводит к передаче больших объемов данных между сервером и клиентом и формированию тяжелых SQL-запросов с длинными конструкциями IN (...), что может замедлить работу СУБД.
  2. Параметризация запроса динамического списка: если логику выборки можно описать условиями на уровне базы данных (например, отбор по реквизитам организации, подразделению, признакам), лучше передавать в форму выбора не готовый массив ссылок, а параметры для фильтрации, настраивая сам запрос динамического списка.
  3. Оптимизация обхода выборки: при заполнении массива на сервере можно использовать выборку из результата запроса (Запрос.Выполнить().Выбрать()) с последовательным заполнением массива, чтобы не создавать промежуточный объект ТаблицаЗначений в памяти.
← На главную