Skip to main content

Adding Other Actions

This chapter provides details on adding other kinds of actions to a DTL transformation. It contains the following sections:

For information on adding assign actions, see the previous chapter.

Adding an If Action

An if action executes other actions conditionally, depending on the value of an expression that you provide. Ensemble represents each if action as a connector line in the DTL diagram.

To add an if action:

  1. If the condition depends upon the value of a source property, click that property.

  2. Select if from the Select Action drop-down list.

    On the Action tab, the Condition field automatically contains the name of the source property that you had selected.

    The area below the diagram contains three new rows. The Actions column displays the following labels for these rows:

    • if — This row marks the beginning of actions to perform if the condition is true.

    • else — This row marks the beginning of actions to perform if the condition is false.

    • endf — This row marks the end of the if action.

  3. Edit the Condition field so that it contains an expression that evaluates to either true or false.

    For example:

    source.ABC = "XYZ"
    

    Notes:

    • To create an expression that uses an Ensemble function, click the search button generated description: icon search next to the Value field. This invokes the Data Transform Function Wizard, which is described earlier.

    • To create a more complex expression, type the expression into the Value field. See “Valid Expressions,” earlier in this book. Make sure that the expression is valid in the scripting language you chose for the data transformation; see “Specifying Transformation Details,” earlier in this book.

  4. To add actions to perform when the condition is true:

    1. Click the if row.

    2. Select an item from the Add Action drop-down list.

    3. Edit the values in the Action tab as needed.

    4. Repeat as necessary.

    You can include assign actions, if actions, and for each actions.

  5. To add actions to perform when the condition is false:

    1. Click the else row.

    2. Continue as described in the preceding item.

The details are then shown in the block below the DTL diagram. For example:

generated description: if steps

Note:

It is not required to have any actions for the if branch or for the else branch. If there are no actions in either branch, the if action has no effect.

Adding a For Each Action

The for each action enables you to define a sequence actions that is executed iteratively, once for each member of one of the following:

  • A collection property (for a standard message) .

  • A repeating property (for an Ensemble virtual document).

  • A set of subdocuments in a document (for an Ensemble virtual document).

Ensemble represents each for each action as a connector line in the DTL diagram.

To add a for each action:

  1. Select a collection or repeating property in the source message.

  2. Select for each from the Select Action drop-down list.

    On the Action tab, the Property field automatically contains the name of the source property that you had selected.

    Also, the Key field automatically contains k1. For the for each action, the Key field specifies the name of an iterator variable.

  3. On the Action tab, the Property field should not include the iterator key within the parentheses. For example, the following is correct:

    source.{PID:PatientIdentifierList( )}
    

    This means that Ensemble will iterate through the PatientIdentifierList repeating fields, starting with the first one (numbered 1) and ending with the last one.

    For example:

    generated description: for each details

  4. To add actions to the for each block, click the for each action and then add the appropriate actions.

The details are then shown in the block below the DTL diagram. For example (partial):

generated description: for each steps

If the <foreach> applies to a collection property in a message, the sequence of activities is executed iteratively, once for every element that exists within the collection property. If the element is null, the sequence is not executed. The sequence is executed if the element has an empty value, that is, the separators are there but there is no value between them, but is not executed for a null value, that is, the message is terminated before the field is specified.

Shortcuts for the For Each Action

When you are working with virtual documents, Ensemble provides a shortcut notation that iterates through every instance of a repeating field within a document structure. This means you do not actually need to set up multiple nested for each loops to handle repeating fields; instead you create a single assign action using a virtual property path with empty parentheses within the curly bracket { } syntax. For information, see “Curly Bracket {} Syntax” in Ensemble Virtual Documents.

Note:

If the source and target types are different, such as transforming from an EnsLib.HL7.MessageOpens in a new tab to an EnsLib.EDI.XML.DocumentOpens in a new tab, you cannot use this short cut for the For Each action. Use an explicit For Each action in these cases.

Avoiding <STORE> Errors with Large Messages

As you loop over segments in an HL7 message or object collections, they are brought into memory. If these objects consume all the memory assigned to the current process, you may get unexpected errors.

