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

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

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

Анализ проблемы и механизма валидации платформы

Проанализируем ситуацию, которая возникает при включении флага РежимВыбораИзСписка. Этот режим превращает стандартное поле ввода в строгий выпадающий список (combo box). Главная особенность этого режима заключается в жесткой валидации данных:

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

Способ 1. Отключение жесткого режима и использование кнопки списка выбора

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

Выполним следующие шаги:

  1. В палитре свойств поля ввода снимем флажок РежимВыбораИзСписка (установим в значение Ложь).
  2. Установим флажок КнопкаСпискаВыбора (или КнопкаВыпадающегоСписка в зависимости от варианта форм) в значение Истина.
  3. Чтобы пользователь не мог вводить произвольный текст руками, а выбирал только из предложенных вариантов, установим свойство РедактированиеТекста в значение Ложь.

Посмотрим на пример программного заполнения списка и установки значения по умолчанию при нажатии кнопки:


&НаКлиенте
Процедура ЗаполнитьИменаПоУмолчанию(Команда)
    
    // Очищаем коллекцию перед повторным заполнением
    Элементы.ИмяПользователя.СписокВыбора.Очистить();
    
    // Добавляем доступные варианты
    Элементы.ИмяПользователя.СписокВыбора.Добавить("Сергей");
    Элементы.ИмяПользователя.СписокВыбора.Добавить("Иван");
    Элементы.ИмяПользователя.СписокВыбора.Добавить("Петр");
    
    // Устанавливаем значение первого элемента списка в реквизит формы
    Если Элементы.ИмяПользователя.СписокВыбора.Количество() > 0 Тогда
        ИмяПользователя = Элементы.ИмяПользователя.СписокВыбора[0].Значение;
    КонецЕсли;
    
КонецПроцедуры

При таких настройках список выбора существует независимо от валидатора ввода: реквизит корректно принимает значение, а пользователь может открывать выпадающий список нажатием кнопки.

Способ 2. Корректная инициализация списка до вывода данных формы

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

В управляемых формах эту операцию необходимо выполнять на сервере в момент создания формы:


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

Обратим внимание на важные детали при работе с данным режимом:

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

Способ 3. Использование события «НачалоВыбора»

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

Для поля ввода отключаем РежимВыбораИзСписка, включаем свойство КнопкаВыбора и создаем обработчик события НачалоВыбора:


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

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

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

← На главную