При разработке расширений в платформе "1С:Предприятие 8.3" программисты часто сталкиваются с ситуацией, когда созданный метод с аннотацией &После (или &Перед) упорно отказывается вызываться. Вы ставите точку останова в расширении, запускаете отладку, оригинальный метод конфигурации успешно выполняется, а управление в вашу процедуру расширения так и не передается. При этом никаких явных ошибок система не выдает.
В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем внутренние механизмы работы платформы с расширениями и рассмотрим пошаговые инструкции по устранению подобных ошибок на примере реального кейса из конфигурации "Зарплата и управление персоналом" (ЗУП 3.1).
---
Это самая распространенная и неочевидная ошибка для начинающих разработчиков расширений. Платформа 1С предъявляет строжайшие требования к соответствию состава и количества параметров расширяющего и оригинального методов.
Проанализируем ситуацию на примере процедуры ПровестиПоУчетам модуля менеджера документа "Увольнение".
В основной конфигурации процедура объявлена следующим образом:
Процедура ПровестиПоУчетам(ДокументСсылка, РежимПроведения, Отказ, ВидыУчетов = Неопределено, Движения = Неопределено, Объект = Неопределено, ДополнительныеПараметры = Неопределено) Экспорт
// Оригинальная логика проведения...
КонецПроцедуры
Если мы напишем в модуле менеджера того же документа в расширении следующий код:
&После("ПровестиПоУчетам")
Процедура Тест() Экспорт
Сообщить("Проверка");
КонецПроцедуры
Платформа при компиляции модуля расширения сопоставит метод Тест() (у которого 0 параметров) с оригинальным методом ПровестиПоУчетам(...) (у которого 7 параметров). Обнаружив несовпадение сигнатур, система просто проигнорирует ваш расширяющий метод при выполнении. Точка останова в процедуре Тест() не сработает.
Чтобы платформа успешно вызвала ваш обработчик, сигнатура расширяющего метода должна полностью дублировать сигнатуру оригинального метода (за исключением значений по умолчанию, о которых мы поговорим ниже).
Правильный вариант объявления процедуры в расширении:
&После("ПровестиПоУчетам")
Процедура Тест(ДокументСсылка, РежимПроведения, Отказ, ВидыУчетов = Неопределено, Движения = Неопределено, Объект = Неопределено, ДополнительныеПараметры = Неопределено) Экспорт
Сообщить("Проверка");
КонецПроцедуры
Рассмотрим важные нюансы работы с параметрами в расширяющих методах:
= Неопределено) не обязательно. Платформа автоматически подставит их из описания оригинального метода. Однако для наглядности кода и исключения синтаксических предупреждений рекомендуется переносить их "как есть".Знач также должно строго соответствовать оригинальной сигнатуре. Если параметр в базовой конфигурации передается по значению, в расширении он тоже должен иметь директиву Знач.&Перед, оригинальном методе и &После связаны сквозным образом. Если оригинальный метод (или метод &Перед) в процессе своей работы изменит значение параметра (например, установит флаг Отказ = Истина), то в процедуру &После придет уже измененное значение этого параметра.---
Второй критически важный фактор — это "Безопасный режим" работы расширения. По умолчанию при установке нового расширения в информационную базу платформа автоматически включает для него безопасный режим.
Выясним, как безопасный режим влияет на исполнение кода:
ПровестиПоУчетам) выполняется строго на сервере, ваш обработчик &После в безопасном режиме гарантированно не будет вызван.Чтобы серверный код вашего расширения успешно компилировался и выполнялся, выполните следующие шаги:
В Конфигураторе состояние безопасного режима по умолчанию можно настроить в свойствах расширения (свойство "Безопасный режим"). При отладке на локальном компьютере рекомендуется всегда отключать это свойство.
---
Иногда разработчики переносят код из типовой конфигурации вместе с инструкциями препроцессора (директивами условной компиляции). Рассмотрим пример из темы обсуждения:
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
#Область ПрограммныйИнтерфейс
&После("ПровестиПоУчетам")
Процедура Тест() Экспорт
Сообщить("Проверка");
КонецПроцедуры
#КонецОбласти
#КонецЕсли
В расширениях конфигурации использование сложных конструкций #Если... Тогда в сочетании с аннотациями расширений не рекомендуется без крайней необходимости. Платформа самостоятельно определяет контекст компиляции расширяемого метода. Если оригинальный метод ПровестиПоУчетам находится в модуле менеджера (который компилируется только на сервере), то и расширяющий метод автоматически будет скомпилирован в соответствующем контексте.
Лишние условия препроцессора могут привести к тому, что при определенных типах соединения (например, через веб-клиент или внешнее соединение) ваш код просто исключится из компиляции, и вызов не произойдет. Оставьте в расширении чистый код без избыточных оберток условной компиляции.
---
Рассмотрим еще несколько важных нюансов поведения платформы, о которых необходимо помнить при проектировании доработок:
&Перед и &После можно применять исключительно к процедурам. Если вам необходимо расширить функцию, платформа выдаст ошибку компиляции. Для изменения поведения функций используйте аннотации &Вместо или &ИзменениеИКонтроль.Возврат (например, произошел досрочный выход из-за ошибки в данных), процедура расширения с аннотацией &После все равно будет выполнена. Платформа гарантирует вызов обработчика &После сразу после завершения работы основного метода, независимо от ветки алгоритма, по которой он завершился.&После, очередность их вызова определяется типом назначения расширения (Исправление -> Адаптация -> Дополнение) и порядком их расположения в списке установленных расширений.---
Если ваша процедура в расширении не работает, последовательно проверьте следующие пункты:
&После("ИмяПроцедуры") с оригинальным именем в основной конфигурации? Попробуйте нажать клавишу F12 на имени процедуры внутри аннотации — конфигуратор должен выполнить успешный переход к оригинальному коду.Экспорт)? Методы без ключевого слова Экспорт также подлежат расширению, но требуют внимательного контроля контекста вызова.Следуя этим правилам, вы гарантированно избежите проблем с "молчаливым" неисполнением кода расширений и сделаете процесс кастомизации ваших конфигураций быстрым и предсказуемым.