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

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

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

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

Метод 1. Программная установка отбора в обычных формах

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


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

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

Метод 2. Использование свойств «Параметры выбора» (без программирования)

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

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

Этот метод хорош тем, что он не требует написания кода и работает автоматически. Однако он обладает существенным недостатком — «жесткой» привязкой к конкретной группе. Если логика фильтрации должна меняться в зависимости от условий, нам придется использовать программные методы.

Метод 3. Управляемые формы и событие «НачалоВыбора»

В управляемом интерфейсе (платформа 8.3) работа с формами строится иначе. Мы не получаем форму явно через ПолучитьФорму, а передаем параметры открытия. Проанализируем, как это сделать в обработчике события НачалоВыбора для элемента формы:


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

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

Метод 4. Фиксированные настройки динамического списка

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


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

Использование ФиксированныеНастройки в объекте КомпоновщикНастроек делает отбор невидимым и недоступным для изменения пользователем. Это критически важно для соблюдения бизнес-логики, когда выбор из других групп строго запрещен правилами учета.

Метод 5. Использование механизма «Связи параметров выбора»

Иногда группа отбора зависит от другого поля на той же форме. Например, при выборе подразделения в поле «Сотрудник» должны отображаться только люди из этого подразделения. Для этого разберем функционал Связи параметров выбора:

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

Теперь при изменении значения в первом поле список выбора во втором будет обновляться автоматически. Это избавляет от необходимости писать какой-либо программный код в ПриИзменении или НачалоВыбора.

Выводы и рекомендации

Подведем итог нашему анализу. Выбор метода зависит от сложности вашей задачи:

Помните, что при использовании иерархических отборов важно правильно указывать тип сравнения. Обычное «Равно» найдет только саму группу, в то время как ВИерархии или ВСпискеПоИерархии раскроют все содержимое выбранной ветки справочника.

← На главную