Механизм бизнес-событий в конфигурации «1С:Документооборот» (включая ДГУ) — это мощный инструмент для автоматизации процессов. Он позволяет гибко реагировать на создание, изменение или регистрацию документов, запуск задач и другие действия пользователей. Однако начинающие разработчики часто сталкиваются с ситуацией, когда написанный код в обработчике события попросту не выполняется, не выдавая при этом видимых ошибок в режиме предприятия. В этой статье мы подробно разберем, как устроен этот механизм изнутри, почему возникают неявные ошибки и как правильно отлаживать серверный код бизнес-событий. В качестве практического примера реализации логики можно использовать дополнительный обработчик для бизнес-события поступления входящей почты.
Первое, что нам необходимо понять — это асинхронный характер работы механизма бизнес-событий в «1С:Документооборот». В отличие от привычных подписок на события платформы 1С, которые выполняются в той же транзакции, что и запись объекта, бизнес-события работают через очередь.
Проанализируем этот процесс по шагам:
ПроизошедшиеБизнесСобытия со статусом «Не обработано» (флаг Обработано = Ложь). На этом транзакция пользователя завершается.Если в вашем обработчике происходит ошибка, пользователь этого не увидит, так как его сеанс уже завершен. Ошибка запишется в свойства самого события, а регламентное задание продолжит свою работу.
Рассмотрим код, который часто пытаются использовать для тестирования:
о = Событие.Источник.ПолучитьОбъект();
о.Заголовок = о.Заголовок + "_01";
о.Записать();
Выясним, почему этот код гарантированно приведет к зависанию системы и ошибкам в регистре. Вы вешаете этот обработчик на событие «Изменение документа». Внутри обработчика вы вызываете метод Записать().
Запись документа система расценивает как новое изменение документа. Детектор срабатывает снова и порождает новое бизнес-событие в очереди. При следующем запуске регламентного задания этот обработчик снова прочитает документ, снова изменит его заголовок, снова запишет его и породит очередное событие. Мы получаем бесконечную рекурсию!
Платформа 1С защищает базу данных от бесконечных циклов: транзакция откатывается, а в регистре Произошедшие бизнес-события для данной записи увеличивается счетчик ЧислоПопытокОбработки. После 3 неудачных попыток событие помечается флагом НеУдалосьОбработать и обработка останавливается.
Чтобы избежать рекурсии, всегда делайте проверку или отключайте регистрацию новых событий при записи:
ДокументОбъект = Событие.Источник.ПолучитьОбъект();
// Проверяем, не были ли символы уже добавлены ранее
Если Не (Прав(ДокументОбъект.Заголовок, 3) = "_01") Тогда
ДокументОбъект.Заголовок = ДокументОбъект.Заголовок + "_01";
// Отключаем детекторы событий для этой записи с помощью флага загрузки
ДокументОбъект.ОбменДанными.Загрузка = Истина;
ДокументОбъект.Записать();
КонецЕсли;
Использование свойства ОбменДанными.Загрузка = Истина временно блокирует работу бизнес-детекторов для выполняемой транзакции записи, предотвращая бесконечное зацикливание. Готовым примером автоматизации через бизнес-события служит обработчик для преобразования doc и docx в PDF при регистрации документов.
Еще одна частая ошибка кроется в типизации переменной Событие.Источник. В зависимости от того, на какое именно событие настроен ваш обработчик, источником может выступать совершенно разный тип данных. Например, при обработке процессов или задач источником будет являться задача (ЗадачаСсылка.ЗадачаИсполнителя), а не сам документ. Попытка напрямую прочитать реквизит Заголовок у задачи приведет к падению кода с ошибкой выполнения.
Всегда добавляйте проверку типа источника перед выполнением логики:
Если ТипЗнч(Событие.Источник) = Тип("СправочникСсылка.ВнутренниеДокументы") Тогда
// Здесь выполняем код, предназначенный исключительно для внутренних документов
КонецЕсли;
Поскольку обработка бизнес-событий происходит в фоновом задании, обычная точка останова в конфигураторе не сработает. Разберем по шагам, как настроить среду для полноценного тестирования и отладки.
Убедимся, что механизм бизнес-событий в принципе включен в базе данных. Перейдем в раздел Настройки -> Настройки программы -> Общие настройки и проверим, установлен ли флаг активности бизнес-событий. Также убедимся, что регламентное задание Обработка произошедших бизнес-событий включено и у него настроено расписание (например, запускаться каждую минуту).
Для диагностики перейдем непосредственно к регистру сведений. Через меню «Все функции» (или «Функции для технического специалиста») откроем регистр сведений Произошедшие бизнес-события (в некоторых версиях интерфейса этот список доступен через форму «История событий и задач»).
Обратим внимание на следующие поля записей:
Ложь, событие еще ждет запуска регламентного задания.Истина говорит о том, что при выполнении кода произошла критическая ошибка.Если в процессе разработки ваш код упал, и запись получила статус ошибки, нам нужно вернуть ее в очередь для повторного анализа. Найдем нужную строку в регистре Произошедшие бизнес-события и вручную отредактируем ее параметры:
Обработано в значение Ложь.Не удалось обработать в значение Ложь.Число попыток в значение 0.Чтобы отловить выполнение кода в момент запуска регламентного задания, выполним следующие действия:
БизнесСобытияВызовСервера (или аналогичный модуль обработки бизнес-событий в вашей версии ДГУ) и найдем процедуру ОбработкаПроизошедшихБизнесСобытий.Теперь вернемся в режим «1С:Предприятие» и с помощью обработки «Консоль регламентных заданий» найдем задание «Обработка произошедших бизнес-событий». Нажмем кнопку Выполнить сейчас. Платформа 1С автоматически подключится к запущенному фоновому процессу, и выполнение остановится на вашей точке останова в Конфигураторе. Теперь вы можете пошагово пройти весь алгоритм вашей обработки и локализовать ошибку!
Если интерактивная отладка фонового задания по каким-то причинам недоступна, отличным инструментом контроля станет запись информации в Журнал регистрации платформы. Вместо использования интерактивных методов вроде Сообщить(), которые вызывают падение фонового процесса, внедрим логирование непосредственно в код обработчика:
ЗаписьЖурналаРегистрации(
"МойОбработчикСобытий",
УровеньЖурналаРегистрации.Информация,
,
Событие.Источник,
"Успешный старт обработки. Источник: " + Строка(Событие.Источник)
);
После выполнения регламентного задания вы сможете открыть Журнал регистрации, отфильтровать записи по событию «МойОбработчикСобытий» и детально проанализировать ход выполнения вашего алгоритма.