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