Почему не сохраняется задача при выполнении бизнес-процесса в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Разберем распространенную ситуацию при разработке бизнес-процессов в платформе 1С:Предприятие. В процессе выполнения маршрута программно создается задача, заполняются ее реквизиты, вызывается метод записи, и в отладчике объект успешно фиксируется. Однако после завершения работы процедуры или шага бизнес-процесса созданная задача бесследно исчезает из базы данных.

Проанализируем причины такого поведения платформы и выясним, как правильно выстраивать логику маршрутизации для создания задач-напоминаний и вложенных процессов.

Анализ проблемы: почему задача исчезает после отладчика

Если объект успешно записывается в режиме отладки, но отсутствует в информационной базе после завершения системного события, это однозначно указывает на неявный откат транзакции. В механизме бизнес-процессов 1С продвижение по карте маршрута и генерация сопутствующих объектов всегда выполняются в рамках единой системной транзакции.

В рассматриваемом случае разработчик пытается создать задачу в модуле бизнес-процесса внутри обработчика точки вложенного процесса:


Процедура ВложенныйПроцесс1ПередСозданиемВложенныхБизнесПроцессов(ТочкаМаршрутаБизнесПроцесса, ФормируемыеБизнесПроцессы, Отказ)
    // Попытка создания задачи вручную
    Задача = Задачи.ЗадачаИсполнителя.СоздатьЗадачу();
    Задача.Дата = ТекущаяДата();
    Задача.Автор = ОбщегоНазначенияСервер.ТекущийПользователь();
    Задача.ДатаИсполнения = НачалоДня(ВыборкаДетальныеЗаписи.ДатаДействия);
    Задача.Предмет = Клиент;
    Задача.БизнесПроцесс = Ссылка;
    Задача.ТочкаМаршрута = ТочкаМаршрутаБизнесПроцесса;
    Задача.РольИсполнителя = РольИсполнителя;
    Задача.Записать();
КонецПроцедуры

Такой подход приводит к конфликту с внутренней архитектурой платформы по следующим причинам:

  1. Ошибочное понимание параметров обработчика. Сигнатура события точки вложенного процесса имеет вид ПередСозданиемВложенныхБизнесПроцессов(ТочкаМаршрутаБизнесПроцесса, ФормируемыеБизнесПроцессы, Отказ). В ней нет параметра СтандартнаяОбработка. Попытка управлять формированием задач через этот флаг не имеет смысла.
  2. Специфика точки «Вложенный бизнес-процесс». Данная точка на карте маршрута не предназначена для выдачи произвольных пользовательских задач. Задача, привязанная к этой точке реквизитом ТочкаМаршрута, обязана выступать в качестве ВедущаяЗадача для запускаемого подчиненного процесса.
  3. Нарушение условий продвижения по маршруту. Точка вложенного процесса ожидает создания подчиненных процессов и добавления их в массив ФормируемыеБизнесПроцессы. Продвижение родительского процесса дальше происходит только после завершения этих вложенных процессов. Если массив остался пустым, а задача создана вручную с привязкой к этой точке, платформа сталкивается с противоречием маршрутизации и откатывает всю транзакцию шага.

Способ 1. Разделение веток на карте маршрута через точку «Условие»

Рассмотрим наиболее надежный и архитектурно правильный способ реализации ветвления, когда при определенных условиях требуется запустить дочерний процесс, а при их отсутствии — отправить задачу-напоминание пользователю.

