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