Как ограничить список выбора значений перечисления в поле формы 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Особенности работы с перечислениями в интерфейсе

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

Для ограничения списка выбора нам потребуется перевести элемент управления в режим выбора из локального списка значений и заполнить этот список только разрешенными элементами. Рассмотрим основные способы реализации.

Способ 1. Программное заполнение списка на сервере (рекомендуемый способ)

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

Разберем по шагам алгоритм настройки:

  1. Откроем модуль формы объекта (например, справочника).
  2. Найдем или создадим обработчик события ПриСозданииНаСервере.
  3. Включим свойство элемента формы РежимВыбораИзСписка.
  4. Очистим коллекцию СписокВыбора элемента и добавим в нее только необходимые значения перечисления с помощью функции ПредопределенноеЗначение().

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Включаем режим выбора из списка для нужного элемента
    Элементы.ИмяРеквизита.РежимВыбораИзСписка = Истина;
    
    // Очищаем список выбора на случай повторной инициализации
    Элементы.ИмяРеквизита.СписокВыбора.Очистить();
    
    // Добавляем только разрешенные значения
    Элементы.ИмяРеквизита.СписокВыбора.Добавить(ПредопределенноеЗначение("Перечисление.ИмяПеречисления.Значение1"));
    Элементы.ИмяРеквизита.СписокВыбора.Добавить(ПредопределенноеЗначение("Перечисление.ИмяПеречисления.Значение2"));
    
КонецПроцедуры

Важный момент: если мы просто добавим элементы в СписокВыбора, но забудем установить свойство РежимВыбораИзСписка = Истина, платформа продолжит открывать полное окно выбора со всеми значениями перечисления.

Способ 2. Интерактивная настройка в конфигураторе

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

Рассмотрим порядок действий в редакторе формы:

  1. Выделим нужное поле ввода в дереве элементов формы.
  2. В палитре свойств найдем раздел Использование и установим флаг РежимВыбораИзСписка в значение Истина.
  3. В свойстве СписокВыбора нажмем кнопку открытия и вручную добавим только те элементы перечисления, которые должны быть доступны пользователю.
  4. В свойствах элемента включим свойство КнопкаВыпадающегоСписка и отключим РедактированиеТекста (установив значение Ложь), чтобы пользователь не мог ввести непредусмотренное значение вручную с клавиатуры.

Способ 3. Перехват события «НачалоВыбора» на клиенте

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

Посмотрим на пример реализации клиентского обработчика:


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

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

Способ 4. Централизованное ограничение через модуль менеджера

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

Для этого в модуле менеджера перечисления определим процедуру-обработчик:


Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    ДанныеВыбора = Новый СписокЗначений;
    ДанныеВыбора.Добавить(Перечисления.ИмяПеречисления.Значение1);
    ДанныеВыбора.Добавить(Перечисления.ИмяПеречисления.Значение2);
    
КонецПроцедуры

Важные нюансы и подводные камни

Проанализируем ситуации, с которыми часто сталкиваются разработчики при ограничении списка выбора перечислений:

  1. Отображение ранее сохраненных значений: если в базе уже существуют объекты со старыми значениями, не входящими в ограниченный список, при открытии формы с включенным свойством РежимВыбораИзСписка поле может визуально отображаться пустым. Чтобы этого избежать, при инициализации формы следует проверять текущее значение реквизита: если оно уже заполнено и отсутствует в урезанном списке, его следует динамически добавить в СписокВыбора.
  2. Защита на уровне бизнес-логики: ограничение на уровне формы защищает только от некорректного ввода пользователем через интерфейс. При записи через код, обмене данными или использовании обработки «Групповое изменение реквизитов» в поле все еще может быть записано любое другое значение перечисления. Для жесткого контроля обязательно добавляйте проверку в модуль объекта в обработчик ПередЗаписью или ОбработкаПроверкиЗаполнения.
← На главную