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