Почему поле ввода на управляемой форме не сохраняет выбранное из списка значение?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке управляемых форм в 1С:Предприятии часто возникает задача предоставить пользователю выбор одного варианта из заранее подготовленного перечня. Однако начинающие разработчики нередко сталкиваются с ситуацией: список вариантов заполнен программно, выпадающее меню открывается, значение выбирается, но в поле ввода ничего не фиксируется или введенные данные сразу сбрасываются. Разберем детально, почему так происходит и как правильно реализовать выбор значения.

Причина проблемы: несовпадение скалярного выбора и типа реквизита

Проанализируем стандартное поведение платформы 1С. Когда на форму добавляется реквизит с типом СписокЗначений и перетаскивается в элементы формы, создается поле ввода, рассчитанное на работу со всей коллекцией целиком. В обычном режиме оно отображает элементы списка через точку с запятой.

Если для такого поля ввода включить свойство РежимВыбораИзСписка и заполнить коллекцию СписокВыбора, поведение элемента меняется:

  1. Пользователь нажимает на кнопку выбора и выбирает один конкретный пункт.
  2. Платформа пытается выполнить стандартное скалярное присвоение: поместить выбранный объект (например, строку или ссылку) непосредственно в реквизит формы, связанный с полем через свойство ПутьКДанным.
  3. Поскольку реквизит формы имеет тип СписокЗначений (коллекция), а не скалярный тип, операция прямого присваивания значения завершается сбоем, и поле ввода сбрасывает результат выбора.

Выясним, какие варианты настройки и программной реализации позволяют корректно решить эту задачу.

Вариант 1. Использование реквизита скалярного или произвольного типа (рекомендуемый способ)

Рассмотрим основной и наиболее правильный подход: реквизит формы должен хранить именно тот тип данных, который выбирает пользователь, а список возможных вариантов должен находиться в свойстве СписокВыбора элемента формы.

Разберем по шагам настройку элементов:

  1. Создадим реквизит формы (например, с именем ВыбранныйВариант).
  2. Назначим ему тип данных, соответствующий выбираемым значениям (например, Строка, Число, конкретная ссылка). Если варианты в списке могут иметь разнородные типы, укажем составной тип или тип Произвольный.
  3. Перетащим реквизит в дерево элементов формы, создав поле ввода.
  4. В свойствах элемента формы установим флаг РежимВыбораИзСписка в значение Истина.
  5. Заполним список выбора программно при открытии формы или создании на сервере.

Посмотрим на пример заполнения списка выбора на клиенте в обработчике ПриОткрытии:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    
    // Очистим список выбора перед заполнением
    Элементы.ВыбранныйВариант.СписокВыбора.Очистить();
    
    // Добавим варианты действий (значение и понятное пользователю представление)
    Элементы.ВыбранныйВариант.СписокВыбора.Добавить("СоздатьДокумент", "Создать новый документ");
    Элементы.ВыбранныйВариант.СписокВыбора.Добавить("ОбновитьДанные", "Обновить существующие данные");
    Элементы.ВыбранныйВариант.СписокВыбора.Добавить("ОтменитьОперацию", "Отменить текущую операцию");
    
КонецПроцедуры

В этом случае платформа автоматически запишет выбранное значение (например, "СоздатьДокумент") в реквизит ВыбранныйВариант, а в интерфейсе отобразит его представление.

Вариант 2. Ручная фиксация значения в реквизите типа «СписокЗначений»

Иногда логика модуля требует, чтобы реквизит формы обязательно оставался объектом СписокЗначений (например, если он передается далее в общие процедуры как коллекция). В этом случае стандартную обработку выбора необходимо переопределить программно.

Рассмотрим, как это сделать. Для поля ввода создадим событие ОбработкаВыбора. Чтобы платформа не сбрасывала данные, отключим стандартную обработку и вручную запишем выбранное значение в список:


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

Важный момент: если не установить СтандартнаяОбработка = Ложь;, платформа после выполнения вашего кода попытается применить стандартное связывание и снова очистит поле.

Вариант 3. Вызов списка выбора без постоянного поля ввода

Если выбор варианта действия нужен по нажатию кнопки или гиперссылки, привязывать реквизит к полю вовсе не обязательно. Для этого воспользуемся немодальным методом ПоказатьВыборИзСписка().

Посмотрим на пример реализации выбора по кнопке:


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

&НаКлиенте
Процедура ПослеВыбораДействия(ВыбранныйЭлемент, ДополнительныеПараметры) Экспорт
    
    Если ВыбранныйЭлемент = Неопределено Тогда
        Возврат; // Пользователь закрыл меню без выбора
    КонецЕсли;
    
    ВыбранноеЗначение = ВыбранныйЭлемент.Значение;
    // Выполняем дальнейшую логику обработки
    
КонецПроцедуры

Такой подход делает интерфейс формы более чистым и избавляет от необходимости создавать лишние элементы и реквизиты формы.

← На главную