Replace MSH:4 with PV1:5 need help to finish it

Homepage Clovertech Forums Read Only Archives Cloverleaf Cloverleaf Replace MSH:4 with PV1:5 need help to finish it

  • Creator
    Topic
  • #54957
    Albert Sinha
    Participant

    # Message handle

               keylget args MSGID mh

               set msg [msgget $mh]

               set segList [split $msg r]

                set fldSep [string index $msg 3]

                set subSep [string index $msg 4]

               

                set pidLoc [lsearch -regexp $segList {^MSH}]

                set MSH [split [lindex $segList $pidLoc] $fldSep]

    How do I split PV1 and then copy the PV1:5 to MSH:4

    Some suggestions and help will be really appreciated.

Viewing 28 reply threads
  • Author
    Replies
    • #83579
      Charlie Bursell
      Participant

      # Message handle

                keylget args MSGID mh

                set msg [msgget $mh]

                set segList [split $msg r]

                 set fldSep [string index $msg 3]

                 set subSep [string index $msg 4]

                 # You don’t need location of PV1 just the fields

                 set PV1 [split [lsearch -inline -regexp $segList {^PID}] $fldSep]

                 # MSH is always first segment get list of fields

                 set MSH [split [lindex $segList 0] $fldSep]

                 # Get PV1.5

                 set pv15 [lindex $PV1 5]

                 # Put PV1.5 into MSH.4  Remember fields are skewed

                 # by one since you split using field 1

                 set MSH [lreplace $MSH 3 3 $pv15]

                 # Replace MSH sith modified segment

                 set segList [lreplace $segList 0 0 [join $MSH $fldSep]]

                 # Send it on

                 msgset $mh [join $segList r]

                 return “{CONTINUE $mh}”

      Note:  I have been known to fat-finger some things.  I did not test it

    • #83580
      David Barr
      Participant

      I’d use a library for this.

      <a href="http://clovertech.infor.com/viewtopic.php?t=4886&#8243; class=”bbcode_url”>http://clovertech.infor.com/viewtopic.php?t=4886

      Your code would look something like this:

      Code:

      package require hl7
      set hl7 [hl7::parse_msg [msgget $mh]]
      hl7::set_field hl7 MSH.4 [hl7::get_field hl7 PV1.5]
      msgset $mh [hl7::join_msg hl7]

    • #83581
      Albert Sinha
      Participant

      Thank you very much to both David and Charlie, now I have a better understanding for my next script.

    • #83582
      Robert Milfajt
      Participant

      Does installation of this library on a server require any special access on AIX, i.e., root, etc.?

      Thanks for taking the time to create this library David!  ðŸ˜€

      Robert Milfajt
      Northwestern Medicine
      Chicago, IL

    • #83583
      David Barr
      Participant

      You just need to extract the archive under $HCIROOT. The files go into the tcl/lib/hl7 subdirectory, so it shouldn’t require root access to install.

    • #83584
      Albert Sinha
      Participant

      In windows it is the same on HCIROOT and just unzip it ?

      Thanks again David

    • #83585
      David Barr
      Participant

      I’m not sure about Windows. You probably have to use %HCIROOT% instead of $HCIROOT if you’re typing at a command prompt, but otherwise it should be the same.

    • #83586
      Albert Sinha
      Participant

      run {  keylget args MSGID mh

                set msg [msgget $mh]

                set segList [split $msg r]

                 set fldSep [string index $msg 3]

                 set subSep [string index $msg 4]

                 set PID [split [lsearch -inline -regexp $segList {^PID}] $fldSep]

                 set MSH [split [lindex $segList 0] $fldSep]

                 # Get Pid 3.3

                 set pid33 [lindex $PID 3]

         set field33 [lindex $pid33 3]

                 set MSH [lreplace $MSH 3 3 $field33]

                 set segList [lreplace $segList 0 0 [join $MSH $fldSep]]

                 # Final restructure

                 msgset $mh [join $segList r]

                 return “{CONTINUE $mh}”

      Above is what I have for replacing MSH4 with PID3

      But here is the input and the output

      input:  

      MSH|^~&|EMR|DMD|PWIM||20160202102658.467||ADT^A31|2016020218221182|P|2.4EVN|A31|20160201110129.503|||USER

      PID|1|004100089^^^GMC^MR^EMR|004100089^^^GMC^MR||TRAUMA^ONE^^^^^L||196001010000|M||99^Unknown^HL70005||||||||480000095^^^GMC|||||||||N|||N

      output:

      MSH|^~&|EMR||PWIM||20160202102658.467||ADT^A31|2016020218221182|P|2.4EVN|A31|20160201110129.503|||USER

      PID|1|004100089^^^GMC^MR^EMR|004100089^^^GMC^MR||TRAUMA^ONE^^^^^L||196001010000|M||99^Unknown^HL70005||||||||480000095^^^GMC|||||||||N|||N

      Seems like it is not populating which should be GMC, instead a blank in MSH-4  , what I am doing wrong. Thanks in advance for any help or suggestion.

    • #83587
      Brandon Grudt
      Participant

      It does not look like you are splitting by the subfield separator, so your pid33 variable is not a list.

    • #83588
      Albert Sinha
      Participant

      set field33 [lindex [split [lindex $PID 3] $sub] 3]

      After replacing field33 with the above line it does not replace it with a blank it keeps it as it is, does not replace it with PID-3.3 . Really need some help to finish this.

    • #83589
      David Barr
      Participant

      It would help if you use the testing tool and echo out some variables at each step. Like I would echo $PID and $sub before “set field33” and echo $field33 after you set it.

    • #83590
      Kevin Crist
      Participant

      Here is one we use here at times.

      Code:


      #########################################################################################
      #########################################################################################
      #########################################################################################
      # Name: tpsTransferField.tcl
      # Purpose: – This tps tclproc moves or copies the specified Segment/Field (Source) value
      # to new Specified Segment/Field (Destination)location.
      # The Source Segment/Field will be set to {} for a MOVE
      # The Source Segment/Field will left intact for a COPY
      # – If the any of the user supplied arguments (5 of them) are omitted,
      #  the message will be continued as is and an entry will be made in
      # the engine log.
      # – If there are mutilple occurances of the Source Segment, the value will be
      # taken from the first one.
      # – If there are mutilple occurances of the Destination Segment, the value
      # will be moved to all of them.
      # – If the Source or Destintion Segment does not exist in the message,
      # the message will be continued and an entry will be put in
      # the engine log.
      # – If the New Field does not exist in the message but the segment does,
      # blank fields will be added to create the space for the field number
      #  specified.
      # – If the New Field already has data in it, it will be over written.
      # – The field numbers start with 0, ie the 3rd field is field number 2.
      #
      # UPoC type: tps
      # Args: tps keyedlist containing the following keys:
      #       MODE    run mode (”start”, “run” or “time”)
      #       MSGID   message handle
      #       ARGS    user-supplied arguments:
      # 1) The user specified Function
      # The key is FUNCTION (only MOVE or COPY are Valid)
      # 1) The user specified Source Segment
      # The key is SOURCESEG
      # 2) The user can specify the Source Field Number
      # The key is SOURCEFLD
      # 3) The user specified Destination Segment
      # The key is DESTINSEG
      # 4) The user can specify the Destination Field Number
      # The key is DESTINFLD
      #
      # Example arguments: {FUNCTION MOVE} {SOURCESEG OBR} {SOURCEFLD 25} {DESTINSEG OBR} {DESTINFLD 30}
      # This will move the value that is in OBR-25 to OBR-30.
      #
      # Returns: tps disposition list:
      #          Continues the modified message
      # OR
      # Continues the Un-modified message (if bad ARGS passed in)
      #
      # Created: John Zalesak 04/15/2009
      #
      #
      #########################################################################################
      #########################################################################################
      #########################################################################################

      proc tpsTransferField { args } {

      #########################################################################################
      # Get the Connection/Proc Name for Error/Debug Messages
      #########################################################################################

      global HciConnName
      set myname “$HciConnName/[lindex [info level 1] 0]”
      set nowis [clock format [clock scan now] -format “%D – %T”]

      #########################################################################################
      # Initialize Variables Used
      #########################################################################################

      set dispList [list] ;# Disposition List Returned to Engine

      set fldSep “” ;# Field Seperator – get from MSH
      set subSep “” ;# SubField Seperator – get from MSH
      set repSep “” ;# Repeating Field Seperator – get from MSH

      set Function “” ;# Specifies Move or Copy
      set SourceSeg “” ;# Source Segment Name
      set SourceFld 0 ;# Source Field Number
      set DestinSeg “” ;# Destination Segment Name
      set DestinFld 0 ;# Destination Segment Name

      set fldVal “” ;# Value to be moved
      set null {} ;# Null Value

      set segList [list] ;# Message Segments in List Form
      set fldList [list] ;# Segment Fields in List Form
      set fldCnt [list] ;# Count of Fields in fldList

      set SourceSegPos [list] ;# List of Seg Pos in segList of Source Seg
      set DestinSegPos [list] ;# List of Seg Pos in segList of Destin Seg

      set seg “” ;# A segment from a list of segments
      set flds 0 ;# Field Counter used in a loop

      #########################################################################################
      # Load in the arguments we need that were passed from the caller
      #########################################################################################

      keylget args MODE mode             ;# The mode the engine called from

      keylget args ARGS.FUNCTION Function ;# The Function reqested (MOVE/COPY)
      set Function [string toupper $Function] ;# Force to uppercase

      keylget args ARGS.SOURCESEG SourceSeg ;# Source Segement Name
      set SourceSeg [string toupper $SourceSeg] ;# Force to uppercase
      keylget args ARGS.SOURCEFLD SourceFld ;# Source Field Number

      keylget args ARGS.DESTINSEG DestinSeg ;# Destination Segement Name
      set DestinSeg [string toupper $DestinSeg] ;# Force to uppercase
      keylget args ARGS.DESTINFLD DestinFld ;# Destination Field Number

      #########################################################################################
      # Switch based on what mode the engine was in when it called the procedure
      #########################################################################################

       switch -exact — $mode {

         run {
          set mh [keylget args MSGID] ;# Get message handle from args
         set dispList [list “CONTINUE $mh”] ;# Initialize to good message
           set msg [msgget $mh] ;# Get a copy of the message

           set fldSep [string index $msg 3] ;# Field Seperator
           set subSep [string index $msg 4] ;# Sub-Field Seperator
           set repSep [string index $msg 5] ;# Repeating Field Seperator

      set segList [split $msg r] ;# Split message into segList

      #########################################################################################
      # Validate the user supplied values
      #########################################################################################

      if { $Function == “MOVE” || $Function == “COPY” } {
      } else {
       echo n n
       echo “==========================================================”
        echo “:WARN – Invalid Function Supplied !”
        echo “:WARN – Function = “$Function” ”
       echo “:WARN – Message Continued As Is.”
       echo “:WARN – Here Is: $myname”
       echo “:WARN – Now Is: $nowis”
       echo $msg
       echo “==========================================================”  
       echo n n
             return $dispList
      }

      if { $SourceSeg == “” || $DestinSeg == “” } {
       echo n n
       echo “==========================================================”
        echo “:WARN – Required Segment was not Supplied !”
        echo “:WARN – Source Segment = “$SourceSeg” ”
        echo “:WARN – Destination Segment = “$DestinSeg” ”
       echo “:WARN – Message Continued As Is.”
       echo “:WARN – Here Is: $myname”
       echo “:WARN – Now Is: $nowis”
       echo $msg
       echo “==========================================================”  
       echo n n
             return $dispList
      }

      if { $SourceFld == “” || $SourceFld == 0 ||
      $DestinFld == “” || $DestinFld == 0 } {
       echo n n
       echo “==========================================================”
        echo “:WARN – Invalid or No Field Number Was Supplied !”
        echo “:WARN – Source Field Number = “$SourceFld” ”
        echo “:WARN – Destination Field Number = “$DestinFld” ”
       echo “:WARN – Message Continued As Is.”
       echo “:WARN – Here Is: $myname”
       echo “:WARN – Now Is: $nowis”
       echo $msg
       echo “==========================================================”  
       echo n n
             return $dispList
      }

      #########################################################################################
      # Find Position of Segement(s) – If missing -> Continue Message and Return
      #########################################################################################

      set SourceSegPos [lsearch -all -regexp $segList “^$SourceSeg”]
      if { [lindex $SourceSegPos 0] < 0 } {
       echo n n
       echo "=========================================================="
        echo ":WARN – Source Segment "$SourceSeg" Is Missing !"
       echo ":WARN – Message Continued As Is."
       echo ":WARN – Here Is: $myname"
       echo ":WARN – Now Is: $nowis"
       echo $msg
       echo "=========================================================="  
       echo n n
             return $dispList
      }

      set DestinSegPos [lsearch -all -regexp $segList "^$DestinSeg"]
      if { [lindex $DestinSegPos 0] = [expr $SourceFld + 1]} {
      set fldVal [lindex $fldList $SourceFld]
      if { $Function == “MOVE” } {
      lset fldList $SourceFld $null
      lset segList [lindex $SourceSegPos] [join $fldList $fldSep]
      }
      } else {
      echo n n
       echo “==========================================================”
        echo “:WARN – Source Segment “$SourceSeg” ”
        echo “:WARN – Does not Contian Field Number: “$SourceFld” ”
       echo “:WARN – Message Continued As Is.”
       echo “:WARN – Here Is: $myname”
       echo “:WARN – Now Is: $nowis”
       echo $msg
       echo “==========================================================”  
       echo n n
             return $dispList
      }

      #########################################################################################
      # Write the Source Field Value into the Destination Field – Add blank fields if needed
      #########################################################################################

      foreach seg $DestinSegPos {
      set fldList [split [lindex $segList $seg] $fldSep]
      set fldCnt [llength $fldList]

      for { set flds $fldCnt } { $flds < [expr $DestinFld + 1] } { incr flds } {
        lappend fldList $null
        }
       
        lset fldList $DestinFld $fldVal
        lset segList $seg [join $fldList $fldSep]
       
        }

      #########################################################################################
      # Recreate the message and store back at msg handle
      #########################################################################################

       set msg [join $segList r]  
         msgset $mh $msg

      }

      start { }
         time { }
         shutdown { }
         default {
          echo ":WARN"
          echo ":WARN ======================================"
       echo ":WARN – tps called with invalid mode !"
      echo ":WARN – Mode Is: $mode"
      echo ":WARN – Here Is: $myname"
      echo ":WARN – Now Is: $nowis"
      echo ":WARN ======================================"
      echo ":WARN"
         }
      } ;# End Switch

      return $dispList

      } ;# End Proc
      [quote][/quote]

    • #83591
      Michael Hertel
      Participant

      set field33 [lindex [split [lindex $PID 3] $sub] 3]

      Should have blown up on you.

      Use $subSep not $sub

      set field33 [lindex [split [lindex $PID 3] $subSep] 3]

    • #83592
      Albert Sinha
      Participant

      thank you all, I will try all the suggestions and test it out.

    • #83593
      Jim Kosloskey
      Participant

      Another thought:

      Xlate:

      BULKCOPY

      COPY PV1-5 –> MSH-4

      Done

      I am not a proponent of using BULKCOPY but this is quick to do.

      email: jim.kosloskey@jim-kosloskey.com 29+ years Cloverleaf, 59 years IT - old fart.

    • #83594
      Albert Sinha
      Participant

      proc replace_MSH_4_PID_3 { args } {

         keylget args MODE mode   ;# Fetch mode

         set dispList {} ;# Nothing to return

         switch -exact — $mode {

             start {

                 

             }

             run {  keylget args MSGID mh

                set msg [msgget $mh]

                set segList [split $msg r]

                 set fldSep [string index $msg 3]

                 set subSep [string index $msg 4]

       set sub [string index ‘^’]

                 set PID [split [lsearch -inline -regexp $segList {^PID}] $fldSep]

                 set MSH [split [lindex $segList 0] $fldSep]

                 # Get Pid 3.3

                 set field33 [lindex [split [lindex $PID 3] $subsep] 3]

                 set MSH [lreplace $MSH 3 3 $field33]

                 set segList [lreplace $segList 0 0 [join $MSH $fldSep]]

                 # Final restructure

                 msgset $mh [join $segList r]

                 return “{CONTINUE $mh}”

             

                   

             }      

             time {

                 # Timer-based processing

                 # N.B.: there may or may not be a MSGID key in args

             }

             shutdown {

                 # Doing some clean-up work

             }

             default {

                 error “Unknown mode ‘$mode’ in tpsFixOnMSH”

             }

         }

         return $dispList

      }

      Above is what I have when I have the tcl in the thread nothing crosses over. When I take it out it goes over.

    • #83595
      Michael Hertel
      Participant

      The proc is case sensitive.

      use $subSep

      Change this line ->  set field33 [lindex [split [lindex $PID 3] $subsep] 3]

      To this line -> set field33 [lindex [split [lindex $PID 3] $subSep] 3]

      Are you running this through your testing tool?

      It should be bombing there with an undefined error.

    • #83596
      Albert Sinha
      Participant

      Yes I am running it via testing tool

    • #83597
      Michael Hertel
      Participant

      Isn’t it erring on an undefined variable?

      In any event, did you make the change and does it work now?

    • #83598
      Albert Sinha
      Participant

      proc replace_MSH_4_PID_3 { args } {

         keylget args MODE mode   ;# Fetch mode

         set dispList {} ;# Nothing to return

         switch -exact — $mode {

             start {

                 

             }

             run {  keylget args MSGID mh

                set msg [msgget $mh]

                set segList [split $msg r]

                 set fldSep [string index $msg 3]

                 set subSep [string index $msg 4]

                 set PID [split [lsearch -inline -regexp $segList {^PID}] $fldSep]

                 set MSH [split [lindex $segList 0] $fldSep]

                 # Get Pid 3.3

                 # set pid33 [lindex $PID 3]

                 # set field33 [lindex $pid33 3]

                 set field33 [lindex [split [lindex $PID 3] $subSep] 3]

                 set MSH [lreplace $MSH 3 3 $field33]

                 set segList [lreplace $segList 0 0 [join $MSH $fldSep]]

                 # Final restructure

                 msgset $mh [join $segList r]

                 return “{CONTINUE $mh}”

             

                   

             }      

             time {

                 # Timer-based processing

                 # N.B.: there may or may not be a MSGID key in args

             }

             shutdown {

                 # Doing some clean-up work

             }

             default {

                 error “Unknown mode ‘$mode’ in tpsFixOnMSH”

             }

         }

         return $dispList

      }

      Here is the whole script I made the change for subSep  still not working, it does not send the message, when I take it out the messages go thru fine.

    • #83599
      Kevin Crist
      Participant

      i copied your script and got it worked fine for me with no modifications.

    • #83600
      Albert Sinha
      Participant

      what you think might be the problem  I am just putting it right on the tps of the outbound thread, and as soon as I stop and restart the process and send a new message it does not go , I take it out and resend it goes thru fine.

    • #83601
      David Barr
      Participant

      Have you looked in the error database?

    • #83602
      Charlie Bursell
      Participant

      Mike

      Change this line ->  set field33 [lindex [split [lindex $PID 3] $subsep] 3]

      To this line -> set field33 [lindex [split [lindex $PID 3] $subSep] 3]

      Would return PID.3.2 which is probably the emty string.

      I too think the proc is good.  To insure put a before and after echo statement

      set segList [split $msg r]

      #DEBUG

      echo nBEFORE:

      foreach el $segList {echo $el}

      echo

      #DEBUG

      echo nAFTER:

      foreach el $segList {echo $el}

      echo

      Note newlines before and after each echo to set it apart from any other garbage.   You can run it through hcitpstest or the engine.  See if change is there.

      Be sure and remove DEBUG once problem is resolved.

    • #83603
      Michael Hertel
      Participant

      Charlie, I don’t want to question you since you are the master.

      But it counts from zero so I think you’re counting in the wrong direction.

      Besides, Kevin said it tested fine. Lol

      If you think I’m wrong, I’ll run the code through my engine to make sure I’m not nuts. But by now I am spending way too much time on this. I was only trying to point out the undefined variable, not the field position.

      🤓

    • #83604
      Charlie Bursell
      Participant

      I will take your work for it but breaking it down from inner to outer:

               [lindex [split [lindex $PID 3] $subSep] 3]

      set var1 [lindex $PID 3]     ;# Returns PID field 3

      set var2 [split $var1 $subSep]   ;#   Splits PID,3 into subfields

      set var3 [lindex $var2 3]  ;3 Returns PID.3.2  0-based

      Where am I wrong?

    • #83605
      Kevin Crist
      Participant

      i only did mine in the testing tool. i did not put it in a thread and test that way.

    • #83606
      Michael Hertel
      Participant

      Quote:

      I will take your work for it but breaking it down from inner to outer:

               [lindex [split [lindex $PID 3] $subSep] 3]

      set var1 [lindex $PID 3]     ;# Returns PID field 3

      set var2 [split $var1 $subSep]   ;#   Splits PID,3 into subfields

      set var3 [lindex $var2 3]  ;3 Returns PID.3.2  0-based

      Where am I wrong?

      Ok, here’s what I’m thinking:

      [lindex $var2 0] = PID-3.1

      [lindex $var2 1] = PID-3.2

      [lindex $var2 2] = PID-3.3

      [lindex $var2 3] = PID-3.4 <—Returns PID-3.4 not PID-3.2 as you state.

      Where am I wrong?  ðŸ˜‰

    • #83607
      Albert Sinha
      Participant

      I will try it with the echo.

      Really appreciate you guys help on this.

Viewing 28 reply threads
  • The forum ‘Cloverleaf’ is closed to new topics and replies.

Forum Statistics

Registered Users
5,117
Forums
28
Topics
9,292
Replies
34,435
Topic Tags
286
Empty Topic Tags
10