К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как создать подписку на событие в 1С

Как создать подписку на событие в 1С: пошаговая инструкция в конфигураторе, обработчики, примеры кода, типичные ошибки и проверка результата.

Подписка на событие в 1С — это механизм, который позволяет выполнять произвольный код при наступлении определённых событий объекта: записи документа, проведении, удалении элемента справочника и других. Вместо того чтобы править модуль объекта каждого документа, разработчик создаёт одну подписку, привязывает её к нужным типам объектов и выносит логику в общий модуль. Это снижает количество изменений в типовом коде конфигурации и упрощает обновление.

Механизм особенно полезен при доработке типовых конфигураций — «Управление торговлей», «Бухгалтерия предприятия», «ERP»: изменения в модулях объектов усложняют обновление, а подписки на события остаются практически нетронутыми. Именно поэтому подписки считаются стандартным приёмом аккуратной доработки.

Ниже разобрано, какие события доступны, как создать подписку в конфигураторе, как написать обработчик и проверить его работу, а также какие ошибки встречаются чаще всего.

Какие события доступны и когда какое выбирать

Набор событий зависит от типа объекта. Для документов и справочников чаще всего используются: Перед записью, При записи, Перед удалением, Обработка заполнения, Обработка проверки заполнения. Для документов дополнительно доступны Обработка проведения и Обработка удаления проведения.

Различие между «Перед записью» и «При записи» принципиально. «Перед записью» вызывается до обращения к базе данных — здесь удобно менять реквизиты объекта, проверять данные и отменять запись через параметр Отказ. «При записи» выполняется внутри транзакции записи: объект уже фактически записывается, поэтому событие подходит для регистрации связанных изменений, но изменять сам источник в нём поздно.

Для проведения документа подписка на «Обработку проведения» позволяет добавить собственные движения или проверки, не трогая модуль документа. Учтите: обработчики подписок выполняются после обработчиков самого объекта, поэтому подменить типовую логику через подписку нельзя — только дополнить её.

Создание подписки в конфигураторе пошагово

Откройте конфигуратор и в дереве конфигурации разверните ветку Общие → Подписки на события. Нажмите «Добавить» на панели инструментов или через контекстное меню. Откроется палитра свойств новой подписки.

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

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

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

Написание обработчика в общем модуле

Обработчик подписки — это экспортная процедура в общем модуле. Модуль должен быть серверным (флажок «Сервер»), а для событий записи и проведения обычно не требуется флажок «Вызов сервера». Рекомендуется создать отдельный общий модуль с говорящим именем, например «ПодпискиНаСобытияСервер», чтобы вся логика подписок была собрана в одном месте.

Сигнатура обработчика зависит от события. Для «Перед записью» процедура получает параметры Источник, Отказ, РежимЗаписи, РежимПроведения (для документов). Первый параметр — сам объект, через него доступны все реквизиты и табличные части.

bsl
Процедура ЗаполнениеОтветственногоПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
	Если Отказ Тогда
		Возврат;
	КонецЕсли;
	Если Не ЗначениеЗаполнено(Источник.Ответственный) Тогда
		Источник.Ответственный = ПользователиИнформационнойБазы.ТекущийПользователь().Имя;
	КонецЕсли;
КонецПроцедуры

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

Подписка на несколько типов объектов

Сила подписок — в возможности назначить один обработчик сразу на десятки типов. Например, подписка «Перед записью» на источник «ДокументОбъект» сработает для всех документов конфигурации. Внутри обработчика тип источника проверяется через ТипЗнч(Источник) или метод Метаданные().

Однако реквизиты у разных объектов различаются. Обращение Источник.Ответственный вызовет ошибку, если у какого-то документа из источника такого реквизита нет. Безопасный приём — проверять наличие реквизита через метаданные: Источник.Метаданные().Реквизиты.Найти("Ответственный") — и только потом обращаться к нему.

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

Подписка или модуль объекта

Подписка на событие

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

Код в модуле объекта

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

Расширение конфигурации

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

Проверка работы подписки

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

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

Контрольные точки

Как проверить результат

Обновление конфигурации БД
Норма

Конфигурация обновлена без ошибок, подписка видна в дереве

Тревожный признак

Подписка создана, но обновление не выполнялось — событие не срабатывает

Срабатывание обработчика
Норма

