...

Доступ к контексту процесса

Тема в разделе "Вопросы по функционалу", создана пользователем inteco, 24 окт 2017.

  1. inteco

    inteco Member

    Добрый день, всем!

    Делаю выборку задач определенного пользователя. Выбираю только активные задачи. Проверяю название процесса, создавшего задачу.
    Нужно добраться до контекста процесса. Как это сделать?
    Код:
    var tasks = PublicAPI.Portal.TaskBase.Filter().Executor(context.Kaznachey).Statuses(TaskBaseExtensions.ActiveTaskStatuses.ToList()).Find(); //создаем список задач пользователя
    foreach (var task in tasks)
    {
    if(task.WorkflowBookmark.Instance.Process.Name=="Расход денег")
    {
    //Тут нужно из контекста процесса прочитать значения переменных
    task.WorkflowBookmark.Instance.Process.Context
    }
    }
    Как из контекста этого процесса прочитать значения его переменных?
    Если добавить .ИмяПеременной - ругается.
     
  2. pushkarev

    pushkarev Active Member

    Нужно объявить переменную контекста как динамическую, т.к. у каждого процесса свой тип данных для контекста. И снаружи неизвестно какой тип контекста используется.
    Рекомендую воспользоваться примером из базы знаний: https://www.elma-bpm.ru/kb/article-17.html
    Там разобрана аналогичная задача.
     
  3. inteco

    inteco Member

    Сделал так:
    dynamic parentContext = task.WorkflowBookmark.Instance.Process.Context;
    context.Vsego = parentContext.KVydache;
    ругается на вторую строку:
    Значение не может быть неопределенным. Имя параметра: property
    :(
     
  4. Riket Contraption

    Riket Contraption New Member

    какие типы у context.Vsego и parentContext.KVydache?
    Скорее всего, parentContext.KVydache nullable и имеет значение null.

    В таком случае необходимо добавить проверку:
    if (parentContext.KVydache == null)
    {
    context.Vsego = parentContext.KVydache;
    }
     
  5. inteco

    inteco Member

    у context.Vsego и parentContext.KVydache тип "Дробное число".
    и parentContext.KVydache не nullable и значение там 1000, когда я открываю задачу task (из первого поста)
    я вижу
    upload_2017-10-24_12-59-34.png
    и, если делать проверку, то наверно
    if (parentContext.KVydache <> null)
     
  6. Riket Contraption

    Riket Contraption New Member

    ой, прошу прощения, конечно "не равно" (!=)
     
  7. Riket Contraption

    Riket Contraption New Member

    И, мне кажется, ошибка ещё в том, что Вы обращаетесь к контексту процесса (task.WorkflowBookmark.Instance.Process.Context), а не к контексту экземпляра: task.WorkflowBookmark.Instance.Context
     
  8. inteco

    inteco Member

    Да! Именно!
    Так
    task.WorkflowBookmark.Instance.Context
    получилось, но прошу пояснить:
    У меня есть стартовый процесс "Аванс", а из него вызывается внешний процесс "Расход денег",
    внутри которого я собственно и получил задачу task.
    И если я спрашиваю task.WorkflowBookmark.Instance.Name то получаю "Аванс",
    а если task.WorkflowBookmark.Instance.Process.Name по получаю "Расход денег".
    Если я правильно понял, то не смотря на то что процессов ДВА, это "Аванс" и вызванный из него "Расход",
    а контекст у них один на всех? Общий?
     
  9. Riket Contraption

    Riket Contraption New Member

    Нет, так быть не может. Контексты у каждого процесса свои.

    Наименование процесса (оно задаётся в дизайнере при создании процесса) с наименованием его экземпляра (задаётся в дизайнере в меню "Настройки" - "Наименование экземпляров"), в принципе, никак не связаны.

    Посмотрите, как происходит наименование экземпляров у процесса "Расход денег", возможно там указан такой шаблон или входная переменная.
    Подробнее о наименовании процессов: https://www.elma-bpm.ru/kb/help/Platform/content/Designer_Name_scheme_index.html
     
  10. inteco

    inteco Member

    Всем спасибо за участие!
    Работает - и это главное!
     
  11. mkv

    mkv New Member

    Доброго дня!

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

    Соответственно, можно значения присваивать в Context.<property> - из внутреннего подпроцесса в родительский.
    По крайней мере, так решил свою задачу. В моем случае человек должен в подпроцессе (помимо основной задачи) проставить значения строк блока, чтобы потом посчитать остаток в другом ячейки строки, поэтому пришлось так поизвращаться.

    Может это некорректно, кто что скажет на этот счет? Я пробовал сначала по справке, то, что выше Алексей указал, но "что-то пошло не так" =)
     
  12. inteco

    inteco Member

    Нет, "Расход денег" это внешний подпроцесс.
    Скорее всего, если task принадлежит "Расход денег", то контекст его,
    как только выйдем из "Расход денег" и вернемся в "Аванс" и task будет принадлежать "Аванс",
    то контекст будет аванса, а контекст "Расход денег" будет недоступен.
    А вообще информационный голод в области C# for ELMA BPM у меня сильнейший.
    Свойства, методы объектов, типы возвращаемых значения, типы параметров
    да еще и с описанием и с примерами...
     
  13. svergay

    svergay New Member

    private dynamic LoadParentContext (int ParentInstance)
    {
    dynamic ParentInstanceContext = PublicAPI.Processes.WorkflowInstance.Find ("Id = " + ParentInstance).FirstOrDefault ().Context;
    return ParentInstanceContext;
    }

    dynamic parentContext = LoadParentContext (Convert.ToInt32(context.ParentInstance));
    int parentContext.ContextnajaPeremennaja ;

    Единственное что я не смог понять как изменять данные в процессе из которого мы вытаскиваем контекстные переменные тип int и datetime, тип string меняется на ура, в блок тоже добавлять получается, а вот увеличивать счетчик например, ругается:

    [System.ArgumentException: Expression of type 'System.Object' cannot be used for assignment to type 'System.Nullable`1[System.Int64]']
    at System.Linq.Expressions.Expression.Assign(Expression left, Expression right) at EleWise.ELMA.Model.Entities.Entity`1.ReflectionDynamicMetaObject.BindSetMember(SetMemberBinder binder, DynamicMetaObject value) at System.Dynamic.DynamicMetaObjectBinder.Bind(Object[] args, ReadOnlyCollection`1 parameters, LabelTarget returnLabel) at System.Runtime.CompilerServices.CallSiteBinder.BindCore[T](CallSite`1 site, Object[] args) at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1) at EleWise.ELMA.Model.Scripts.Approval_stage_1_Scripts.agreed(Approval_stage_1 context) in \ProcessScripts_daa64e4c967046efa28a67ed96bb98c9.cs:line 268

    Кто знает подскажите.

    parentContext.AllMatching -= 1; ругается на эту строку .
     
  14. pushkarev

    pushkarev Active Member

    Вы используете неявное преобразование типов и оператор -= не получится использовать с динамическими переменными, нужно явное преобразование. Для вашего случая код должен быть такой:
    Код:
    parentContext.AllMatching = ((long?)parentContext.AllMatching) - 1;
     
    1 это нравится
  15. svergay

    svergay New Member

    Спасибо, очень помогло, а как можно удалить строку блока родительского процесса
    foreach(var element in parentContext.WasAgreed)
    {
    if (element.Matching.Id == context.Add_Matching.Id)
    {
    element.Remove();
    }
    }
    так не работает
     
    Последнее редактирование: 8 фев 2018

Поделиться: