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