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