Почему не сохраняется и не отображается выбранное значение из списка выбора в 1С?

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

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

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

Выясняем причину: почему пропадает выбранное значение?

Для того чтобы понять, почему платформа «очищает» поле при открытии, проанализируем внутренние механизмы работы управляемого интерфейса. Здесь играют роль два важнейших фактора: режим выбора из списка и привязка данных. Для быстрой проверки и интерактивной настройки этих параметров непосредственно в сеансе пользователя можно использовать обработку для редактирования свойств элементов управляемых форм в режиме предприятия.

Фактор №1: Режим выбора из списка (Choice List Mode)

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

Давайте посмотрим, как это ломает логику, если заполнять список на клиенте в процедуре ПриОткрытии:

  1. При открытии существующего документа платформа сначала инициализирует форму на сервере. Она считывает сохраненную строку (например, "СДЭК") из базы данных и пытается сопоставить ее со списком выбора элемента формы.
  2. В этот момент на сервере список выбора элемента формы СписокВыбора еще абсолютно пуст, ведь разработчик планирует заполнить его позже — на клиенте в событии ПриОткрытии.
  3. Платформа не находит значение "СДЭК" в пустом списке выбора и «сбрасывает» визуальное отображение поля на форме.
  4. Затем управление передается на клиент, срабатывает процедура ПриОткрытии, список выбора заполняется значениями "СДЭК" и "ПочтаРоссии". Но визуальный сброс уже произошел, и поле остается пустым для пользователя.

Фактор №2: Отсутствие прямой связи с данными (ПутьКДанным)

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


Вариант решения №1: Самый правильный и «чистый» (без написания лишнего кода)

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

Выполним настройку по шагам:

  1. Откройте управляемую форму в конфигураторе и выберите элемент формы (поле ввода), в котором происходит выбор.
  2. В палитре свойств этого элемента найдите свойство ПутьКДанным (DataPath) и укажите в нем ваш реквизит объекта напрямую — например, Объект.Почтоваяслужба (вместо временного локального реквизита формы).
  3. Убедитесь, что для элемента формы включено свойство РежимВыбораИзСписка.
  4. Теперь перенесем заполнение списка выбора с клиента на сервер. Это критически важно, чтобы платформа знала доступные значения еще на этапе компоновки формы до ее отправки клиенту.

Перейдите в модуль формы и реализуйте заполнение списка в процедуре ПриСозданииНаСервере:


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

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


Вариант решения №2: Если необходимо использовать локальный реквизит формы

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

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


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

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

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


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

Обратите внимание: в данном случае нам не требуется отключать стандартную обработку (СтандартнаяОбработка = Ложь), так как элемент формы напрямую связан с реквизитом Реквизит1, и платформа сама корректно отобразит выбранное значение, зная, что оно присутствует в предварительно заполненном списке выбора.


Вариант решения №3: Простой обходной путь с кнопкой списка выбора

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

Рассмотрим этот способ по шагам:

  1. Свяжите элемент формы с реквизитом Объект.Почтоваяслужба через свойство ПутьКДанным.
  2. В свойствах элемента формы **отключите** (снимите галочку) свойство РежимВыбораИзСписка.
  3. В свойствах этого же элемента **включите** (установите галочку) свойство КнопкаСпискаВыбора (Drop List Button).
  4. В событии ПриСозданииНаСервере заполните список выбора точно так же, как в первом варианте.

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

Резюме и рекомендации

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

← На главную