Andre Cerri · Apr 24, 2017

A couple of questions on HL7/X12 handling


1) What's the correct way to check for an existence of a segment?  So far I have been doing this by checking to see if a required field is non-null, and this seems to work but is a bit clumsy. In this case, it’s an X12 message being checked in an IF action in BPL:


Or in a DTL, to see if a Z segment exists:


2) I have a case where I need to change from an external date format (YYYYMMDD) to internal (+$H) for a DTL to create a new object (and then persist it later). I am using:  +..ConvertDateTime(source.{G62:Date},"%Y%m%d","%q(3)") Is there a cleaner way using built in utils or without writing a custom function?

3) I have a case where I need to change from an external time format (HHMM) to internal for a DTL to create a new object (and then persist it later). I am using this: $e(source.{G62:Time},1,2)*60+$e(source.{G62:Time},3,4)*60  Is there a cleaner way using built in utils or without writing a custom function?

4) PID segment is actually in a repeating group. In the real world, do you ever see more than one PIDgrp or PID segment? Or is the de facto standard a single group/segment?


0 1,108
Discussion (3)1
Log in or sign up to continue

Hi Andre,

1. Description might be empty whilst NTE might actually exist, so it would be better to do...


2. If you are looking to shave off a few characters then take a look at $zdh...


3. For time there is $zth, but it expects a : in the time (e.g. HH:MM).

It doesn't look like you have a colon, so you could use $tr to reformat the time first. This will save you 10 or so characters...


4. You can have more than one PID group, but you should not see more than one PID segment in a PID group. Not all message types define (or allow) a repeating PID group. You might see multiple PID groups in an ADT merge message. You might also see bulk records in an ORU message, but in the real world probably not. If you know the implementation only ever sends one PID group then you will see many developers just hard coding its ordinal key to 1, e.g.


Developing with HL7 can feel verbose to begin with. Tbh, what you are currently doing is all perfectly fine and acceptable.


Thx Sean.

On the date transform stuff, I don't care about length, more interested in using nice clean on the eye out of the box Ensemble functions, which demo much better than $zdh et al, and better than a custom function than means a new customer has to write code, however simple. Sometimes deals are won or lost on "silly" stuff like this.

R.e. checking for a segment, your example is better than mine but again less intuitive than something like request.SegmentExists("NTE(1")) would be - if it existed. LOL.

Thx for the info on the multiple PID segments, good to know.


No problem. I know you said you didn't want to write your own custom code, so this is for anyone else landing on the question.

If you use the DTL editor (which I advise even for ardent COS developers), then you will most likely use the helper methods in Ens.Util.FunctionSet that your DTL extends from, e.g. ToUpper, ToLower etc.

Inevitably there will be other common functions that will be needed time and time again. A good example would be to select a patient ID in a repeating field of no known order. This can be achieved with a small amount of DTL logic, but many developers will break out and write some custom code for this. The problem however is that I see each developer doing there own thing and a system ends up with custom DTL logic all over the place, often repeating the same code over and over again.

The answer is to have one class for all of these functions and make that class extend Ens.Rule.FunctionSet. By extending this class, all of the ClassMethods in that class will magically appear in the drop down list of the DTL function wizard. This way all developers across the team, past and future will visibly see what methods are available to them.

To see this in action, create your own class, something like this...

Class Foo.FunctionSet Extends Ens.Rule.FunctionSet

  ClassMethod SegmentExists(pSegment) As %Boolean
      Quit pSegment'=""


Then create a new HL7 DTL. Click on any segment on the source and add an "If" action to it. Now in the action tab, click on the condition wizard and select the function drop down box. The SegmentExists function will magically appear in the list. Select it and the wizard will inject the segment value into this function.

Whilst developers feel the need to type these things out by hand, they will never beat the precision of using these types of building blocks and tools. It also means that you can have data mappers with strong business logic and not so broad programming skills bashing out these transforms.