Question
· Apr 3, 2017

Convert All OBX to NTE Shared Code

I am working on creating a DTL that can replace OBX segment with a string formatted NTE segment .  There is a class ImportFromString but it looks like that is not replacing the target message with the new formatted NTE. I do see  target.setvalueat class but I wanted the transformer to not be scheme base.  

ClassMethod Transform(source As EnsLib.HL7.Message, target As EnsLib.HL7.Message) As %Status
{
  set target = source.%ConstructClone(1)
  s idx=1
  s pSegCount=target.SegCount
  s pObservationValue=""
  s pObservationIdentifier=""
  s pOBXSegment=""
  FOR idx = pSegCount {
          s seg=target.GetSegmentAt(idx)
        if seg.Name="OBX"
            #;Get OBX5 Value
            s pObservationValue = seg.GetValueAt(5)
            #;Create Identifier Value
            s pObservationIdentifier = pObservationIdentifier+1
            #;Build New NTE Segment
            s pOBXSegment="NTE" _"|" _pObservationIdentifier _"|" _pObservationValue

            do seg.ImportFromString(pOBXSegment,"","")
      }
  

  quit $$$OK
}

}

Discussion (5)0
Log in or sign up to continue

I still has OBX segments, with adding target.SetSegmentAt class.

  FOR idx = pSegCount {
          s seg=target.GetSegmentAt(idx)
        if seg.Name="OBX"
            #;Get OBX5 Value
            s pObservationValue = seg.GetValueAt(5)
            #;Create Identifier Value
            s pObservationIdentifier = pObservationIdentifier+1
            #;Build New NTE Segment
            s pOBXSegment="NTE" _"|" _pObservationIdentifier _"|" _pObservationValue
            d seg.ImportFromString(pOBXSegment,"","")
            d target.SetSegmentAt(seg,idx)
      }
  
 

Hi Tom,

Should have spotted this earlier. GetSegmentAt will return an immutable segment, so you shouldn't be able recycle that segment for other purposes.

If you create a new segment, then you might be able to set it at the old segments idx, but having never done it this way I wouldn't be 100% sure if it would.

By all means give it a go, but you should at least test the status and bubble it back up the stack so that you don't end up with silent failures. If there is an error it will apear in the logs.

set sc=target.SetSegmentAt(newsegment,idx)
if $$$ISERR(sc) quit sc

BUT, if I was doing this by hand, I would remove the segment with...

target.SetValueAt(,"PIDgrpgrp(1).ORCgrp(1).OBXgrp(1).OBX","remove","")

I've explicitly hard-coded the groups. Note that this path is a 2.4 schema path and may be different for other schema's. If your data does have repeating groups in it, then you will need to set these logically.

I would then set the two values using...

set sc=target.SetValueAt(pObservationIdentifier,"PIDgrpgrp(1).ORCgrp(1).NTE(1):SetIDNTE","set","") 
set sc=target.SetValueAt(pObservationValue,"PIDgrpgrp(1).ORCgrp(1).NTE(1):SourceofComment","set","")

However, I wouldn't do this by hand at all. Having developed 1000's of DTL's over the years, 95% of them have always been done via the Data Transformation Build tool. The code it generates will have no typo's in the schema paths, it will handle immutability for you, it will trap errors for you and you will end up with a more maintainable solution.

If anything, use the tool and inspect the code it generates to see the right way to develop by hand.

Sean

Thanks Sean, One of the things I wanted to avoid was the schema path. Using the 2.4 schema I would need extra DTL to do the same function and wanted to see if there was a way to make it not bound to a schema.

So you are thinking something like this may work?

S sNewSeg = ##class(EnsLib.HL7.Segment).%New()
    d sNewSeg.init(target.getSegmentIdByIndex(idx),0,"2.3", pOBXSegment)

Try this...

ClassMethod Transform(source As EnsLib.HL7.Message, Output target As EnsLib.HL7.Message) As %Status
{
    set target=source.%ConstructClone(1)
    set seg=target.FindSegment("OBX",.idx,.sc)
    while idx'="",$$$ISOK(sc)
    {
        set ntestr = "NTE|"_$I(ident)_"|"_seg.GetValueAt(5)
        set nte = ##class(EnsLib.HL7.Segment).ImportFromString(ntestr,.sc,source.Separators) if $$$ISERR(sc) goto ERROR
        set sc=target.SetSegmentAt(nte,idx) if $$$ISERR(sc) goto ERROR        
        set seg=target.FindSegment("OBX",.idx,.sc)
    }
ERROR
    quit sc
}