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