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