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