QlikView Expressor: Using the Multi-Transform Operator

    Introduced in QlikView Expressor 3.9 is the Multi-Transform operator, a member of the Transformers operator grouping.  This operator provides functionality equivalent to a Copy operator or Filter operator where a Transform operator is connected to each of these operators' output ports.  The advantages to using the Multi-Transform operator are that your dataflow will be less crowded and exeuction can be more efficient.  However, the ability to use this operator to its fullest functionality requires a higher skill level with Expressor Datascript, including an understanding of how to use an iterator return function.


    When you first open this operator's Rules Editor you will see two or more (up to 10) output ports each representing an output record with the same attributes as the input record.  In this state, the operator will simply copy the attribute values from the input record to the multiple output records.  That is, the operator functions as a Copy operator.  There's really no reason to employe the Multi-Transform operator in this way as Expressor already has a Copy operator.  So the next step would be to define the various transformations you want the operator to perform.


    As an example, let's configure the Multi-Transform operator to have two output ports.


    Your first action is to decide which of the input attributes will not be in all of the output records and block their propagation across the rules editor.  In this example, only the party attribute will be in both output records, so you must block the other three input attributes.


    Now you add the attributes that will hold the transformed values to the output records.  In this example, you add an attribute named fullname to output 1 and the attributes fname and lname to output 2.  The red icons adjacent to each of these attributes indicates that they have not yet been bound to a rule and are therefore unused.


    As appropriate, add Expression or Function Rules to initialize these output attributes.  Note that your rules do not need to set values into the attribute party; this is done by Expressor's attribute propagation feature.


    For each record that enters this operator, a record will be emitted on both of the output ports.  But what do you do if you don't want every record emitted on both output ports.  Suppose you only want members of the Republican or Democratic party emitted from output 1 and members of other political parties emitted on output 2.  In this case, you must write a Function Rule with an iterative return that determines on which port to emit the record.  That is, you are implementing the equivalent of a Filter operator that selects based on the value of the party attribute.  What makes this scripting a bit complex is that your code must also manage the iterator return function so that only one record is emitted for each record processed.


    To support this use case, you must add a Function Rule to the rules editor and specify that this rule is iterative.


    Then provide an implementation for the transform function that includes an iterator return function.  In the following example, observe how the flag varaible is used to limit the iterator return function to a single execution for each incoming record.


    As each record enters the operator, the runtime invokes the transform function.  The flag variable is reset to true and the the iterator return function is invoked.  The flag's value is checked and if true the value in the party parameter is examined.  Based on the party, the appropriate port number is returned.  Note that two values are returned: the port on which to emit the record and the output record.  In this example, the output record is an empty Expressor Datascript table, which is OK since the actual output records were created in Rule_1 and Rule_2.


    While the logic in this example is relatively straight-forward, with a little practice you will be able to emit records on any subset of the output ports regardless of how many output ports the operator may implement.  It comes down to knowing how to manage the iterator return function using indicators such as the flag variable or variables used as counters and knowing when to reset output to an empty table.  If appropriate to your processing logic, the Function Rule filter, finalize and/or initialize helper functions may also be utilized.


    The example developed above does what was intended and provides the same processing logic as a Filter operator and two downstream Transform operators.  But the code could be made a little more efficient.  As the example is now designed, the runtime will invoke all three rules.  Yet with each record processed, it should only be necessary to perform the logic in either Rule_1 or Rule_2 as the record either represents a member of the desired parties or not.  To gain more efficiency, the logic within Rule_1 and Rule_2 should be brought into Rule_3 as helper functions as illustrated in the following screen shot.


    Of course, if the processing logic were more complex, it would be appropriate to locate the code that initializes the output records in a Datascript Module so that the coding within the Multi-Transform operator could be kept to a minimum.


    As with all the other operators in the Transformers grouping, any of the attributes in any of the outputs may be associated with a constraint.  If a constraint in any of the output records is violated and the Corrective Action associated with the constraint is Escalate, the records from all the output ports will be managed as specified by the Error Handling property of the Multi-Transform operator.  For example, if the Error Handling property is set to reject or skip the record or all remaining records, then no record will be emitted from any of the output ports.