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