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