Почему не работает обработчик ПриСозданииНаСервереПосле в расширении 1С и как это исправить

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке в среде 1С:Предприятие 8.3 использование расширений стало стандартом де-факто. Однако механизмы расширения конфигурации таят в себе подводные камни, особенно когда речь идет о стандартных событиях формы, таких как ПриСозданииНаСервере. Рассмотрим ситуацию, когда добавленная процедура с аннотацией &После (After) упорно отказывается выполняться, несмотря на наличие корректной привязки в свойствах формы.

Разберем механизм цепочки вызовов

Для начала проанализируем, как платформа 1С обрабатывает расширяющие методы. Когда мы добавляем процедуру ПриСозданииНаСервереПосле, мы ожидаем, что она выполнится сразу после того, как отработает основной код типовой конфигурации. Но важно понимать, что если в системе установлено несколько расширений (включая автоматические исправления — патчи от 1С), порядок их выполнения критически важен.

Выясним причину возможного прерывания цепочки. Основная проблема часто кроется в использовании аннотации &Вместо (Instead) в другом расширении. Рассмотрим схему:

  1. Платформа собирает все расширения, где задействован метод ПриСозданииНаСервере.
  2. Если в одном из расширений (которое стоит выше в приоритете или является патчем) используется &Вместо, то выполнение типового кода полностью замещается кодом из этого расширения.
  3. Внимание: если внутри метода с аннотацией &Вместо не прописан метод ПродолжитьВызов(), то выполнение всех остальных расширений (и &Перед, и &После) блокируется.

Проанализируем влияние патчей и исправлений

Зачастую разработчик даже не подозревает, что в базе установлено расширение-исправление от вендора. Патчи от 1С — это такие же расширения. Если 1С выпустила исправление для конкретной формы документа, в котором процедура ПриСозданииНаСервере перекрыта через &Вместо, ваш код в пользовательском расширении перестанет вызываться.

Чтобы проверить это, выполним следующие шаги:

  1. Перейдем в список расширений конфигурации.
  2. Проверим наличие патчей (обычно они имеют префиксы типа EF_...).
  3. Временно отключим патчи и проверим работоспособность нашего кода.

Исследование проблемы "тройного вызова"

Иногда мы сталкиваемся с обратной ситуацией: код выполняется несколько раз или "перескакивает" из одного расширения в другое. Это происходит из-за того, что платформа пытается объединить вызовы. Если в одном расширении процедура привязана к событию формы, а в другом — просто объявлена с той же аннотацией, может возникнуть путаница в контекстах.

Посмотрим на пример из практики, когда стек вызовов показывает сложную структуру переходов между общими модулями расширения и модулем формы:


// В расширении Аренды
&После("ПриСозданииНаСервере")
Процедура ГУТА_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
    // Вызов общего модуля для модификации формы
    ГУТА_МодификацияКонфигурации.ПриСозданииНаСервереПосле(ЭтаФорма, Отказ, СтандартнаяОбработка);
КонецПроцедуры

Если в системе несколько таких расширений, и они используют схожие имена процедур, платформа может ошибочно интерпретировать вызовы. Рекомендуется всегда использовать уникальные префиксы для имен процедур в расширениях, чтобы избежать коллизий.

Рассмотрим решение через ПродолжитьВызов()

Если нам абсолютно необходимо использовать &Вместо, но мы не хотим "ломать" работу других расширений, мы обязаны использовать метод ПродолжитьВызов(). Это позволит платформе передать управление дальше по цепочке.

Проанализируем правильный пример реализации:


&Вместо("ПриСозданииНаСервере")
Процедура Моя_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Наш код, который должен выполниться ДО основного
    Сообщить("Выполняется предварительная логика расширения");
    
    // Передаем управление основному коду и другим расширениям (&После)
    ПродолжитьВызов(Отказ, СтандартнаяОбработка);
    
    // Наш код, который должен выполниться ПОСЛЕ основного
    Сообщить("Выполняется финальная логика расширения");
    
КонецПроцедуры

Как провести диагностику программно

Если визуальный осмотр расширений не помогает, воспользуемся замером производительности. Это самый надежный способ увидеть реальную картину исполнения кода.

  1. Включим замер производительности в конфигураторе.
  2. Откроем форму документа в режиме "Предприятие".
  3. Остановим замер и проанализируем дерево вызовов.
  4. Найдем процедуру ПриСозданииНаСервере. В замере будет четко видно, на каком расширении прерывается исполнение и заходит ли управление в ваш блок &После.

Также стоит обратить внимание на свойство формы "Состав" в расширении. Убедимся, что сама форма добавлена в расширение корректно. Иногда помогает удаление формы из расширения и ее повторное добавление с переносом обработчиков событий.

Подведем итоги

Проблема неработающего обработчика ПриСозданииНаСервереПосле в 90% случаев не является багом платформы, а является следствием архитектурного конфликта. Помните: любое расширение с аннотацией &Вместо без вызова ПродолжитьВызов() "убивает" все последующие расширения в очереди. Порядок расширений в списке (вверх/вниз) определяет эту очередь, и именно его нужно проверять в первую очередь при возникновении подобных проблем.

← На главную