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