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