При разработке на платформе 1С:Предприятие 8.3 часто возникает задача ограничить список элементов в форме выбора не по одному простому полю, а по совокупности условий. Например, когда нужно отфильтровать договоры конкретного контрагента, в названии которых встречается определенная подстрока. В рамках данной статьи мы разберем, как реализовать такой функционал, проанализируем различные способы установки отборов и выясним, какой из них наиболее эффективен в конкретных ситуациях.
Этот метод является наиболее мощным, так как позволяет использовать не только простое равенство, но и такие виды сравнения, как «Содержит», «В списке» или «Больше». Разберем ситуацию, когда нам нужно открыть форму выбора договоров, отфильтрованных по владельцу (контрагенту) и по подстроке в наименовании.
Рассмотрим по шагам реализацию в обработчике события НачалоВыбора для поля ввода:
&НаКлиенте
Процедура ДоговорНачалоВыбора(Элемент, ДанныеВыбора, ВыборДобавлением, СтандартнаяОбработка)
// 1. Отключаем стандартное открытие формы, так как будем открывать её программно
СтандартнаяОбработка = Ложь;
// 2. Создаем объект настроек компоновки данных для формирования отбора
НастройкиКомпоновки = Новый НастройкиКомпоновкиДанных;
// 3. Создаем группу для объединения условий (необязательно, если условие одно)
ГруппаОтбора = НастройкиКомпоновки.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
// 4. Добавляем отбор по Владельцу (Контрагенту) на равенство
ЭлементОтбораВладелец = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбораВладелец.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Владелец");
ЭлементОтбораВладелец.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбораВладелец.Использование = Истина;
ЭлементОтбораВладелец.ПравоеЗначение = Объект.Контрагент;
// 5. Добавляем отбор по Наименованию с условием "Содержит"
ЭлементОтбораНаименование = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбораНаименование.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Наименование");
ЭлементОтбораНаименование.ВидСравнения = ВидСравненияКомпоновкиДанных.Содержит;
ЭлементОтбораНаименование.Использование = Истина;
ЭлементОтбораНаименование.ПравоеЗначение = "ССГ"; // Искомая подстрока
// 6. Подготавливаем параметры для открытия формы
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ФиксированныеНастройки", НастройкиКомпоновки);
ПараметрыФормы.Вставить("РежимВыбора", Истина);
// 7. Открываем форму, указывая элемент формы (поле ввода) в качестве владельца.
// Это позволит платформе автоматически подставить выбранное значение в поле без доп. кода.
ОткрытьФорму("Справочник.Договоры.ФормаВыбора", ПараметрыФормы, Элементы.Договор);
КонецПроцедуры
Важным моментом здесь является использование ключа ФиксированныеНастройки. Если передать настройки под этим ключом, пользователь в открывшейся форме не сможет их изменить или удалить через меню «Настроить список». Если же вы хотите, чтобы отбор был предустановлен, но доступен для редактирования, следует использовать механизмы пользовательских настроек.
Если ваша задача ограничивается только проверкой на равенство (например, только по контрагенту), можно избежать создания громоздких объектов компоновки данных. Проанализируем более простой вариант кода:
&НаКлиенте
Процедура ДоговорНачалоВыбораПростой(Элемент, ДанныеВыбора, ВыборДобавлением, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
СтруктураОтбора = Новый Структура;
СтруктураОтбора.Вставить("Владелец", Объект.Контрагент);
СтруктураОтбора.Вставить("ПометкаУдаления", Ложь);
ПараметрыФормы = Новый Структура("Отбор, РежимВыбора", СтруктураОтбора, Истина);
ОткрытьФорму("Справочник.Договоры.ФормаВыбора", ПараметрыФормы, Элемент);
КонецПроцедуры
Обратите внимание: данный метод не поддерживает условие «Содержит». Если вы передадите строку в структуру отбора, платформа будет искать только полное совпадение наименования.
Выясним, можно ли решить задачу вообще без написания программного кода. Платформа 1С предоставляет механизм «Связи параметров выбора». Это наиболее предпочтительный метод для стандартных задач фильтрации «поле от поля».
Договор в документе).Отбор.ВладелецОбъект.КонтрагентПосле этой настройки при нажатии на кнопку выбора в поле договора платформа автоматически применит фильтр по текущему контрагенту. Однако для фильтрации по подстроке «ССГ» этот метод все равно потребует дополнения в виде программного кода или настройки Параметров выбора в метаданных (если значение «ССГ» статично).
Рассмотрим несколько критически важных моментов, которые часто упускают начинающие разработчики:
1. Имена полей (ЛевоеЗначение). Поля, которые вы используете в ПолеКомпоновкиДанных, должны соответствовать именам реквизитов в динамическом списке открываемой формы. Например, если в справочнике поле называется Наименование, а вы напишете Наименованее (с ошибкой), отбор не сработает или вызовет ошибку выполнения.
2. Быстрый ввод (подбор по строке). Код в событии НачалоВыбора срабатывает только при нажатии на кнопку «Выбрать» (три точки). Если пользователь начнет вводить текст прямо в поле, фильтры не применятся. Чтобы ограничить выбор и при быстром вводе, необходимо переопределить обработчик ОбработкаПолученияДанныхВыбора в модуле менеджера соответствующего справочника.
3. Владелец формы. Если при вызове ОткрытьФорму в качестве третьего параметра (Владелец) передать ЭтаФорма, то после выбора элемента сработает событие ОбработкаВыбора. Если же передать конкретный элемент формы (например, Элементы.Договор), платформа сама заполнит этот реквизит, что сокращает объем кода.
4. Типы данных. Всегда проверяйте типы значений, передаваемых в ПравоеЗначение. Если поле Наименование строковое, то и искать в нем нужно строку. Сравнение строки с числом (как в некоторых ошибочных примерах) приведет к тому, что список окажется пустым.
Подводя итог, для реализации сложных условий поиска (таких как вхождение подстроки) оптимальным выбором будет использование НастройкиКомпоновкиДанных в сочетании с ОткрытьФорму, в то время как для простых зависимостей лучше использовать стандартные средства конфигуратора.