To avoid this, remove the objects from memory after you no longer need them. For example, if you are processing many HL7 segments in a for each loop, you can call the commitSegmentByPath() method on both the source and target as the last step in the loop. Similarly, for object collections, use the %UnSwizzleAt() method.

For example, within the innermost for each loop, include a code action that contains the following ObjectScript:

 Do source.commitSegmentByPath("ORCgrp("_tORCkey_").OBRgrp("_tOBRkey_").OBXgrp("_tOBXkey_").OBX")
 Do target.commitSegmentByPath("ORCgrp("_tORCkey_").OBRgrp("_tOBRkey_").OBXgrp("_tOBXkey_").OBX")

If you cannot make code changes, a temporary workaround is to increase the amount of memory allocated for each process. You can change this by setting the bbsiz parameter on the Advanced Memory Settings page in the Management Portal. Note that this requires a system restart and should only occur after consulting with your system administrator.

Adding a Subtransform Action

A subtransform invokes another transformation (an ordinary transformation), often within a for each loop. Subtransformations are particularly useful with virtual documents, because EDI formats are typically based on a set of segments that are used in many message types. The ability to reuse a transformation within another transformation means that you can create a reusable library of segment transformations that you can call as needed, without duplicating code transformation.

Ensemble does not represent a subtransform action in the DTL diagram.

To add a subtransform action:

  1. Select subtransform from the Select Action drop-down list.

  2. On the Action tab, specify the following details:

    • Transform Class — Specifies the data transformation class to use. This can be either a DTL transformation or a custom transformation. For information on custom transformations, see “Defining Custom Transformations” in Developing Ensemble Productions. You must enter the class.

    • Source Property — Identifies the property being transformed. This may be an object property or a virtual document property path. Generally it is a property of the source message used by the transformation. You must enter the source property.

    • Target Property — Identifies the property into which the transformed value will be written. This may be an object property or a virtual document property path. Generally it is a property of the target message used by the transformation. You must enter the target property.

    • Auxiliary Property—Optionally, specifies a value that is passed to the subtransform. The subtransform accesses the value as the aux variable.

    • Disabled—Optionally, specifies that the subtransform is disabled.

    • Description—Optionally, specifies a text description of the subtransform.

    Note:

    In the case of a subtransform with Create as new or copy, it is not necessary to have a pre-existing target object.

Example

The examples show two DTL transformation classes. The second transformation calls the first one as a subtransformation.

  • The following transformation applies to fields within the virtual document segment IN1 for HL7 Version 2.3.1 messages. IN1 provides insurance information for the ADT series of patient admission messages, as will become clear from the next two transformation classes examples, which call this one via the subtransform action.

    It is common to refer to a transformation that plays this role as a subtransformation. However, this really is just an ordinary transformation and could also be invoked directly.

    Class Test.HL7.SegDTLa Extends Ens.DataTransformDTL
    {
    Parameter REPORTERRORS = 1;
    
    XData DTL [ XMLNamespace = "http://www.intersystems.com/dtl" ]
      {
      <transform targetClass='EnsLib.HL7.Segment' targetDocType='2.5:IN1'
                 sourceClass='EnsLib.HL7.Segment' sourceDocType='2.3.1:IN1'
                 create='copy' language='objectscript'>
        <assign property='target.{InsurancePlanID.Identifier}'
                value='source.{InsuranceCompanyID(1).ID}'
                action='set'/>
        <assign property='target.{InsuranceCompanyID}'
                value='""'
                action='remove'/>
        <assign property='target.{InsuranceCompanyName}'
                value='..ToLower(source.{InsuranceCompanyName})'
                action='set'/>
      </transform>
      }
    }
  • The following transformation invokes the preceding transformation:

    Class Test.HL7.A01SegDTLb Extends Ens.DataTransformDTL
    {
    Parameter REPORTERRORS = 1;
    
    XData DTL [ XMLNamespace = "http://www.intersystems.com/dtl" ]
      {
      <transform targetClass='EnsLib.HL7.Message'
                 targetDocType='2.5:ADT_A01'
                 sourceClass='EnsLib.HL7.Message'
                 sourceDocType='Demo.HL7.MsgRouter.Schema:ADT_A01'
                 create='copy' language='objectscript'>
        <foreach property='source.{()}' key='i'>
          <assign property='target.{(i):1}' value='i' action='set'/>
          <if condition='target.GetSegmentAt((i)).Name="IN1"'>
            <true>
              <subtransform class='Test.HL7.SegDTLa'
                            targetObj='target.{(i)}'
                            sourceObj='source.GetSegmentAt(i)'/>
            </true>
          </if>
        </foreach>
      </transform>
      }
    }

