Как настроить отбор по родителю при автоподборе (вводе по строке) в обычных формах 1С?

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

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

Разбор типичной ошибки: форма выбора и автоподбор

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


Форма = Справочники.Номенклатура.ПолучитьФормуВыбора(, Элемент);
Форма.Отбор.Ссылка.ВидСравнения = ВидСравнения.НеВИерархии;
Форма.Отбор.Ссылка.Значение = РодительНоменклатуры;
Форма.Отбор.Ссылка.Использование = Истина;
Форма.РежимВыбора = Истина;
Форма.Открыть();

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

Почему так происходит? Выясним причину: форма выбора и выпадающий список (автоподбор) — это совершенно разные механизмы. Настройки формы никак не влияют на формирование быстрого списка при вводе по строке.

Решение 1: Использование события АвтоПодбор поля ввода

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

  1. Перехватим введенный текст в обработчике события АвтоПодбор.
  2. Обязательно отключим стандартный механизм платформы, установив СтандартнаяОбработка = Ложь.
  3. Сформируем собственный запрос к справочнику с учетом нужного нам родителя и введенного текста.
  4. Поместим результат в параметр ДанныеВыбора (тип СписокЗначений).

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


Процедура НоменклатураАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
    
    // Отключаем стандартный поиск всей номенклатуры
    СтандартнаяОбработка = Ложь;
    
    // Создаем запрос для ручного поиска
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 50
        |    Номенклатура.Ссылка КАК Ссылка
        |ИЗ
        |    Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |    Номенклатура.Родитель В ИЕРАРХИИ(&Родитель)
        |    И Номенклатура.Наименование ПОДОБНО &ТекстПоиска";
        
    Запрос.УстановитьПараметр("Родитель", НужныйРодитель);
    // Добавляем знак процента для поиска по началу строки
    Запрос.УстановитьПараметр("ТекстПоиска", Текст + "%");
    
    Результат = Запрос.Выполнить();
    Выборка = Результат.Выбрать();
    
    // Формируем свой список выбора
    ДанныеВыбора = Новый СписокЗначений;
    Пока Выборка.Следующий() Цикл
        ДанныеВыбора.Добавить(Выборка.Ссылка);
    КонецЦикла;
    
КонецПроцедуры

Важный нюанс: Обязательно используйте ограничение выборки (например, ВЫБРАТЬ ПЕРВЫЕ 50). Если пользователь введет только одну букву, и в выбранной папке тысячи элементов, запрос без ограничения может вызвать серьезное зависание системы.

Решение 2: Универсальный подход через модуль менеджера (для 8.3+)

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

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

Решение 3: Ограничение через "Список выбора"

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

  1. Используем событие НачалоВыбораИзСписка или заполняем список при открытии формы.
  2. Программно заполняем свойство элемента управления СписокВыбора нужными значениями из выбранной папки.
  3. Устанавливаем свойство поля РежимВыбораИзСписка в значение Истина.

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

Дополнительные аспекты: Иерархия и полнотекстовый поиск

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

Также обратите внимание на тип иерархии в запросе: если вы используете оператор В ИЕРАРХИИ, система будет искать элементы во всех вложенных подпапках указанного родителя. Если же задача состоит в том, чтобы искать элементы строго в одной конкретной группе (без учета вложенных папок), то в запросе необходимо использовать строгое равенство: ГДЕ Номенклатура.Родитель = &Родитель.

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

← На главную