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