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