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