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

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

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

Анализ проблемы: почему список не выпадает

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

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

Шаг 1. Настройка свойств элемента формы

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

Шаг 2. Реализация логики заполнения списка

Рассмотрим правильный подход к заполнению списка. Лучше всего вынести логику формирования списка в отдельную серверную функцию, которая возвращает объект СписокЗначений. Проанализируем код, который решает поставленную задачу.

Для начала создадим процедуру, которая будет вызываться при изменении основного статуса. Это позволит нам сразу подготовить список выбора для зависимого реквизита.


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

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

Шаг 3. Формирование данных на сервере

Теперь реализуем серверную часть. Важно добавлять в список именно ссылки на перечисления, а не строковые представления, иначе при выборе возникнет ошибка несоответствия типов.


&НаСервереБезКонтекста
Функция ПолучитьСписокДоступныхВариантов(Знач ТекущийСтатус)
    Результат = Новый СписокЗначений;
    
    Если ТекущийСтатус = Перечисления.СтатусыПроживания.Заключение Тогда
        Результат.Добавить(Перечисления.ЕРМ_ВариантыСтатусовПроживания.З_ПоискПринятыхЗаПериод, "Принятые за период");
        Результат.Добавить(Перечисления.ЕРМ_ВариантыСтатусовПроживания.З_РаботающиеНаДату, "Работающие на дату");
        
    ИначеЕсли ТекущийСтатус = Перечисления.СтатусыПроживания.Приостановка Тогда
        Результат.Добавить(Перечисления.ЕРМ_ВариантыСтатусовПроживания.В_РучнойПодборПоПроживающим, "Ручной подбор");
        Результат.Добавить(Перечисления.ЕРМ_ВариантыСтатусовПроживания.В_ЗаполнениеПериодаПриостановки, "Заполнить период для всех");
        
    ИначеЕсли ТекущийСтатус = Перечисления.СтатусыПроживания.Расторжение Тогда
        Результат.Добавить(Перечисления.ЕРМ_ВариантыСтатусовПроживания.Р_Увольнение, "Уволенные на дату");
    КонецЕсли;
    
    Возврат Результат;
КонецФункции

Шаг 4. Использование события НачалоВыбора

Если вы хотите, чтобы список формировался именно в момент нажатия на кнопку выбора (динамически), используйте событие НачалоВыбора. Это критически важный момент: здесь нужно явно управлять параметром СтандартнаяОбработка.

Разберем, как это работает:


&НаКлиенте
Процедура ВариантСтатусаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    // Отключаем стандартный механизм 1С, который показывает все значения перечисления
    СтандартнаяОбработка = Ложь;
    
    // Вызываем нашу процедуру обновления списка
    ОбновитьСписокВыбораВариантов();
КонецПроцедуры

Важное примечание: Если вы установите СтандартнаяОбработка = Ложь, но забудете заполнить СписокВыбора или ДанныеВыбора, нажатие на кнопку выбора не приведет ни к какому результату — список просто не откроется. Это именно та ситуация, которую описывал автор темы.

Сравнение СписокВыбора и ДоступныеЗначения

Выясним разницу между двумя похожими свойствами, чтобы не допускать ошибок в будущем:

Дополнительные рекомендации по UX

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


&НаКлиенте
// Внутри процедуры СтатусПриИзменении
Если Список.НайтиПоЗначению(Объект.ВариантСтатуса) = Неопределено Тогда
    Объект.ВариантСтатуса = Неопределено; // Или значение по умолчанию
КонецЕсли;

Это гарантирует, что данные в базе всегда будут соответствовать логике вашего фильтра. Также в некоторых случаях после программного изменения списка на клиенте полезно вызвать метод ЭтаФорма.ОбновитьОтображениеДанных(), чтобы форсировать перерисовку элементов интерфейса, хотя в большинстве случаев 1С делает это автоматически. Для отладки и инспектирования свойств элементов прямо в режиме пользователя пригодится инструмент для редактирования свойств форм в режиме предприятия.

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

← На главную