При разработке универсальных модулей и интеграционных подсистем разработчики часто сталкиваются с задачей динамического добавления элементов управления и реквизитов на формы типовых документов. При этом нередко выдвигаются жесткие архитектурные требования: запрет на прямое редактирование форм и модулей объектов, а также невозможность использования механизма расширений конфигурации. Разберем особенности работы платформы с управляемыми формами, выясним причины возникающих ограничений и рассмотрим корректные пути решения этой задачи.
Попытка перехватить открытие формы документа через подписку на событие ОбработкаПолученияФормы и модифицировать ее из внешней обработки наталкивается на фундаментальные ограничения клиент-серверной архитектуры 1С:
УправляемаяФорма является контекстным и существует на клиенте только в виде ссылки на форму. Его невозможно передать в качестве параметра в серверную процедуру общего модуля или внешней обработки.ИзменитьРеквизиты: Метод ИзменитьРеквизиты доступен исключительно на сервере и может быть выполнен только внутри контекста самой формы (например, в обработчиках ПриСозданииНаСервере или ПриЧтенииНаСервере). Вызвать его снаружи формы при наличии лишь клиентской ссылки на нее невозможно.ОбработкаПолученияФормы: Данное событие служит исключительно для выбора типа или имени формы, которая должна быть открыта. В момент его срабатывания контекст формы еще не сформирован, и программно внедрить в нее реквизиты нельзя.УстановитьДействие для программно созданных элементов может связывать события только с процедурами модуля самой формы или серверными процедурами общих модулей. Подключить в качестве обработчика процедуру из модуля внешней обработки платформа не позволяет.Рассмотрим, как устроен базовый синтаксис программного добавления реквизитов и элементов, если код выполняется в серверном контексте самой формы.
Для добавления нового реквизита формируется массив объектов РеквизитФормы, после чего вызывается метод управляемой формы:
// Создаем описание нового реквизита формы
МассивРеквизитов = Новый Массив;
Реквизит = Новый РеквизитФормы("ДополнительноеПоле", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(150)), , "Доп. поле", Истина);
МассивРеквизитов.Добавить(Реквизит);
// Применяем изменения к структуре реквизитов формы
ЭтаФорма.ИзменитьРеквизиты(МассивРеквизитов);
// Добавляем визуальный элемент на форму и связываем его с реквизитом
Элемент = ЭтаФорма.Элементы.Добавить("ПолеВводаДополнительное", Тип("ПолеФормы"), ЭтаФорма);
Элемент.Вид = ВидПоляФормы.ПолеВвода;
Элемент.ПутьКДанным = "ДополнительноеПоле";
Важно: Обращение к программно добавленным реквизитам верхнего уровня в коде модуля формы возможно только через конструкцию ЭтотОбъект.ИмяРеквизита.
Если конфигурация построена на базе «Библиотеки стандартных подсистем» (БСП), внедрение дополнительных реквизитов без изменения форм документов выполняется через механизм общих переопределяемых модулей. В типовых конфигурациях формы документов при инициализации на сервере передают свой контекст в общие модули.
Разберем по шагам, как подключить программное изменение формы:
МодификацияКонфигурацииПереопределяемый или УправлениеСвойствамиПереопределяемый.ПриСозданииНаСервере получаем контекст формы через переданный параметр Форма.
Процедура ПриСозданииНаСервере(Форма, Отказ, СтандартнаяОбработка) Экспорт
// Проверяем имя формы или тип основного реквизита
Если Форма.ИмяФормы = "Документ.РеализацияТоваровУслуг.Форма.ФормаДокумента" Тогда
МассивДобавляемых = Новый Массив;
МассивДобавляемых.Добавить(Новый РеквизитФормы("СпецСтатус", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(50)), , "Специальный статус"));
Форма.ИзменитьРеквизиты(МассивДобавляемых);
// Создаем элемент формы
НовыйЭлемент = Форма.Элементы.Добавить("СпецСтатус", Тип("ПолеФормы"), Форма);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = "СпецСтатус";
КонецЕсли;
КонецПроцедуры
Если требования проекта исключают даже минимальную правку общих модулей конфигурации, проанализируем следующие варианты реализации:
ОбработкаПолученияФормы стандартная обработка отменяется (СтандартнаяОбработка = Ложь), а в качестве возвращаемой формы назначается форма универсальной внешней обработки. Эта форма полностью берет на себя логику отображения типовых полей объекта, работу с дополнительными реквизитами и запись документа через объектную модель.Оповестить и ОбработкаОповещения).