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