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