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