Routing Rules

Is there a way in the routing rule to compare two fields in two different segments? For example, for the message below we need to compare one Identifier in PID-3 (uiytr5678906^^^^CKS)against another in MRG-1 (uiytr5678A06^^^^CKS). Both will always have the same IdentifierTypeCode (PID-3.5/MRG-1.5), but the ID number can be different. Just to clarify, we only want to compare the CKS IdentifierID, not the entire field or all the identifiers in the MRG-1 or PID-3 field.

PD1|||OAK HOSPITAL^^105|600080^ANGELES^DAISY^S^^^^^^^^^103~1073512752^ANGELES^DAISY^S^^^^^^^^^104~600080^ANGELES^DAISY^S^^^^^^^^^106||2|||||||||||

  • 0
  • 158
  • 11
  • 2


So, here's where the ability to write a little custom function in COS for use in the Routing Rule engine comes in handy. You may need to modify the HL7 paths depending on the schema you're using:

Class User.Util.FunctionSet Extends Ens.Rule.FunctionSet



ClassMethod CheckMrnDupForFac(pMsg As EnsLib.HL7.Message, pFac As %String) As %Boolean


       Set tPid3Cnt = pMsg.GetValueAt("PIDgrp(1).PID:3(*)")

       Set tMrg1Cnt = pMsg.GetValueAt("PIDgrp(1).MRG:1(*)")

       for i=1:1:tPid3Cnt


             If pMsg.GetValueAt("PIDgrp(1).PID:3("_i_").5") = pFac


                    Set tPidMrn = pMsg.GetValueAt("PIDgrp(1).PID:3("_i_").1")

                    for j=1:1:tMrg1Cnt


                          Set tMrgMrn = pMsg.GetValueAt("PIDgrp(1).MRG:1("_j_").1")

                          if (pMsg.GetValueAt("PIDgrp(1).MRG:1("_j_").5") = pFac) && (tPidMrn '= tMrgMrn)


                                 Return 1





       Return 0




(updated for readability/word-wrap)

The method above will return true only when CKS entries exist in both fields and are different. Your specific needs may vary :)

It will be available in the function drop-down list in the rule editor.

Getting an <INVALID OREF> on line 1.

The expression editor will often add a period after "Document" ... can you verify that you removed it?

Yes. Testing in terminal. BHS 18e1>w ##class(BHS.Custom.CustomFunctionSets).CheckMrnDup("PID|1||09877^^^^BHSMRN~uytreeqw^^^^CKS|","CKS") set tPid3Cnt = pMsg.GetValueAt("PID:3(1).1") ^ zCheckMrnDup+1^BHS.Custom.CustomFunctionSets.3 BHS 20e1>

The method takes the message object as its first argument, referenced by the variable Document in the Rule Editor. The call you should be making is, literally, CheckMrnDupForFac(Document,"CKS"). The method will parse the PID:3 and MRG:1 fields for you; you don't need to supply them literally.

Are the identifiers you are trying to compare always at the same position in each field, i.e. 3rd repetition? If yes, you should be able to use HL7.{PID:3(3).1}=HL7.{MRG:1(3).1} to compare them.

And if they're not always in the same repetition but the number of repetitions is fixed, it gets a little bit messy; you could do something like:

HL7.{MRG:1.1} CONTAINS HL7.{PID:3(1).1}


HL7.{MRG:1.1} CONTAINS HL7.{PID:3(2).1}


HL7.{MRG:1.1} CONTAINS HL7.{PID:3(3).1}

If they're completely arbitrary in the number of repetitions, you're gonna have to write some COS :)


Again, I just want to compare this identifier; uiytr5678A06^^^^CKS.   This rule, HL7.{PID:3.1}=HL7.{MRG:3.1}would compare every identifier.

Unfortunately no.  Not all patients will have every identifier.  Almost all will have the BHSMRN identifier , but not all will have a FHMRN or CKS.    The goal is to check every outbound A40 to see if the CKS is different in the two segments.  If they are we write them to a file.  If not, we move to the next.

I am not sure if this address the question or not; however, I was able to build the following in the Rules Editor and save, have not tested it though.

I tried to do a screen capture of this in the editor... could not display/paste here even after installing two Chrome Plugins... anyways, here's the "code" 

when condition="If(HL7.{PID:PatientIdentifierList(1).IDNumber}=HL7.{MRG:PriorPatientIdentifierList(1).IDNumber},1,o)">


I hope this helps? 

( the last two parameters are "optional" )


Hi Richard,

The issue in this case was that there could be a variable number of repetitions in the PID:3 and MRG:1 fields, and that there was no guarantee that the MRNs for each facility would appear in the same order. So the actual need was to be able to compare each iteration of the MRN in PID:3 with each iteration of the MRN in MRG:1. This is cumbersome/difficult without a loop construct in the Rules editor, and would require at least as many sequential comparisons as there are repetitions in PID:3.

The example you provided compares only the first iteration of PID:3 with the first iteration of MRG:1, so if the desired match appeared in any subsequent iteration of either of those fields the desired outcome would not be achieved. This is one of those cases where some ObjectScript is a more streamlined solution.

Ok, thanks for that explanation.  I knew my solution might not address the question; however I was thinking the may be a solution utilizing the Rules Editor making this much less complex?  What about using Contains " [ " instead of " = " and not explicit reference to iterations?  

i.e. If(HL7.{PID:PatientIdentifierList().IDNumber} [ HL7.{MRG:PriorPatientIdentifierList().IDNumber},1,o)

Again, I haven't tested, but it saves ( compiles ? ) without error.  Not sure if empty parenthesis would work here, or if there is another way to indicate all iterations, and then perhaps the first one could be more explicit (1) ... just thought I would take a stab at this and see if it would be feasible... 

The issue with the "[" option is that it doesn't compare the MRNs individually; it treats the entire PID:3 field (which can contain multiple MRNs) as the value to locate in MRG:1. You'd have to first locate the PID:3 iteration that contains the "CKS" facility identifier, then check the MRG:1 field to see if it's contained within it.