Разберем реализацию по шагам:

  1. Откроем карту маршрута бизнес-процесса. Перед точкой запуска вложенного процесса разместим точку маршрута типа Условие.
  2. В обработчике проверки условия опишем проверку необходимых данных:
    
    Процедура ПроверкаУсловия1ПроверкаУсловия(ТочкаМаршрутаБизнесПроцесса, Результат)
        Если НеобходимостьСозданияВложенногоПроцесса() Тогда
            Результат = Истина;
        Иначе
            Результат = Ложь;
        КонецЕсли;
    КонецПроцедуры
    
  3. Ветку Истина соединим с точкой типа Вложенный бизнес-процесс. В ее обработчике сформируем требуемые бизнес-процессы и передадим их в системную коллекцию ФормируемыеБизнесПроцессы без ручного вызова записи.
  4. Ветку Ложь направим на штатную точку маршрута Действие, где должна формироваться задача-уведомление.
  5. В обработчике точки действия используем событие ПередСозданиемЗадач. Для программного добавления задачи поместим ее в системный массив ФормируемыеЗадачи:
    
    Процедура НапоминаниеПередСозданиемЗадач(ТочкаМаршрутаБизнесПроцесса, ФормируемыеЗадачи, СтандартнаяОбработка)
        СтандартнаяОбработка = Ложь;
        
        НоваяЗадача = Задачи.ЗадачаИсполнителя.СоздатьЗадачу();
        НоваяЗадача.БизнесПроцесс = Ссылка;
        НоваяЗадача.ТочкаМаршрута = ТочкаМаршрутаБизнесПроцесса;
        НоваяЗадача.Дата = ТекущаяДата();
        НоваяЗадача.Автор = ОбщегоНазначенияСервер.ТекущийПользователь();
        НоваяЗадача.Предмет = Клиент;
        НоваяЗадача.РольИсполнителя = РольИсполнителя;
        
        // Передаем задачу платформе — метод Записать() вызывать не нужно!
        ФормируемыеЗадачи.Добавить(НоваяЗадача);
    КонецПроцедуры
    

При таком подходе платформа сама корректно запишет объект задачи в базу данных и будет ожидать ее выполнения для дальнейшего перехода по схеме.

Способ 2. Создание независимой задачи без привязки к точке маршрута

Если задача носит исключительно информационный характер (уведомление, напоминание) и не должна останавливать ход текущего бизнес-процесса, ее нельзя привязывать к точке маршрута бизнес-процесса.

Посмотрим на пример правильного заполнения реквизитов независимой задачи:


Задача = Задачи.ЗадачаИсполнителя.СоздатьЗадачу();
Задача.Дата = ТекущаяДата();
Задача.Автор = ОбщегоНазначенияСервер.ТекущийПользователь();
Задача.ДатаИсполнения = НачалоДня(ВыборкаДетальныеЗаписи.ДатаДействия);
Задача.Предмет = Клиент;
// Связываем с процессом для истории, но НЕ заполняем реквизит ТочкаМаршрута
Задача.БизнесПроцесс = Ссылка;
Задача.РольИсполнителя = РольИсполнителя;
Задача.Записать();

Обратите внимание: свойство Задача.ТочкаМаршрута остается пустым. В этом случае задача сохраняется как самостоятельный документ-задание, а родительский бизнес-процесс беспрепятственно продолжает движение по своей карте маршрута.

Способ 3. Программный пропуск точки вложенного процесса

Если архитектура конфигурации требует оставить генерацию условий внутри одной точки карты, выясним, как правильно отказаться от создания подпроцессов без сбоя транзакции.

Для пропуска точки вложенного процесса необходимо в обработчике ПередСозданиемЗадач этой точки отключить формирование ведущих задач:


Процедура ВложенныйПроцесс1ПередСозданиемЗадач(ТочкаМаршрутаБизнесПроцесса, ФормируемыеЗадачи, СтандартнаяОбработка)
    Если Не НужноСоздаватьПодпроцессы Тогда
        // Отменяем стандартное создание ведущей задачи
        СтандартнаяОбработка = Ложь;
        // Коллекция ФормируемыеЗадачи остается пустой
    КонецЕсли;
КонецПроцедуры

Если ведущая задача для вложенного процесса не была сгенерирована, платформа не ожидает завершения дочернего маршрута и сразу передает управление следующей точке карты, не вызывая аварийного отката транзакции.

← На главную