Точка останова в процедуре останавливает выполнение при записи объекта

Тревожный признак

Отладчик не заходит в процедуру — проверяйте источник, событие и контекст модуля

Результат в данных
Норма

Реквизит заполнен / связанная запись создана после записи объекта

Тревожный признак

Данные не меняются, хотя отладчик проходит обработчик — ошибка в логике кода

Типичные ошибки и ограничения

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

Вторая группа ошибок связана с транзакциями. Обработчик «При записи» выполняется внутри транзакции: вызов в нём методов, открывающих новую транзакцию или обращающихся к внешним ресурсам, может привести к конфликтам блокировок и откатам. Также помните, что при установке Отказ = Истина вся транзакция записи откатывается, включая изменения, сделанные другими подписками.

Третья типичная проблема — неявное изменение поведения обменов и загрузки данных. При загрузке через обмен у объекта обычно установлен ОбменДанными.Загрузка = Истина; если подписка не проверяет этот флаг, она будет срабатывать при каждой загрузке и может исказить приходящие данные. Добавляйте проверку Если Источник.ОбменДанными.Загрузка Тогда Возврат; там, где логика нужна только при интерактивной работе.

Типичные ошибки
01
Запись источника внутри обработчика «При записи» — рекурсивный вызов подписки и зависание сеанса
02
Обращение к реквизиту без проверки его наличия при источнике из нескольких типов — ошибка «Поле не обнаружено»
03
Отсутствие проверки ОбменДанными.Загрузка — подписка искажает данные при обмене
04
Тяжёлые запросы в цикле внутри обработчика — замедление записи документов для всех пользователей
05
Клиентский общий модуль для серверного события — подписка молча не срабатывает

Когда подписка не подходит: альтернативы

Подписка не может заменить штатный обработчик объекта — она лишь дополняет его. Если нужно изменить порядок проведения, отменить типовые движения или встроиться в середину логики документа, используйте расширение конфигурации с аннотациями «Вместо», «Перед», «После» либо доработку модуля объекта.

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

Маршрут решения

Как выбрать действие

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

FAQ

Почему подписка на событие не срабатывает?

Чаще всего не обновлена конфигурация базы данных после создания подписки, либо обработчик размещён в клиентском общем модуле, а событие серверное. Также проверьте, что тип тестируемого объекта включён в источник подписки и что событие выбрано корректно (например, «ПередЗаписью», а не «ПриЗаписи»).

Можно ли одной подпиской обработать все документы конфигурации?

Да, в свойстве «Источник» выберите тип «ДокументОбъект» — подписка будет срабатывать для всех документов. Внутри обработчика проверяйте наличие нужных реквизитов через метаданные, чтобы избежать ошибок у документов без этих реквизитов.

Чем «Перед записью» отличается от «При записи»?

«Перед записью» вызывается до обращения к базе данных и подходит для изменения реквизитов и валидации с возможностью отказа. «При записи» выполняется внутри транзакции записи, когда объект уже записывается, — там логично фиксировать связанные изменения, но менять сам объект поздно.

Как избежать зацикливания, если в обработчике нужно записать объект?

Используйте свойство ДополнительныеСвойства: перед повторной записью установите признак, например Источник.ДополнительныеСвойства.Вставить("ПропускПодписки", Истина), а в начале обработчика проверяйте его и завершайте выполнение. Это стандартный способ разорвать рекурсию.

Снимет ли конфигурацию с поддержки добавление подписки?

Добавление новых объектов метаданных (подписок, общих модулей) обычно меняет режим поддержки на «с изменениями», но не разрушает возможность обновления так, как это делает правка типовых модулей. Точный эффект зависит от настроек поддержки конкретной конфигурации — проверьте их перед изменениями.

Выполняется ли подписка при программной записи объекта?

Да. Подписка срабатывает при любом вызове записи объекта — интерактивном или программном, включая обмены данными. Чтобы исключить срабатывание при обмене, проверяйте в обработчике флаг Источник.ОбменДанными.Загрузка.

Итог

Что важно запомнить

Подписка на событие создаётся в ветке «Общие → Подписки на события»: источник, событие и обработчик в серверном общем модуле. Проверяйте флаг ОбменДанными.Загрузка, избегайте рекурсивной записи и тяжёлого кода в транзакции, а новую подписку сначала тестируйте на копии базы.