Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Реализовать автоматическое выполнение задач для данного исполнителя
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 > Программисту > Программирование в 1С Предприятие 8.3
Vladal
Конфгурация на БСП 3.0.2, платформа 8.3.13.

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



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

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

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

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

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

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

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

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

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

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

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


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

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

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

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


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

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


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


Всё работает, все счастливы.
rpashkovsky
Vladal @ 17.04.19, 16:01 необходимо зарегистрироваться для просмотра ссылки ,
Прочитайте его перед записью, раз он у вас изменяется, сильно не вчитывался,
но логика следующая
Объект.ПРочитать();
Объект.Задача.ПолучитьОбъект().ВыполнитьЗадачу();

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

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

Задача решена двумя днями головоломок и 10 строками.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.