Как настроить подписку на событие в расширении конфигурации 1С и что делать на старых платформах?

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

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

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

Выясняем причину: ограничения версий платформы

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

  1. Платформы версий до 8.3.17 (включая 8.3.14, 8.3.15, 8.3.16): В этих релизах механизм подписок на события в расширениях не был реализован разработчиками платформы. Добавить новую подписку в расширение физически невозможно — данный пункт метаданных заблокирован для создания.
  2. Платформы версии 8.3.17 и выше: Начиная с этого релиза, фирма "1С" добавила полноценную поддержку собственных и заимствованных подписок на события внутри расширений.

Если вы вынуждены работать на старой версии платформы (например, 8.3.14, как автор вопроса), создавать стандартную подписку в расширении нельзя. В таком случае необходимо использовать альтернативный вариант — перехват событий через модули заимствованных объектов. Ниже мы детально разберем оба сценария.

Решение №1: Перехват событий через заимствование модуля объекта (для платформ ниже 8.3.17)

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

Разберем по шагам, как сделать это правильно, избежав распространенных ошибок синтаксиса:

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

Давайте проанализируем разницу между этими аннотациями:

Посмотрим на пример правильной реализации перехвата события проведения документа с помощью аннотации &После:


&После("ОбработкаПроведения")
Процедура Расш1_ОбработкаПроведения(Отказ, РежимПроведения)
    
    // Переменная "ЭтотОбъект" доступна внутри контекста модуля объекта расширения
    НомерДокумента = ЭтотОбъект.Номер;
    ДатаДокумента = ЭтотОбъект.Дата;
    
    // Пример вывода сообщения пользователю
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = "Регистрация проведения документа № " + НомерДокумента + " от " + ДатаДокумента;
    Сообщение.Сообщить();
    
КонецПроцедуры

Важный нюанс: Обратите внимание, что имя процедуры в расширении должно отличаться от оригинального (например, иметь префикс вашего расширения Расш1_ОбработкаПроведения), а список входящих параметров (в данном случае Отказ и РежимПроведения) должен строго и в точности соответствовать оригинальной процедуре в основной конфигурации. Если вы ошибетесь в количестве или названиях параметров, платформа выдаст ошибку времени выполнения. Для выявления подобных проблем в коде можно использовать инструмент для анализа расширений на наличие ошибок в вызовах и сигнатурах.

Анализ ошибки из сообщения №7

Давайте разберем, почему у автора вопроса в сообщении №7 не сработал код. Автор попытался написать процедуру следующим образом:


&После("ОбработкаПроведения")
Процедура ОбработкаПроведения_Своя()
    ...
КонецПроцедуры

Эта процедура не выполнилась по двум ключевым причинам:

  1. Неверная сигнатура (состав параметров): Оригинальная процедура ОбработкаПроведения в модуле любого документа 1С всегда принимает два обязательных параметра: Отказ (тип Булево) и РежимПроведения (тип РежимПроведенияДокумента). Автор объявил процедуру без параметров. Платформа не смогла сопоставить вызов и проигнорировала данный обработчик.
  2. Ручной ввод вместо автоматической генерации: При ручном написании кода легко ошибиться в регистре букв или имени аннотации. Всегда используйте контекстное меню конфигуратора для добавления обработчиков событий в расширение.

Решение №2: Использование подписок на события (для платформ 8.3.17 и выше)

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

Сценарий А: Создание абсолютно новой подписки в расширении

Вы можете создать собственную подписку, которая будет реагировать как на объекты из расширения, так и на заимствованные объекты основной конфигурации. Выполните следующие действия:

  1. В дереве метаданных вашего расширения перейдите в ветку Общие -> Подписки на события и нажмите кнопку Добавить.
  2. В свойствах подписки укажите имя, выберите интересующее вас событие (например, ПередЗаписью, ПриЗаписи или ОбработкаПроведения).
  3. В поле Источник выберите объект, событие которого вы хотите перехватить. Начиная с версии 8.3.17, здесь можно выбирать заимствованные в расширение документы и справочники.
  4. В поле Обработчик укажите процедуру из общего модуля, который также создан внутри вашего расширения. Обратите внимание, что у этого общего модуля должны стоять флажки Клиент (серверный вызов) и Сервер в зависимости от контекста выполнения события.

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

Сценарий Б: Заимствование существующей подписки из основной конфигурации

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

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

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

Сравнение подходов: Перехват в модуле объекта VS Подписка на события

Проанализируем преимущества и недостатки обоих методов, чтобы вы могли выбрать наиболее архитектурно правильный подход для своего проекта:

Критерий сравнения Перехват через модуль объекта (&После, &Перед) Собственная подписка на событие в расширении
Поддерживаемые версии платформы Любые версии (начиная с появления расширений в 8.3.6) Только платформы версии 8.3.17 и выше
Групповая обработка объектов Неудобно. Приходится заимствовать модуль каждого объекта отдельно и дублировать вызовы. Удобно. Можно подписаться на обобщенный тип (например, ДокументОбъект) для всей базы.
Удобство отладки и чтения кода Высокое. Разработчик сразу видит перехваченный метод в модуле конкретного объекта. Среднее. Код обработчика вынесен в отдельный общий модуль, требуется дополнительный поиск связи.
Производительность Высокая. Прямой вызов методов платформой без дополнительных проверок условий. Высокая, однако при некорректно настроенных обобщенных типах источников может создавать небольшую нагрузку.

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

← На главную