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

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

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

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

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

Для начала проанализируем код, который позволяет получить форму и наложить на ее основной реквизит (обычно это СправочникСписок) необходимый фильтр:


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

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

Метод 2. Отключение иерархического просмотра для «плоского» списка

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

Проанализируем этот подход:


// В дополнение к установке отбора
ФормаВыбора.ЭлементыФормы.СправочникСписок.ИерархическийПросмотр = Ложь;

Когда свойство ИерархическийПросмотр установлено в Ложь, справочник превращается в плоскую таблицу. В этом случае отбор по колонке Родитель отрабатывает идеально, скрывая всё лишнее. Кнопки «Перейти на уровень вверх» и дерево групп исчезнут или перестанут влиять на состав строк.

Метод 3. Позиционирование на группе через дерево (ТекущаяСтрока)

Иногда пользователю всё же нужно оставить возможность навигации, но при открытии формы «провалить» его в конкретную папку. В обычных формах установка свойства ТекущийРодитель не всегда срабатывает стабильно, если форма уже содержит дерево групп. Выясним причину: дерево слева само управляет текущим родителем списка.

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


// Получаем ссылку на нужную группу
ГруппаДляОткрытия = Справочники.Номенклатура.НайтиПоНаименованию("Инструменты");

// Устанавливаем текущую строку. Для справочника в обычной форме 
// текущей строкой списка является ссылка на элемент.
ФормаВыбора.ЭлементыФормы.СправочникСписок.ТекущаяСтрока = ГруппаДляОткрытия;

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

Метод 4. Ограничение через «Связи параметров выбора» в метаданных

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

  1. Откроем свойства реквизита объекта (например, поле Договор в документе).
  2. Найдем свойство Связи параметров выбора.
  3. Настроим связь: укажем, что поле Родитель выбираемого справочника должно быть равно значению какого-либо другого реквизита формы (например, предопределенной группе или реквизиту, где хранится ссылка на папку).

Платформа сама наложит фильтр при интерактивном нажатии на кнопку выбора. Это самый «чистый» способ с точки зрения архитектуры 1С.

Метод 5. Использование параметра «ВыборГруппИЭлементов»

При настройке выбора важно определить, что именно мы разрешаем выбирать. Если нам нужны только конечные элементы внутри группы, а выбор самих групп (папок) запрещен, необходимо использовать перечисление ИспользованиеВыбораГруппИЭлементов.

Посмотрим на пример установки этого параметра:


ФормаВыбора = Справочники.Контрагенты.ПолучитьФормуВыбора(, Элемент);
// Разрешаем выбирать только элементы, исключая группы
ФормаВыбора.ВыборГруппИЭлементов = ИспользованиеВыбораГруппИЭлементов.Элементы;
ФормаВыбора.Открыть();

Метод 6. Использование метода «Выбрать()» менеджера справочника

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

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


Выборка = Справочники.Склады.Выбрать(ГруппаСкладов);
СписокДляВыбора = Новый СписокЗначений;

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

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

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

Проанализируем основные ошибки, которые совершают разработчики при работе с отборами в обычных формах:

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

← На главную