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