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