Почему не отображается значение в поле ввода при включенном свойстве РежимВыбораИзСписка?

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

При разработке управляемых форм в 1С часто возникает задача ограничить ввод пользователя заранее определенным набором значений. Для этого у элемента формы включают свойство РежимВыбораИзСписка. Однако нередко разработчики сталкиваются с неприятным поведением платформы: реквизит в объекте заполнен, но при открытии формы поле ввода остается пустым. Разберем механику этой проблемы и рассмотрим надежные способы ее решения.

Выясним причину такого поведения платформы

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

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

Распространенная ошибка заключается в том, что список выбора заполняют исключительно в обработчике события НачалоВыбора. В таком сценарии при интерактивном клике на кнопку выбора список формируется и выбор срабатывает штатно. Но при повторном открытии формы событие НачалоВыбора еще не наступало, коллекция СписокВыбора пуста, и сохраненное значение снова не отображается на экране.

Решение 1. Полная инициализация списка выбора при создании формы

Проанализируем наиболее стабильный и правильный подход. Если список допустимых значений формируется динамически в коде, его следует заполнять целиком уже на этапе создания формы на сервере, а не откладывать до момента нажатия пользователем на кнопку выбора.

Рассмотрим пример кода в серверном обработчике формы:


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

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

Решение 2. Добавление текущего значения реквизита в список выбора

Посмотрим на ситуацию, когда список выбора огромен или его полное построение на сервере при каждом открытии формы нежелательно из соображений производительности. В этом случае в обработчике ПриСозданииНаСервере можно добавить в СписокВыбора только текущее сохраненное значение, а весь остальной массив подгружать позже в НачалоВыбора.

Разберем по шагам, как это реализовать:

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

Рассмотрим пример реализации на сервере:


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

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

Решение 3. Использование свойства КнопкаСпискаВыбора

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


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

В таком режиме поле сохраняет визуальное значение реквизита независимо от того, заполнен ли СписокВыбора при открытии формы. Пользователь при этом по-прежнему может нажимать на кнопку выпадающего списка и выбирать нужный вариант.

Решение 4. Открытие выпадающего списка через метод ПоказатьВыборИзСписка

Проанализируем еще один удобный подход, который полностью избавляет от необходимости синхронизировать свойства самого элемента формы. Мы можем оставить свойства РежимВыбораИзСписка и КнопкаСпискаВыбора выключенными, включив стандартную кнопку выбора КнопкаВыбора = Истина, а сам выбор обрабатывать асинхронно на клиенте.

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


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

&НаКлиенте
Процедура ПослеВыбораИзСписка(ВыбранныйЭлемент, ДополнительныеПараметры) Экспорт
    
    Если ВыбранныйЭлемент <> Неопределено Тогда
        Объект.Реквизит = ВыбранныйЭлемент.Значение;
    КонецЕсли;
    
КонецПроцедуры

Этот метод гарантирует, что значение в реквизите отображается всегда в стандартном виде, а интерактивный выбор динамически формируется непосредственно перед показом пользователю.

← На главную