Как реализовать выбор элементов из определенной группы справочника в 1С

Программист 1С v8.3 (Обычные формы)
← На главную

При разработке конфигураций на платформе 1С часто возникает задача ограничить выбор пользователя конкретной папкой (группой) справочника. Например, если в документе есть несколько табличных частей, каждая из которых должна заполняться только определенным типом свойств (ширина, длина, цвет), открывать каждый раз весь корень справочника неудобно. Пользователю приходится вручную переходить в нужную группу, что замедляет работу и провоцирует ошибки.

В этой статье мы подробно разберем, как программно и интерактивно настроить открытие формы выбора сразу на нужной группе и «запереть» пользователя внутри нее, чтобы он не мог случайно выбрать элементы из других категорий.

Способ 1. Установка параметров в метаданных (для управляемых форм)

Прежде чем приступать к написанию кода, проанализируем стандартные возможности платформы 8.3. Если группа выбора заранее известна и не меняется динамически, мы можем обойтись без программирования.

Для этого в свойствах реквизита (в табличной части или в самом справочнике) найдем пункт Параметры выбора. Здесь можно добавить фиксированный отбор. Укажем поле Родитель и выберем конкретную предопределенную группу. В этом случае при нажатии на кнопку выбора 1С автоматически передаст этот параметр в форму, и пользователь увидит только содержимое нужной папки.

Также обратим внимание на свойство Связи параметров выбора. Это крайне полезный инструмент, если группа зависит от другого реквизита в той же строке табличной части. Например, если в колонке «Тип» указано «Мебель», то в колонке «Свойство» будут доступны только элементы из группы «Мебельные характеристики».

Способ 2. Программное открытие формы в управляемом приложении

Если нам нужно гибкое управление, рассмотрим ситуацию, когда форма открывается программно. Разберем код, который часто используют разработчики, и выясним, почему он иногда не срабатывает. Основной механизм заключается в передаче структуры Отбор через параметры формы.

Посмотрим на пример кода в обработчике события НачалоВыбора:


&НаКлиенте
Процедура ТЧ_ДлинаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь; // Отменяем стандартное открытие формы
    
    ПараметрыОтбора = Новый Структура("Родитель", ПредопределенноеЗначение("Справочник.эл_СвойстваИзделия.Длина"));
    ПараметрыФормы = Новый Структура("Отбор", ПараметрыОтбора);
    
    ОткрытьФорму("Справочник.эл_СвойстваИзделия.ФормаВыбора", ПараметрыФормы, Элемент);
    
КонецПроцедуры

Важный нюанс: Чтобы пользователь не мог сбросить этот фильтр через настройки списка, рекомендуется использовать ФиксированныеНастройки. Если просто передать отбор в параметрах, он применится, но в некоторых интерфейсах пользователь сможет вернуться «на уровень вверх». Чтобы этого избежать, в самой открываемой форме выбора можно программно установить фиксированный отбор в обработчике ПриСозданииНаСервере.

Способ 3. Реализация в обычных формах (1С 8.2 и старые конфигурации)

В обычных формах (не управляемых) механизм работы с формой выбора принципиально другой. Здесь мы сначала получаем объект формы, а затем напрямую обращаемся к настройкам её списка. Проанализируем типичную ошибку: если мы просто установим отбор по родителю, но оставим включенным иерархический просмотр, форма может открыться в корне, просто все остальные ветки будут пустыми.

Рассмотрим правильный алгоритм действий для обычной формы:

  1. Отключаем стандартную обработку события выбора.
  2. Получаем форму выбора через ПолучитьФорму.
  3. Устанавливаем вид сравнения и значение в отборе СправочникСписок.
  4. Выключаем иерархический просмотр, чтобы пользователь видел плоский список элементов именно этой папки.

Пример кода для реализации этого сценария:


Процедура ТЧ_ДлинаНачалоВыбора(Элемент, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    // Получаем форму выбора
    ФормаВыбора = Справочники.эл_СвойстваИзделия.ПолучитьФормуВыбора("ФормаВыбора", Элемент);
    
    // Устанавливаем группу-родителя (например, из предопределенных)
    ГруппаРодитель = Справочники.эл_СвойстваИзделия.Длина;
    
    // Настраиваем отбор в списке справочника
    ОтборРодитель = ФормаВыбора.СправочникСписок.Отбор.Родитель;
    ОтборРодитель.Установить(ГруппаРодитель);
    
    // Важно: отключаем иерархию, чтобы не «выкидывало» в корень
    ФормаВыбора.СправочникСписок.ИерархическийПросмотр = Ложь;
    
    // Открываем форму
    ФормаВыбора.Открыть();
    
КонецПроцедуры

В этом примере свойство ИерархическийПросмотр = Ложь гарантирует, что форма откроется не как дерево с одной активной веткой, а как обычный список элементов, лежащих внутри папки «Длина».

Способ 4. Альтернатива — Выбор из выпадающего списка

Выясним ситуацию: что если элементов в нужной группе совсем немного (например, 5–10 значений)? В таком случае открывать целое окно справочника — это лишнее действие, которое заставляет пользователя переключать внимание. Рассмотрим более элегантный метод — подмену формы выбора выпадающим списком.

Разберем этот метод по шагам:

  1. В событии НачалоВыбора подавляем стандартное окно.
  2. Выполняем запрос к справочнику, выбирая все элементы, у которых родитель — наша группа.
  3. Загружаем результат в СписокЗначений.
  4. Используем метод ВыбратьИзСписка.

Посмотрим на пример кода:


&НаКлиенте
Процедура ТЧ_ДлинаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    СписокЭлементов = ПолучитьСписокЭлементовНаСервере();
    
    ВыбранныйЭлемент = ВыбратьИзСписка(СписокЭлементов, Элемент);
    
    Если ВыбранныйЭлемент <> Неопределено Тогда
        Объект.ТЧ_Длина[Элементы.ТЧ_Длина.ТекущаяСтрока].Свойство = ВыбранныйЭлемент.Значение;
    КонецЕсли;
    
КонецПроцедуры

&НаСервере
Функция ПолучитьСписокЭлементовНаСервере()
    
    Список = Новый СписокЗначений;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   эл_СвойстваИзделия.Ссылка КАК Ссылка
        |ИЗ
        |   Справочник.эл_СвойстваИзделия КАК эл_СвойстваИзделия
        |ГДЕ
        |   эл_СвойстваИзделия.Родитель = &Родитель
        |   И эл_СвойстваИзделия.ЭтоГруппа = ЛОЖЬ";
    
    Запрос.УстановитьПараметр("Родитель", Справочники.эл_СвойстваИзделия.Длина);
    
    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Выборка.Следующий() Цикл
        Список.Добавить(Выборка.Ссылка);
    КонецЦикла;
    
    Возврат Список;
    
КонецФункции

Такой подход максимально ускоряет работу, так как выбор происходит мгновенно в контексте текущего поля ввода.

Типичные ошибки и их решение

Проанализируем, почему отбор может не работать:

Подводя итог, выбор конкретного способа зависит от типа используемых форм и количества элементов в справочнике. Для простых задач идеально подходят настройки в метаданных, для сложных интерфейсов — программная установка отбора с отключением иерархии или выпадающие списки.

← На главную