При разработке расширений для конфигураций 1С программисты часто сталкиваются с ситуацией: в коде элемент формы добавлен, путь к данным прописан, отладчик уверенно показывает наличие значения в реквизите объекта, но на самой форме поле отображается абсолютно пустым. В этой статье мы детально разберем, почему возникает этот эффект «невидимых данных», как правильно работать с программными элементами управления и какие нюансы настройки списков выбора критичны для корректного отображения информации.
Рассмотрим типовой сценарий. Нам необходимо расширить функционал документа (например, «Прием на работу») и добавить на форму поле, где пользователь сможет выбрать адрес места работы из списка контактной информации организации. Мы используем расширение и подключаемся к событию ПриСозданииНаСервере.
Давайте проанализируем базовый код создания элемента:
&НаСервере
Процедура РасшКадры_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
// Добавляем новое поле на форму программно
НовоеПоле = Элементы.Добавить("АдресМестаРаботыСотрудника", Тип("ПолеФормы"), Элементы.ГруппаПравая);
НовоеПоле.ПутьКДанным = "Объект.АдресМестаРаботыСотрудника";
НовоеПоле.Вид = ВидПоляФормы.ПолеВвода;
// Включаем режим выбора из списка
НовоеПоле.РежимВыбораИзСписка = Истина;
НовоеПоле.КнопкаВыпадающегоСписка = Истина;
// Заполняем список выбора значениями
СформироватьАдресаМестРаботыСотрудника(Объект.Организация);
КонецПроцедуры
На первый взгляд, все верно. Однако именно здесь кроется причина проблемы. Когда мы устанавливаем свойство РежимВыбораИзСписка = Истина, поведение платформы 1С кардинально меняется.
Разберем подробнее, как работает РежимВыбораИзСписка. Это свойство указывает платформе, что значение в данном поле может быть только одним из тех, что содержатся в коллекции СписокВыбора этого элемента.
Проанализируем механику отображения:
ПутьКДанным (например, «г. Москва, ул. Ленина, д. 1»).СписокВыбора этого элемента формы.Объект.АдресМестаРаботыСотрудника данные есть, визуально поле останется пустым.Таким образом, если вы открываете форму существующего документа, где адрес уже сохранен, но код заполнения списка выбора по какой-то причине не отработал или сформировал другой список, пользователь увидит пустое поле.
Для того чтобы данные всегда корректно отображались, список выбора должен инициализироваться при каждом открытии формы. Выясним, как оптимизировать этот процесс. Часто разработчики допускают ошибку, обращаясь к данным через точку от ссылки, что замедляет работу системы. Проанализируем более грамотный подход с использованием функций общего назначения.
&НаСервере
Процедура СформироватьАдресаМестРаботыСотрудника(ОрганизацияСсылка)
// Очищаем текущий список перед заполнением
ЭлементСписок = Элементы.АдресМестаРаботыСотрудника;
ЭлементСписок.СписокВыбора.Очистить();
// Проверяем заполненность организации
Если ОрганизацияСсылка.Пустая() Тогда
Возврат;
КонецЕсли;
// Используем БСП для получения табличной части контактной информации
// Это гораздо быстрее, чем прямое обращение через точку
КонтактнаяИнформация = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ОрганизацияСсылка, "КонтактнаяИнформация");
Для Каждого СтрокаКИ Из КонтактнаяИнформация Цикл
// Отфильтруем только нужные нам виды адресов, например, рабочие
Если СтрНайти(Врег(Строка(СтрокаКИ.Вид)), "РАБОТ") > 0 Тогда
ЭлементСписок.СписокВыбора.Добавить(СтрокаКИ.Представление);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Если специфика вашей задачи допускает, что пользователь может ввести адрес вручную (которого нет в предустановленном списке организации), или вы хотите гарантированно видеть значение, даже если список выбора еще не загружен, рассмотрим альтернативный вариант настройки элемента:
РежимВыбораИзСписка = Ложь.КнопкаСпискаВыбора = Истина.В этом случае поле ведет себя как обычное текстовое поле ввода, но сохраняет «стрелочку» справа. При нажатии на нее будет выпадать ваш список, но само значение в поле не будет зависеть от наличия совпадений в этом списке. Это «соломоново решение», которое избавляет от проблем с пустующими полями при сохранении гибкости ввода.
Разберем еще несколько моментов, которые помогут избежать ошибок при программном добавлении элементов в расширениях:
1. Место хранения данных. Помните, что если вы просто добавили «Реквизит формы» в расширении, он не будет сохраняться в базе данных. Чтобы данные «выжили» после закрытия формы, реквизит должен быть добавлен в объект метаданных (само дерево документа в расширении).
2. Обновление при изменении. Если на форме меняется «Организация», список адресов в нашем поле должен моментально обновиться. Для этого необходимо создать обработчик события ПриИзменении для поля Организация:
&НаКлиенте
Процедура РасшКадры_ОрганизацияПриИзмененииПосле(Элемент)
// Вызываем серверную процедуру переформирования списка
СформироватьАдресаМестРаботыСотрудника(Объект.Организация);
КонецПроцедуры
3. Проверка на существование. При программном добавлении элементов в процедурах, которые могут вызываться повторно, всегда проверяйте, не создан ли элемент ранее, используя Элементы.Найти("ИмяЭлемента"), чтобы избежать исключительных ситуаций.
Подведем итог: если в отладчике значение есть, а на форме его нет — в 99% случаев виновато свойство РежимВыбораИзСписка и отсутствие актуального значения в коллекции СписокВыбора. Настраивайте элементы внимательно, используйте возможности БСП для получения данных и всегда учитывайте жизненный цикл формы управляемого приложения.