Как установить отбор «В иерархии» при выборе элемента справочника в управляемой форме 1С?

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

При разработке интерфейсов в 1С:Предприятии 8.3 часто возникает задача ограничить выбор элементов определенной группой (папкой) справочника или списком условий. Разработчики сталкиваются с ограничением: типовые свойства реквизитов и элементов формы Параметры выбора и Связи параметров выбора в конфигураторе поддерживают только строгое равенство (ВидСравнения.Равно). Задать условие В иерархии декларативно через свойства объекта нельзя.

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

Способ 1. Программное открытие формы выбора с фиксированными настройками динамического списка

Проанализируем классический вариант решения задачи. Мы перехватываем стандартную обработку выбора значения и открываем форму выбора программно, передавая в нее структуру отбора через объект НастройкиКомпоновкиДанных.

Разберем по шагам реализацию этого механизма:

  1. В свойствах элемента формы создадим событие НачалоВыбора.
  2. Установим признак СтандартнаяОбработка = Ложь, чтобы отменить стандартное открытие формы без отборов.
  3. Сформируем объект НастройкиКомпоновкиДанных и добавим элемент отбора с видом сравнения ВидСравненияКомпоновкиДанных.ВИерархии.
  4. Передадим настройки в параметре формы ФиксированныеНастройки.

Посмотрим на пример кода в модуле формы:


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

Использование параметра ФиксированныеНастройки гарантирует, что пользователь не сможет снять или изменить данный отбор в открывшемся окне.

Способ 2. Настройка отбора внутри самой формы выбора

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

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


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

В модуле самой формы выбора в обработчике ПриСозданииНаСервере считываем этот параметр и добавляем условие в отбор динамического списка Список:


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

Способ 3. Ограничение выбора на уровне модуля менеджера для быстрого ввода

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

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


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

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

← На главную