Open Documentation Menu

Changing process variables in a multi-instance

Within subprocesses configured as multi-instances, changing process variables is initially only possible within the scope of the current subprocess instance.

The following example process shows a process in which a user task is assigned to each of a group of recipients (variable allAssignees). For this purpose, a multi-instance is used. For the user task, each user should insert a variable decision, for example with a form. Since each subprocess instance has its own scope of variables, it is currently not possible to summarize all entered values in decision of all recipients.

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" targetNamespace="" exporter="d.velop process modeler">
  <process id="writeMultiInstanceVariables" name="WriteMultiInstanceVariables" isExecutable="true">
    <extensionElements>
      <camunda:properties>
        <camunda:property name="variable:allAssignees*" value="[Identity]!" />
        <camunda:property name="variable:assignee" value="Identity" />
        <camunda:property name="variable:allDecisions" value="[String]" /> 
        <camunda:property name="variable:decision" value="String" />       
          </camunda:properties>
    </extensionElements>
    <startEvent id="start" />
    <endEvent id="end" />
    <sequenceFlow id="s1" sourceRef="start" targetRef="subflow" />
    <subProcess id="subflow">    
      <multiInstanceLoopCharacteristics camunda:collection="${variables.get('assignees')}" camunda:elementVariable="assignee" />
      <startEvent id="subflow_start" />
      <sequenceFlow id="s2-1" sourceRef="subflow_start" targetRef="subflow_usertask" />
      <endEvent id="subflow_end" />
      <sequenceFlow id="s2-2" sourceRef="subflow_usertask" targetRef="subflow_end" />
      <userTask id="subflow_usertask" name="Decision" camunda:candidateUsers="${variables.get('assignee')}" />
    </subProcess>
    <sequenceFlow id="s3" sourceRef="subflow" targetRef="end" />
  </process>
</definitions>

In order to write process variables from the scope of the multi-instance into the scope of the entire process, you need to add a step of the type bpmn:serviceTask to the subprocess.

...
 <subProcess id="subflow">
   ...
   <sequenceFlow id="s2-3" sourceRef="writeDecision" targetRef="subflow_end" />
   <serviceTask id="writeDecision" name="Write decision to global scope" camunda:asyncBefore="true" camunda:asyncAfter="true" camunda:delegateExpression="${writeMultiInstanceVariables}">
     <extensionElements>
       ...
       <camunda:inputOutput>
         <camunda:inputParameter name="allDecisions">${variables.get('decision')}</camunda:inputParameter>
       </camunda:inputOutput>
     </extensionElements>
   </serviceTask>
</subProcess>
...

Explanation of the properties

  • id: The property is used as a unique identifier for the send activity.

  • name: This property is used as a display name in the user interfaces.

  • camunda:*: These properties contain technical information required for the execution. For steps to write variables from a multi-instance into the process, you always need to enter the values of the example for these properties.

In the camunda:inputOutput area, you must now define an element of the type camunda:inputParameter for each variable for which you want to insert a value in the scope of the process. The property name must correspond to the process variable into which you want to write. The content of this element defines the value that is written. You can also access variables (of the scope of the multi-instance or of the entire process).

Process variables which are written that way must always be of the type Multi-value. The index to which an instance of the multi-instance subprocess writes is determined by the automatically assigned value of the loopCounter variable.

Note

allAssignees has the values ['user1', 'user2', 'user3']. This results in three instances of the multi-instance subprocess with the following variables (relevant here):

Instance 1:

assignee: 'user1'

loopCounter: 0

Instance 2:

assignee: 'user2'

loopCounter: 1

Instance 3:

assignee: 'user3'

loopCounter: 2

If user2 would finish the user task in instance 2 with the value 'myDecision' for decision and would write the variable allDecisions in the following step, the variable would have the following values:

allDecisions: [null, 'myDecision', null]

In order for the BPMN diagram to be displayed correctly in the modeling tool as well as the user interface, diagram information has been added. The final BPMN definition looks as follows:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI"  xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" targetNamespace="" exporter="d.velop process modeler">
 <process id="writeMultiInstanceVariables" name="WriteMultiInstanceVariables" isExecutable="true">
    <extensionElements>
      <camunda:properties>
        <camunda:property name="variable:allAssignees*" value="[Identity]!" />
        <camunda:property name="variable:assignee" value="Identity" />
        <camunda:property name="variable:decision" value="String" />
        <camunda:property name="variable:allDecisions" value="[String]" />
      </camunda:properties>
    </extensionElements>
    <startEvent id="start" />
    <endEvent id="end" />
    <sequenceFlow id="s1" sourceRef="start" targetRef="subflow" />
    <subProcess id="subflow">
      <multiInstanceLoopCharacteristics camunda:collection="${variables.get('allAssignees')}" camunda:elementVariable="assignee" />
      <startEvent id="subflow_start" />
      <sequenceFlow id="s2-1" sourceRef="subflow_start" targetRef="subflow_usertask" />
      <endEvent id="subflow_end" />
      <sequenceFlow id="s2-2" sourceRef="subflow_usertask" targetRef="writeDecision" />
      <userTask id="subflow_usertask" name="Decision" camunda:candidateUsers="${variables.get('assignee')}" />
      <sequenceFlow id="s2-3" sourceRef="writeDecision" targetRef="subflow_end" />
      <serviceTask id="writeDecision" name="Write decision to global scope" camunda:asyncBefore="true" camunda:asyncAfter="true" camunda:delegateExpression="${writeMultiInstanceVariables}">
        <extensionElements>
          <camunda:failedJobRetryTimeCycle>R3/PT5M</camunda:failedJobRetryTimeCycle>
          <camunda:inputOutput>
            <camunda:inputParameter name="allDecisions">${variables.get('decision')}</camunda:inputParameter>
          </camunda:inputOutput>
        </extensionElements>
      </serviceTask>
    </subProcess>
    <sequenceFlow id="s3" sourceRef="subflow" targetRef="end" />
  </process>

  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="writeMultiInstanceVariables">
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="start">
        <dc:Bounds x="179" y="159" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_0ssel47_di" bpmnElement="end">
        <dc:Bounds x="912" y="159" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_0li7yi3_di" bpmnElement="subflow" isExpanded="true">
        <dc:Bounds x="300" y="77" width="490" height="200" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_0ybst54_di" bpmnElement="subflow_start">
        <dc:Bounds x="340" y="159" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_0f9450b_di" bpmnElement="subflow_end">
        <dc:Bounds x="712" y="159" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_1qx66xt_di" bpmnElement="subflow_usertask">
        <dc:Bounds x="430" y="137" width="100" height="80" />
        <bpmndi:BPMNLabel />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_13t76uu_di" bpmnElement="writeDecision">
        <dc:Bounds x="570" y="137" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="Flow_146y71c_di" bpmnElement="s2-1">
        <di:waypoint x="376" y="177" />
        <di:waypoint x="430" y="177" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_1yq9qcz_di" bpmnElement="s2-2">
        <di:waypoint x="530" y="177" />
        <di:waypoint x="570" y="177" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_1huut97_di" bpmnElement="s2-3">
        <di:waypoint x="670" y="177" />
        <di:waypoint x="712" y="177" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_1o99dar_di" bpmnElement="s1">
        <di:waypoint x="215" y="177" />
        <di:waypoint x="300" y="177" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_13w0opv_di" bpmnElement="s3">
        <di:waypoint x="790" y="177" />
        <di:waypoint x="912" y="177" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>