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