Adding a Trace Action

A trace action generates a trace message, which is helpful for diagnosis. If the Log Trace Events setting is enabled for the parent business host, this message is written to the Event Log. If the Foreground setting is enabled for the parent business host, the trace messages are also written to the Terminal window.

Ensemble does not represent a trace action in the DTL diagram.

To add a trace action:

  1. Select trace from the Select Action drop-down list.

  2. On the Action tab, specify the following:

    • Value — Specify a literal value or other valid expression.

      See “Valid Expressions,” earlier in this book. Make sure that the expression is valid in the scripting language you chose for the data transformation; see “Specifying Transformation Details,” earlier in this book.

    • Description — Specify an optional description.

The trace action generates trace message with User priority; the result is the same as using the $$$TRACE macro in ObjectScript or the WriteTrace("user") utility in Basic.

Adding a Code Action

A code action enables you to execute one or more lines of user-written code within a DTL data transformation. This option enables you to perform special tasks that are difficult to express using the DTL elements. Ensemble does not represent a code action in the DTL diagram.

To add a code action:

  1. Select code from the Select Action drop-down list.

  2. On the Action tab, specify the following:

    • Code — Specify one or more lines of code in the scripting language specified for the transformation. For rules about expressions in this code, see “Syntax Rules.”

      Ensemble automatically wraps your code within a CDATA block. This means that you do not have to escape special XML characters such as the apostrophe (') or the ampersand (&),

      Also see the notes below.

    • Description — Specify an optional description.

Tip:

To write custom code that you can debug easily, write the code within a class method or a routine so that it can be executed in the Terminal. Debug the code there. Then call the method or routine from within the code action of the DTL.

Guidelines for Using Custom Code in DTL

In order to ensure that execution of a data transformation can be suspended and restored, you should follow these guidelines when using a code action:

  • The execution time should be short; custom code should not tie up the general execution of the data transformation.

  • Do not allocate any system resources (such as taking out locks or opening devices) without releasing them within the same code action.

  • If a code action starts a transaction, make sure that the same action ends the transactions in all possible scenarios; otherwise, the transaction can be left open indefinitely. This could prevent other processing or can cause significant downtime.

Adding an SQL Action

An SQL action enables you to execute an SQL SELECT statement from within the DTL transformation. Ensemble does not represent an sql action in the DTL diagram.

To add an sql action:

  1. Select sql from the Select Action drop-down list.

  2. On the Action tab, specify the following:

    • SQL — Specify a valid SQL SELECT statement.

      Ensemble automatically wraps your SQL within a CDATA block. This means that you do not have to escape special XML characters such as the apostrophe (') or the ampersand (&).

      Also see the notes below.

    • Description — Specify an optional description.

Guidelines for Using SQL in DTL

Be sure to use the following guidelines:

  • Always use the fully qualified name of the table, including both the SQL schema name and table name, as in:

    MyApp.PatientTable

    Where MyApp is the SQL schema name and PatientTable is the table name.

  • Any tables listed in the FROM clause must either be stored within the local Ensemble database or linked to an external relational database using the SQL Gateway.

  • Within the INTO and WHERE clauses of the SQL query, you can refer to a property of the source or target object. To do so, place a colon (:) in front of the property name. For example:

      SELECT Name INTO :target.Name
      FROM MainFrame.EmployeeRecord
      WHERE SSN = :source.SSN AND City = :source.Home.City
    
    
  • Only the first row returned by the query will be used. Make sure that the WHERE clause correctly specifies the desired row.

FeedbackOpens in a new tab