› Clovertech Forums › Read Only Archives › Cloverleaf › Cloverleaf › Replace MSH:4 with PV1:5 need help to finish it
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.
# 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
I’d use a library for this.
<a href="https://usspvlclovertch2.infor.com/viewtopic.php?t=4886″ class=”bbcode_url”>https://usspvlclovertch2.infor.com/viewtopic.php?t=4886
Your code would look something like this:
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]
Thank you very much to both David and Charlie, now I have a better understanding for my next script.
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
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.
In windows it is the same on HCIROOT and just unzip it ?
Thanks again David
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.
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.
It does not look like you are splitting by the subfield separator, so your pid33 variable is not a list.
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.
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.
Here is one we use here at times.
#########################################################################################
#########################################################################################
#########################################################################################
# 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]
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]
thank you all, I will try all the suggestions and test it out.
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.
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.
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.
Yes I am running it via testing tool
Isn’t it erring on an undefined variable?
In any event, did you make the change and does it work now?
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.
i copied your script and got it worked fine for me with no modifications.
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.
Have you looked in the error database?
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.
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.
🤓
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?
i only did mine in the testing tool. i did not put it in a thread and test that way.
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? 😉
I will try it with the echo.
Really appreciate you guys help on this.