Как ограничить выбор номенклатуры определенной группой при вводе по строке в 1С?

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

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

Решение для типовых конфигураций на обычных формах

В типовых решениях на базе обычных форм (например, «Управление торговым предприятием», «Управление производственным предприятием» или «Управление торговлей 10.3») механизмы интерактивного поиска вынесены в специализированные общие модули. Чтобы перехватить ввод текста, используем событие поля ввода в табличной части.

Проанализируем порядок действий:

  1. Открываем форму документа в конфигураторе и переходим к свойствам поля ввода номенклатуры в табличной части.
  2. Находим событие ОкончаниеВводаТекста и создаем для него процедуру-обработчик.
  3. В обработчике вызываем типовой метод ПроцедурыПоискаПоСтроке.ОкончаниеВводаТекстаВЭлементеУправления, передавая в структуру параметров нужного родителя.

Посмотрим на пример программного кода:


Процедура ТоварыНоменклатураОкончаниеВводаТекста(Элемент, Текст, Значение, СтандартнаяОбработка)

    СтандартнаяОбработка = Ложь;

    СтруктураПараметров = Новый Структура;
    СтруктураПараметров.Вставить("Родитель", Справочники.Номенклатура.НайтиПоНаименованию("Услуги"));

    ПроцедурыПоискаПоСтроке.ОкончаниеВводаТекстаВЭлементеУправления(
        Элемент,
        Текст,
        Значение,
        СтандартнаяОбработка,
        СтруктураПараметров
    );

КонецПроцедуры

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

Реализация поиска без типовых модулей через собственный запрос

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

Рассмотрим пример реализации:


Процедура ТоварыНоменклатураОкончаниеВводаТекста(Элемент, Текст, Значение, ДанныеВыбора, СтандартнаяОбработка)

    Если ПустаяСтрока(Текст) Тогда
        Возврат;
    КонецЕсли;

    СтандартнаяОбработка = Ложь;
    ДанныеВыбора = Новый СписокЗначений;

    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 20
        |	Номенклатура.Ссылка КАК Ссылка,
        |	Номенклатура.Наименование КАК Наименование
        |ИЗ
        |	Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |	НЕ Номенклатура.ЭтоГруппа
        |	И Номенклатура.Ссылка В ИЕРАРХИИ(&Родитель)
        |	И (Номенклатура.Наименование ПОДОБНО &ШаблонПоиска
        |		ИЛИ Номенклатура.Артикул ПОДОБНО &ШаблонПоиска)
        |
        |УПОРЯДОЧИТЬ ПО
        |	Номенклатура.Наименование";

    Запрос.УстановитьПараметр("Родитель", НужнаяГруппаНоменклатуры);
    Запрос.УстановитьПараметр("ШаблонПоиска", "%" + Текст + "%");

    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        ДанныеВыбора.Добавить(Выборка.Ссылка, Выборка.Наименование);
    КонецЦикла;

КонецПроцедуры

Обратите внимание: при самостоятельной обработке события штатный механизм платформы отключается. Если в конфигурации настроен ввод по строке не только по наименованию, но также по артикулу или коду, обязательно включайте эти реквизиты в условие запроса через оператор ИЛИ. Кроме того, всегда ограничивайте выборку конструкцией ВЫБРАТЬ ПЕРВЫЕ, чтобы не перегружать СУБД тяжелыми запросами с оператором В ИЕРАРХИИ при наборе текста пользователем.

Обеспечение комплексной защиты от неверного выбора

Фильтрация исключительно в событии ОкончаниеВводаТекста не гарантирует стопроцентную защиту. Пользователь может нажать клавишу F4 (троеточие) и открыть стандартную форму выбора, вставить ссылку через буфер обмена или перетащить ее мышью. Чтобы полностью исключить ошибки, разберем сопутствующие меры контроля.

  1. Ограничение формы выбора: перехватываем событие поля ввода НачалоВыбора, отключаем стандартное открытие формы и передаем иерархический отбор:
    
    Процедура ТоварыНоменклатураНачалоВыбора(Элемент, СтандартнаяОбработка)
        СтандартнаяОбработка = Ложь;
        ФормаВыбора = Справочники.Номенклатура.ПолучитьФормуВыбора(, Элемент);
        ФормаВыбора.Отбор.Ссылка.ВидСравнения = ВидСравнения.ВИерархии;
        ФормаВыбора.Отбор.Ссылка.Значение = НужнаяГруппаНоменклатуры;
        ФормаВыбора.Отбор.Ссылка.Использование = Истина;
        ФормаВыбора.Открыть();
    КонецПроцедуры
    
  2. Валидация данных при записи: на уровне модуля объекта проверяем корректность выбранного элемента в событии ОбработкаПроверкиЗаполнения или ПередЗаписью с помощью метода ПринадлежитЭлементу():
    
    Для Каждого Стр Из Товары Цикл
        Если НЕ Стр.Номенклатура.ПринадлежитЭлементу(НужнаяГруппаНоменклатуры) Тогда
            Отказ = Истина;
            Сообщение = Новый СообщениеПользователю;
            Сообщение.Текст = "Номенклатура """ + Стр.Номенклатура + """ не входит в разрешенную группу!";
            Сообщение.Сообщить();
        КонецЕсли;
    КонецЦикла;
    

Как решить аналогичную задачу в управляемых формах

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

  1. Свойство «Параметры выбора»: в палитре свойств элемента формы или реквизита объекта находим пункт ПараметрыВыбора и добавляем отбор Отбор.Родитель(ВИерархии), указав целевую группу. Платформа автоматически применит это ограничение как для всплывающего списка автоподбора, так и для формы выбора.
  2. Событие модуля менеджера: если логика фильтрации зависит от контекста документа, переопределяем обработчик ОбработкаПолученияДанныхВыбора в модуле менеджера справочника Номенклатура, где динамически формируем список ДанныеВыбора на основе переданных параметров.
← На главную