Версия для печати темы (https://pro1c.org.ua/index.php?s=7d5844a01b0d7702480663b075f6ceab&showtopic=51560)

Нажмите сюда для просмотра этой темы в обычном формате

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 _ Программирование в 1С Предприятие 8.3 _ Реализовать автоматическое выполнение задач для данного исполнителя

Автор: Vladal 16.04.19, 12:55

Конфгурация на БСП 3.0.2, платформа 8.3.13.

Есть бизнес-процесс с "линейной" картой.



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

Что есть: при интерактивном закрытии задачи формируется следующая, в которую нужно зайти и нажать кнопку Согласовать, и так три раза (на карте три последние точки маршрута).
Что я дописал:

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

Цитата
Операция не может быть выполнена из-за несоответствия версии или отсутствия записи базы данных (возможно, запись была изменена или удалена)!

Естественно, ссылка одна и та же, да и открыта интерактивно.

Делал это программно. Получил ссылку на текущую задачу, вызвал метод ВыполнитьЗадачу(), в отладчике прослеживаю все этапы и на последнем шаге получаю ошибку о невозможности закрыть задачу, так как она уже была выполнена.

Как это сделать правильно?

В обработчике точки маршрута ВыполнитьПриСозданииЗадач пишу свой код:
////////////////////////////////////////////////////////////////////////////////
// Обработчики событий элементов карты маршрута.

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

        // Определить. был ли этот исполнитель в предыдущих точках маршрута
        Запрос = Новый Запрос;
        Запрос.Текст =
        "ВЫБРАТЬ РАЗРЕШЕННЫЕ
        |    ЗадачаИсполнителя.Ссылка КАК Ссылка,
        |    ЗадачаИсполнителя.БизнесПроцесс КАК БизнесПроцесс,
        |    ЗадачаИсполнителя.Выполнена КАК Выполнена,
        |    ЗадачаИсполнителя.ГруппаИсполнителейЗадач КАК ГруппаИсполнителейЗадач,
        
...

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

Автор: Vladal 16.04.19, 18:51

Сделал эксперимент. В пустой конфе создал БП и Задачу, в карте маршрута добавил несколько пунктов линейно, в обработчик записал такой код:

Процедура ПриСозданииЗадач(ТочкаМаршрутаБизнесПроцесса, ФормируемыеЗадачи, Отказ)
    ФормируемыеЗадачи[0].Записать();
    ФормируемыеЗадачи[0].ВыполнитьЗадачу();
КонецПроцедуры


БП стартует, создает столько же задач, сколько в карте, и закрывается с выполнением.

Сферический конь в вакууме не привел к ошибке.
Единственное, что если создать БП и в форме только что созданного объекта
Что делать?

Автор: Vladal 17.04.19, 16:01

Будет хорошим тоном написать, как я решил эту проблему.

В пустой базе "сферический конь в вакууме" работает так, как мне надо, значит я на верном пути.
В рабочей конфе тоже все отрабатывает, если закрывать задачу непосредственно самой задачей
Задача.ВыполнитьЗадачу(); вместо вызова модуля БизнесПроцессыИЗадачиВызовСервера.ВыполнитьЗадачу(Задача.Ссылка, Истина);.
Но при этом все равно валилась ошибка об измененном объекте и несоответствии версий.
Попробовал записывать задачу перед закрытием, ожидаемого эффекта не было, ошибка осталась, зато отладчик Задача.Ссылка.УникальныйИдентификатор() показывал, что создаются разные задачи и к ним потом рекурсивно обращается метод ВыполнитьЗадачу().

Ок.
Но при выходе из каждой итерации рекурсии каждая из задач оказывалась с признаком Выполнена, и соответственно в модуле самой задачи не проходила проверку по условию:

...
ИначеЕсли НЕ ПометкаУдаления И ИсходныеРеквизиты.Выполнена И Выполнена Тогда
    ОбщегоНазначения.СообщитьПользователю(
        НСтр("ru='Эта задача уже была выполнена ранее.';en='This task has already been done earlier.'"),,,, Отказ);
    Возврат;
КонецЕсли;


Нужен был какой-то признак для игнора этой проверки. Добавил свойство Автозакрытие в ДополнительныеСвойства и всё получилось!

В бизнес-процессе после определения, что задача должна закрыться автоматически, добавляю в объект признак Автозакрытие:
Результат = Запрос.Выполнить();
Если Не Результат.Пустой() Тогда
    Если Не Задача.Выполнена Тогда
        Задача.ДополнительныеСвойства.Вставить("Автозакрытие", Истина);
        Задача.ВыполнитьЗадачу();
    КонецЕсли;
КонецЕсли;


А в модуле задачи ПередЗаписью читаю, есть ли этот признак и вызываю проверку:
ИначеЕсли НЕ ПометкаУдаления И ИсходныеРеквизиты.Выполнена И Выполнена 
    И НЕ ЭтоАвтоЗакрытие Тогда                                          // При автозакрытии из БП не проводить эту проверку
    ОбщегоНазначения.СообщитьПользователю(
        НСтр("ru='Эта задача уже была выполнена ранее.';en='This task has already been done earlier.'"),,,, Отказ);
    Возврат;
КонецЕсли;


Всё работает, все счастливы.

Автор: rpashkovsky 21.04.19, 18:15

Vladal @ 17.04.19, 16:01 * ,
Прочитайте его перед записью, раз он у вас изменяется, сильно не вчитывался,
но логика следующая

Объект.ПРочитать();
Объект.Задача.ПолучитьОбъект().ВыполнитьЗадачу();

Под объектом имею в виду сам БП

Автор: Vladal 22.04.19, 8:39

rpashkovsky @ Вчера, 19:15 * ,
Как раз с БП всё в порядке. после записи задачи назначается оповещение при котором его объект перечитывается в форме.

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

Задача решена двумя днями головоломок и 10 строками.

Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7
https://pro1c.org.ua