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