Использование расширений конфигурации в платформе «1С:Предприятие 8» существенно упрощает процесс поддержки и обновления типовых решений. Однако при выпуске очередного релиза поставщика разработчики часто сталкиваются со следующей проблемой: стандартный инструмент сравнения и объединения в конфигураторе показывает только отличия основной конфигурации от новой конфигурации поставщика. При этом изменения в коде расширений, которые перехватывают или замещают типовые методы, остаются «невидимыми» для этого механизма.
Если вовремя не отследить изменения в исходном коде поставщика, переопределенные в расширении методы могут начать работать некорректно или полностью заблокировать запуск системы из-за несоответствия сигнатур. В этой статье мы подробно разберем, как решить проблему контроля изменений в расширениях при обновлении, какие современные инструменты предоставляет платформа 1С, а также как правильно организовать архитектуру кода, чтобы минимизировать риски.
Прежде чем перейти к методам решения, проанализируем первопричину проблемы. Наибольшую сложность при обновлении создают методы, переопределенные с помощью аннотации &Вместо. Когда разработчик полностью копирует код типового метода в расширение и модифицирует его, связь с оригинальным кодом поставщика теряется.
Если в новом релизе поставщик исправит критическую ошибку в этом методе или изменит его внутреннюю логику, конфигурация с расширением продолжит выполнять старый заимствованный код, который находится внутри расширения. Это приводит к скрытым логическим ошибкам, которые крайне тяжело локализовать на этапе тестирования.
Главное правило гигиены разработки: использование чистого замещения через &Вместо должно быть сведено к минимуму или полностью исключено.
---
Начиная с версии платформы 8.3.15, разработчикам доступен мощный инструмент автоматического контроля заимствованного кода — аннотация &ИзменениеИКонтроль. Это компромиссное и наиболее безопасное решение для модификации существующих методов.
Рассмотрим, как работает этот механизм. Вместо полного копирования метода мы заимствуем его с данной аннотацией и размечаем свои изменения специальными тегами компилятора: #Вставка, #КонецВставки, #Удаление и #КонецУдаления.
Посмотрим на пример применения директивы:
&ИзменениеИКонтроль("РассчитатьСкидку")
Процедура Расш1_РассчитатьСкидку(ДокументСсылка, СуммаДокумента)
// Исходный неизмененный код метода поставщика
СтандартныйПроцент = ПолучитьБазовыйПроцент();
//#Удаление
// Скидка = СуммаДокумента * (СтандартныйПроцент / 100);
//#КонецУдаления
//#Вставка
// Наша доработка: увеличиваем скидку для VIP-клиентов
Если ДокументСсылка.Контрагент.VIP Тогда
Скидка = СуммаДокумента * ((СтандартныйПроцент + 5) / 100);
Иначе
Скидка = СуммаДокумента * (СтандартныйПроцент / 100);
КонецЕсли;
//#КонецВставки
КонецПроцедуры
Как это помогает при обновлении? При попытке применить расширение после обновления конфигурации поставщика платформа автоматически проверяет, совпадает ли текст метода в расширении (без учета ваших вставок и удалений) с новым текстом метода в основной конфигурации. Если поставщик изменил этот метод, платформа выдаст ошибку применимости расширения.
Для разрешения этого конфликта выполним следующие шаги:
---
Если вам не требуется полностью переписывать алгоритм метода, а нужно лишь выполнить дополнительное действие до или после него, используйте директивы &Перед и &После с обязательным вызовом метода ПродолжитьВызов(). Это сохраняет целостность оригинального вызова.
Разберем пример правильного расширения метода, который гарантирует совместимость при обновлении:
&Вместо("ПередЗаписью")
Процедура Расш1_ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Выполняем действия ДО оригинального метода
Если Не ПроверитьЗаполнениеПолей() Тогда
Отказ = Истина;
Возврат;
КонецЕсли;
// Передаем управление оригинальному методу поставщика
ПродолжитьВызов(Отказ, РежимЗаписи, РежимПроведения);
// Выполняем действия ПОСЛЕ оригинального метода
ЗафиксироватьЛогСобытия();
КонецПроцедуры
Использование конструкции ПродолжитьВызов() гарантирует, что даже при изменении логики оригинального метода платформой 1С ваш код отработает корректно и не заблокирует выполнение базовых алгоритмов.
---
Для крупных проектов с большим количеством расширений классический конфигуратор становится менее эффективным. В этом случае целесообразно перевести разработку в среду 1C:EDT (Enterprise Development Tools).
В EDT работа с расширениями и основной конфигурацией выходит на принципиально иной уровень:
---
Для того чтобы не пропустить скрытые ошибки при обновлении, выработаем регламент проверки применимости расширений:
Конфигурация – Расширения конфигурации – Проверить возможность применения (или используйте групповую проверку для всех расширений сразу). Система выдаст список всех несовместимых объектов и методов.Для эффективного отслеживания изменений в расширениях при обновлениях 1С необходимо придерживаться комплексного подхода:
Внедрите в практику обязательное использование директивы &ИзменениеИКонтроль для точечных изменений кода. Полностью откажитесь от замещения кода через &Вместо без явной технологической необходимости, отдавая предпочтение связкам &Перед/&После и ПродолжитьВызов(). Для больших баз и командной разработки используйте среду 1C:EDT, которая берет на себя автоматическое сопоставление изменений через механизмы Git и встроенный статический анализатор кода.