С выходом механизма расширений в платформе 1С:Предприятие 8.3 жизнь разработчиков существенно упростилась. Однако при регулярном обновлении типовых конфигураций (например, 1С:Бухгалтерия, ERP или ЗУП) возникает серьезная проблема: как быстро и эффективно отслеживать изменения в процедурах и функциях, которые мы переопределили в расширении? Если типовой код изменился при обновлении, а наше расширение заменяет его «слепую», это неминуемо приведет к критическим ошибкам в логике программы.
В этой статье мы подробно разберем, как решить проблему сравнения кода в расширениях и конфигурациях. Мы проанализируем как классические обходные пути, предложенные участниками сообщества, так и современные системные механизмы, которые фирма «1С» добавила в платформу в последние годы.
Рассмотрим стандартную ситуацию. Разработчик заимствует процедуру из основной конфигурации в расширение с помощью директивы &Вместо, вносит туда несколько строк кастомной логики или комментирует часть типового алгоритма. При выходе очередного обновления конфигурации (например, Бухгалтерии предприятия) вендор полностью переписывает эту же процедуру — оптимизирует запросы, исправляет ошибки или добавляет новые реквизиты.
Поскольку в расширении метод перехвачен через &Вместо, программа будет выполнять исключительно код из расширения, полностью игнорируя новые типовые изменения. Нам необходимо сопоставить старый типовой код, новый типовой код и наш код в расширении. Как сделать это быстро, если таких процедур десятки или сотни?
Как справедливо заметили участники обсуждения, самый простой способ избежать проблем со сравнением кода при обновлениях — отказаться от агрессивного переопределения через &Вместо везде, где это возможно. Вместо этого рекомендуется использовать директивы &Перед и &После.
Если мы используем эти директивы, оригинальный код конфигурации выполняется полностью, а мы лишь дополняем его до или после. В этом случае обновление типового кода пройдет безболезненно, так как платформа сама выполнит актуальную версию типового метода.
Однако возникает резонный вопрос: как быть, если нам нужно переопределить функцию, которая возвращает значение, или модифицировать параметры «на лету»? В этом случае на помощь приходит директива &Вместо в сочетании со специальным методом ПродолжитьВызов().
Давайте разберем пример использования этого механизма:
&Вместо("РассчитатьСуммуДокумента")
Функция Расш1_РассчитатьСуммуДокумента(ПараметрыРасчета)
// Выполняем предварительные действия
ПараметрыРасчета.Вставить("ДополнительнаяСкидка", Истина);
// Вызываем оригинальный метод основной конфигурации
Результат = ПродолжитьВызов(ПараметрыРасчета);
// Корректируем возвращаемое значение без дублирования типового кода
Если Результат > 1000 Тогда
Результат = Результат - 50;
КонецЕсли;
Возврат Результат;
КонецФункции
При таком подходе мы не копируем тело типовой функции в расширение. Мы лишь перехватываем управление, изменяем входные параметры, вызываем оригинальный код через ПродолжитьВызов() и корректируем результат. При обновлении конфигурации тело функции РассчитатьСуммуДокумента обновится штатно, и нам не придется вручную переносить изменения в расширение.
Если код все же пришлось переопределить полностью (с удалением или полной заменой типовых строк), классическим (хотя и трудоемким) методом остается пофайловое сравнение. Рассмотрим этот алгоритм по шагам:
original_old.txt).extension.txt).original_new.txt).Безусловно, если измененных процедур больше сотни, этот процесс превращается в рутину и занимает огромное количество времени. Поэтому перейдем к более современным и автоматизированным методам.
Начиная с версии платформы 8.3.15, фирма «1С» внедрила революционную директиву &ИзменениеИКонтроль, которая призвана полностью решить проблему контроля применимости расширений. Это штатный и наиболее рекомендуемый инструмент на сегодняшний день.
При заимствовании метода с этой аннотацией платформа фиксирует структуру оригинального метода. Внутри кода расширения мы используем специальные инструкции препроцессора для указания изменений:
#Вставка ... #КонецВставки — для добавления нового кода.#Удаление ... #КонецУдаления — для исключения оригинального кода.Рассмотрим пример того, как выглядит процедура под контролем платформы:
&ИзменениеИКонтроль("СформироватьПечатнуюФорму")
Процедура СформироватьПечатнуюФорму(ДокументСсылка, ПараметрыПечати)
// Данный фрагмент кода остается без изменений
Макет = ПолучитьМакет("МакетПриходнойНакладной");
ТабДок = Новый ТабличныйДокумент;
#Удаление
// Этот код оригинальной конфигурации будет проигнорирован при выполнении
ЗаполнитьПараметрыПоУмолчанию(ПараметрыПечати);
#КонецУдаления
#Вставка
// Вставляем нашу собственную логику заполнения параметров
Расш1_ЗаполнитьПараметрыПользователя(ПараметрыПечати);
#КонецВставки
ТабДок.Вывести(Макет);
КонецПроцедуры
Почему это удобно при обновлении? Если в новой версии конфигурации вендор изменит строчку ЗаполнитьПараметрыПоУмолчанию(ПараметрыПечати), платформа сразу зафиксирует несоответствие шаблона. При проверке применимости расширений вы увидите ошибку. Вам больше не нужно гадать, где именно изменился код — платформа сама укажет на конкретный метод.
Если вы используете директиву &ИзменениеИКонтроль, вам больше не нужно вручную копировать тексты модулей. Платформа 1С поддерживает интеграцию с внешними инструментами трехстороннего слияния (3-way merge).
Давайте настроим этот механизм по шагам:
kdiff3.exe). Настройте шаблоны командной строки для сопоставления файлов.Платформа автоматически сформирует три файла: старый метод конфигурации (до обновления), новый метод конфигурации и ваш измененный метод из расширения. Внешняя программа визуально подсветит, какие именно строки изменил вендор, а какие — вы. Объединение изменений произойдет за считанные секунды в удобном графическом интерфейсе.
Если вы ведете разработку в современной среде 1С:EDT (Enterprise Development Tools), построенной на базе Eclipse, задача сравнения упрощается еще сильнее. Проекты конфигурации и расширений в EDT хранятся в виде файлов в системе контроля версий Git.
В EDT встроен мощный инструмент сравнения веток и истории коммитов. Вы можете в любой момент выполнить сравнение вашего проекта расширения с импортированной новой версией конфигурации. Среда наглядно покажет все расхождения в модулях на двух- или трехпанельном редакторе сравнения, позволяя переносить изменения простым перетаскиванием строк или использованием горячих клавиш.
Проблема сравнения процедур расширения и конфигурации за последние годы получила полноценное системное решение. Проанализировав все варианты, мы рекомендуем придерживаться следующих правил при доработке конфигураций:
&Перед и &После.&Вместо только для изменения параметров и постобработки результата через ПродолжитьВызов().&ИзменениеИКонтроль. Это заставит платформу автоматически контролировать целостность кода при каждом обновлении.