В процессе разработки на платформе 1С:Предприятие 8 (особенно при работе с обычными формами) часто возникает задача ограничить пользователю область выбора элементов в справочнике. Типичный пример: при выборе договора в документе нужно показать только те договоры, которые относятся к определенной папке или контрагенту. В этой статье мы подробно разберем, как программно вызвать форму выбора и установить в ней жесткий фильтр по родителю, а также рассмотрим нюансы работы с иерархическими списками.
Самый распространенный и гибкий способ — это перехват события ПередНачаломВыбора в поле ввода или программный вызов формы через менеджер справочника. Рассмотрим ситуацию, когда нам нужно открыть форму выбора справочника Номенклатура и показать только товары из группы «Запчасти».
Для начала проанализируем код, который позволяет получить форму и наложить на ее основной реквизит (обычно это СправочникСписок) необходимый фильтр:
// В обработчике события НачалоВыбора или в любой другой процедуре
Процедура ПолеВводаНачалоВыбора(Элемент, СтандартнаяОбработка)
// Отменяем стандартное открытие формы, так как будем открывать её программно
СтандартнаяОбработка = Ложь;
// Получаем форму выбора по умолчанию
ФормаВыбора = Справочники.Номенклатура.ПолучитьФормуВыбора("ФормаВыбора", Элемент);
// Устанавливаем отбор по конкретной группе (Родителю)
// НужнаяГруппа - это ссылка на элемент справочника, являющийся группой
ФормаВыбора.СправочникСписок.Отбор.Родитель.ВидСравнения = ВидСравнения.Равно;
ФормаВыбора.СправочникСписок.Отбор.Родитель.Значение = НужнаяГруппа;
ФормаВыбора.СправочникСписок.Отбор.Родитель.Использование = Истина;
// По желанию: запрещаем пользователю менять этот отбор
ФормаВыбора.ЭлементыФормы.СправочникСписок.НастройкаОтбора.Родитель.Доступность = Ложь;
ФормаВыбора.Открыть();
КонецПроцедуры
В данном примере мы используем объект Отбор. Важно помнить, что если в справочнике включена иерархия, обычный отбор по родителю может конфликтовать с визуальным деревом групп в левой части формы. Рассмотрим далее, как этого избежать.
Как отмечалось в обсуждении, иерархический список может мешать работе фильтра. Если ваша задача — не просто подсветить группу, а сделать так, чтобы пользователь видел только элементы этой группы без возможности «бродить» по другим папкам, лучше всего отключить иерархический просмотр программно.
Проанализируем этот подход:
// В дополнение к установке отбора
ФормаВыбора.ЭлементыФормы.СправочникСписок.ИерархическийПросмотр = Ложь;
Когда свойство ИерархическийПросмотр установлено в Ложь, справочник превращается в плоскую таблицу. В этом случае отбор по колонке Родитель отрабатывает идеально, скрывая всё лишнее. Кнопки «Перейти на уровень вверх» и дерево групп исчезнут или перестанут влиять на состав строк.
Иногда пользователю всё же нужно оставить возможность навигации, но при открытии формы «провалить» его в конкретную папку. В обычных формах установка свойства ТекущийРодитель не всегда срабатывает стабильно, если форма уже содержит дерево групп. Выясним причину: дерево слева само управляет текущим родителем списка.
Решение заключается в том, чтобы установить фокус на нужную группу в самом объекте списка или дерева. Рассмотрим пример:
// Получаем ссылку на нужную группу
ГруппаДляОткрытия = Справочники.Номенклатура.НайтиПоНаименованию("Инструменты");
// Устанавливаем текущую строку. Для справочника в обычной форме
// текущей строкой списка является ссылка на элемент.
ФормаВыбора.ЭлементыФормы.СправочникСписок.ТекущаяСтрока = ГруппаДляОткрытия;
При таком подходе форма откроется, и в левой части (в дереве) курсор автоматически встанет на папку «Инструменты», а в правой части отобразится ее содержимое. Это наиболее мягкий способ управления интерфейсом, который не ограничивает права пользователя, но помогает ему быстрее найти данные.
Если задача типовая и решается в рамках одного реквизита, мы можем обойтись без написания кода. Рассмотрим, как это сделать в конфигураторе:
Договор в документе).Родитель выбираемого справочника должно быть равно значению какого-либо другого реквизита формы (например, предопределенной группе или реквизиту, где хранится ссылка на папку).Платформа сама наложит фильтр при интерактивном нажатии на кнопку выбора. Это самый «чистый» способ с точки зрения архитектуры 1С.
При настройке выбора важно определить, что именно мы разрешаем выбирать. Если нам нужны только конечные элементы внутри группы, а выбор самих групп (папок) запрещен, необходимо использовать перечисление ИспользованиеВыбораГруппИЭлементов.
Посмотрим на пример установки этого параметра:
ФормаВыбора = Справочники.Контрагенты.ПолучитьФормуВыбора(, Элемент);
// Разрешаем выбирать только элементы, исключая группы
ФормаВыбора.ВыборГруппИЭлементов = ИспользованиеВыбораГруппИЭлементов.Элементы;
ФормаВыбора.Открыть();
В редких случаях, когда стандартная форма выбора слишком перегружена, можно воспользоваться методом Выбрать(). Он позволяет получить выборку с уже наложенным фильтром. На основе этой выборки можно быстро заполнить СписокЗначений и предложить его пользователю через метод ВыбратьИзСписка().
Разберем, когда это полезно: если в группе всего 5-10 элементов, открывать тяжелую форму справочника нецелесообразно. Проще показать компактный список прямо под полем ввода.
Выборка = Справочники.Склады.Выбрать(ГруппаСкладов);
СписокДляВыбора = Новый СписокЗначений;
Пока Выборка.Следующий() Цикл
СписокДляВыбора.Добавить(Выборка.Ссылка);
КонецЦикла;
// Показываем список пользователю
ВыбранноеЗначение = ВыбратьИзСписка(СписокДляВыбора, ЭлементФормы);
Если ВыбранноеЗначение <> Неопределено Тогда
Объект.Склад = ВыбранноеЗначение.Значение;
КонецЕсли;
Проанализируем основные ошибки, которые совершают разработчики при работе с отборами в обычных формах:
ВидСравнения.Равно для родителя, вы увидите только элементы «первого уровня» этой папки. Если внутри есть подпапки, их содержимое не отобразится. В таких случаях используйте ВидСравнения.ВИерархии.Используя приведенные выше методы, вы сможете гибко управлять процессом выбора, делая интерфейс вашей конфигурации более дружелюбным и защищенным от ошибок ввода данных.