Разработка и Конфигурация · 11 мин
Когда выполняется подписка на событие в 1С
Когда выполняется подписка на событие в 1С: порядок вызова обработчиков, события записи и проведения, транзакции, типичные ошибки и проверка результата.
Подписка на событие в 1С — это механизм конфигуратора, который позволяет выполнить произвольный код в ответ на стандартные события объектов: запись, проведение, удаление, заполнение и другие. В отличие от обработчиков, встроенных в модуль самого объекта, подписка не требует изменения типового кода, поэтому её часто используют для доработок без снятия конфигурации с поддержки.
Ключевой вопрос, который возникает у разработчика, — в какой именно момент срабатывает подписка. Ответ зависит от выбранного события: одни обработчики вызываются до записи данных в базу, другие — внутри транзакции, третьи — после её завершения. Понимание этого порядка критично: ошибка в выборе события приводит к записи неактуальных данных, конфликтам транзакций или трудноуловимым сбоям.
Подписки создаются в конфигураторе в ветке «Общие» → «Подписки на события». Для каждой подписки указывается источник (типы объектов), событие и процедура-обработчик из общего модуля. Далее разберём, когда именно платформа вызывает эти обработчики и как выбрать правильное событие под конкретную задачу.
Общий принцип: в каком потоке выполняется подписка
Подписка на событие всегда выполняется синхронно — в том же сеансе и в том же потоке выполнения, где произошло событие. Если пользователь нажимает «Провести» в форме документа, все подписки на события проведения отработают до того, как управление вернётся в интерфейс. Пользователь будет ждать завершения всех обработчиков, поэтому тяжёлый код в подписке напрямую ухудшает отзывчивость системы.
Обработчики подписок вызываются после обработчиков, описанных в модуле самого объекта, либо в определённой последовательности относительно них — в зависимости от события. Если на одно и то же событие создано несколько подписок, платформа вызывает их все, но порядок вызова подписок между собой не гарантирован и не должен использоваться в логике.
Важно понимать: подписка срабатывает при любом способе возникновения события — интерактивная запись из формы, программная запись через метод Записать(), обмен данными, фоновое задание. Это и сила механизма, и источник рисков: обработчик, рассчитанный только на работу пользователя, может неожиданно сработать при загрузке данных.
События записи: ПередЗаписью, ПриЗаписи, ПослеЗаписи
Самая частая группа событий связана с записью объектов. Событие ПередЗаписью возникает до начала транзакции сохранения данных: объект ещё можно свободно изменить, отменить запись через параметр Отказ, проверить заполнение реквизитов. Это правильное место для контроля корректности данных и автозаполнения полей.
Событие ПриЗаписи выполняется уже внутри транзакции, после того как данные объекта физически записаны в базу, но до фиксации транзакции. Здесь принято записывать связанные данные: дополнительные сведения, записи регистров, связанные объекты. Всё, что сделано в этом обработчике, либо зафиксируется вместе с основной записью, либо откатится вместе с ней при ошибке.
Для некоторых типов объектов доступны события, выполняемые после завершения транзакции. Они подходят для действий, которые не должны блокировать основную запись: отправка уведомлений, запуск фоновых заданий, обращения к внешним системам. Длительные операции внутри транзакции записи удерживают блокировки и могут вызвать конфликты при параллельной работе пользователей.
Документы: проведение и его особенности
У документов помимо событий записи есть события проведения. ОбработкаПроведения выполняется внутри транзакции проведения и предназначена для формирования движений по регистрам. ОбработкаУдаленияПроведения вызывается при отмене проведения или перепроведении. Подписка на эти события позволяет добавить собственные движения к типовым, не меняя модуль документа.
События заполнения, копирования и удаления
Событие ОбработкаЗаполнения возникает при создании нового объекта — интерактивно или программно через метод заполнения. Подписка на него удобна для установки значений по умолчанию: организации, склада, ответственного. Обработчик получает данные заполнения и признак стандартной обработки, который можно отключить.
Событие ПриКопировании срабатывает, когда объект создаётся копированием существующего. Здесь обычно очищают поля, которые не должны переходить в копию: номера, даты документов-оснований, служебные признаки. Без такой обработки скопированный документ может утащить за собой устаревшие связи.
События удаления — ПередУдалением и ОбработкаУдаления — выполняются при интерактивном или программном удалении объекта. В них проверяют возможность удаления и очищают связанные данные. Учтите, что пометка удаления — это запись объекта с изменённым признаком, поэтому срабатывают события записи, а не удаления.
Подписки в обмене данными и фоновых заданиях
При обмене данными через планы обмена подписки на события записи срабатывают так же, как при обычной работе. Если обработчик не должен выполняться при загрузке, в коде проверяют признак ОбменДанными.Загрузка у объекта. Игнорирование этого признака — классическая причина дублирования движений и побочных эффектов при синхронизации баз.
Отдельная группа — события планов обмена, например ПриОтправкеДанных и ПриПолученииДанных. Они вызываются в момент формирования или чтения сообщения обмена и позволяют изменить выгружаемые данные или отказаться от приёма конкретного объекта. Эти подписки работают только в контексте обмена и не срабатывают при обычной записи.
Фоновые задания и регламентные операции также вызывают подписки, если в их коде происходит запись объектов. Обработчик, рассчитанный на интерактивный контекст (обращение к форме, модальные вызовы, предупреждения пользователю), в фоновом сеансе завершится ошибкой. Код подписок должен быть безопасен для серверного и фонового выполнения.
Как выбрать событие под конкретную задачу
Выбор события определяется тем, что должен делать обработчик. Нужно проверить или изменить данные до сохранения — берите «ПередЗаписью». Нужно записать связанные объекты атомарно с основным — «ПриЗаписи». Нужно добавить движения документа — «ОбработкаПроведения». Нужно отреагировать на факт записи без блокировки транзакции — события после записи или запуск фонового задания из обработчика.
Источник подписки стоит ограничивать минимально необходимым набором типов. Подписка на «все документы» будет вызываться при записи каждого документа в системе, и даже пустой обработчик добавляет накладные расходы. Если логика нужна для двух видов документов — укажите именно их.
Как выбрать событие
Типичные ошибки и проверка работы подписки
Самая распространённая ошибка — рекурсивный вызов: обработчик записи объекта записывает тот же объект, что снова вызывает подписку. Платформа отслеживает часть таких ситуаций, но надёжнее защищаться самостоятельно: проверять, изменились ли данные, использовать дополнительные свойства объекта для передачи признака «обработано» между вызовами.
Вторая частая проблема — подписка «не срабатывает». Причины обычно такие: обработчик размещён в общем модуле без нужных флагов (серверный вызов, привилегированный режим), в источнике не указан нужный тип объекта, запись выполняется в режиме загрузки, а обработчик не учитывает признак ОбменДанными.Загрузка, либо исключение в обработчике перехвачено выше по стеку.
Для диагностики используйте отладку с точкой останова в обработчике, запись в журнал регистрации и временные сообщения через Сообщить(). Проверяйте подписку во всех сценариях: интерактивная запись, программная запись, проведение, отмена проведения, обмен данными, фоновое задание.
Как проверить результат
Точка останова срабатывает при записи объекта нужного типа
Обработчик не вызывается — проверьте источник и флаги общего модуля
При загрузке данных логика пропускается или отрабатывает корректно
При синхронизации дублируются записи и движения
Запись объекта занимает примерно столько же времени, что и без подписки
Заметная задержка при каждой записи — обработчик перегружен
Исключение откатывает транзакцию целиком, данных-мусора нет
Часть связанных данных записалась, часть — нет
FAQ: частые вопросы о подписках на события
В каком порядке вызываются несколько подписок на одно событие?
Платформа гарантирует вызов всех подписок, но не фиксирует их порядок между собой. Если одна подписка зависит от результата другой, объедините логику в один обработчик или передавайте состояние через дополнительные свойства объекта.
Почему подписка не срабатывает при записи из фонового задания?
Чаще всего общий модуль с обработчиком не является серверным или вызов идёт в контексте, где модуль недоступен. Проверьте флаги «Сервер» и «Вызов сервера» у модуля и убедитесь, что обработчик не обращается к клиентским объектам вроде формы или предупреждений.
Можно ли из подписки отменить запись объекта?
Да, в событиях «ПередЗаписью» и «ОбработкаПроведения» параметр «Отказ» позволяет прервать операцию с откатом транзакции. В событии «ПриЗаписи» отмена также возможна — транзакция будет откачена целиком, включая уже записанные в ней данные.
Срабатывает ли подписка на запись при пометке удаления?
Да. Пометка удаления — это запись объекта с изменённым значением признака «ПометкаУдаления», поэтому вызываются события «ПередЗаписью» и «ПриЗаписи». События удаления срабатывают только при непосредственном удалении объекта из базы.
Чем подписка лучше изменения модуля объекта?
Подписка не требует правки типового модуля, поэтому упрощает обновление конфигурации на поддержке. Минус — логика разнесена по разным местам, её сложнее найти. Для глубокой переработки поведения объекта иногда честнее доработать модуль напрямую с корректным оформлением изменений.
Как временно отключить подписку без удаления?
Штатного флага отключения у подписки нет. Варианты: очистить обработчик в свойствах подписки, добавить в начало обработчика проверку функциональной опции или константы-переключателя, либо выгрузить изменение через расширение конфигурации, которое можно отключить целиком.
Что важно запомнить
Подписка на событие выполняется синхронно в момент наступления события: «ПередЗаписью» — до транзакции, «ПриЗаписи» и «ОбработкаПроведения» — внутри неё. Выбирайте событие по сути задачи, ограничивайте источник нужными типами, учитывайте режим загрузки при обмене и не размещайте длительные операции внутри транзакции записи.