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