I’ve inherited a code to create an HL7 message parsing application. It parses HL7 fields into a spreadsheet. I need to edit the code so that it parses additional HL7 fields. I tried to open, add new fields/delete unwanted fields, and save the changes but the changes were not reflected in the spreadsheet. Here’s the code below where I added MSH_3, MSH_7, and EVN segment:
import os
import csv
import datetime as DT
import hl7
from tkinter import *
from tkinter import filedialog
from time import sleep
import winsound
def split_HL7file(hl7file):
hl7file = open(hl7file, ‘r+’).read().replace(‘\n’, ‘\r’)
rv =
for line in hl7file.split(‘\r’):
line = line.strip()
if line[:3] in [‘FHS’, ‘BHS’, ‘FTS’, ‘BTS’]:
continue
if line[:3] == ‘MSH’:
newmsg = [line]
rv.append(newmsg)
else:
if len(rv) == 0:
#logger.error(‘Segment received before message header [%s]’, line)
continue
rv[-1].append(line)
rv = [‘\r’.join(msg) for msg in rv]
for i, msg in enumerate(rv):
if not msg[-1] == ‘\r’:
rv[i] = msg + ‘\r’
return rv
def retrieveSegment(message, segmentAbbrev, segmentIndex1=None,segmentIndex2=None,segmentIndex3=None,segmentIndex4=None):
segmentStr = '\t'+segmentAbbrev +' '+ str(segmentIndex1)+'.'+ str(segmentIndex2)+'.'+ str(segmentIndex3)
try:
if segmentIndex1 == None:
#return message.segment(segmentAbbrev)
return '\n'+segmentAbbrev +'\t'+'\t'+ str(message.segment(segmentAbbrev)) +'\n'
elif segmentIndex2 == None:
#return message.segment(segmentAbbrev)[segmentIndex1]
return '\t'+segmentAbbrev + ' ' + str(segmentIndex1)+'\t'+ str(message.segment(segmentAbbrev)[segmentIndex1])
elif segmentIndex3 == None:
#return message.segment(segmentAbbrev)[segmentIndex1](segmentIndex2)
return '\t'+segmentAbbrev + ' ' + str(segmentIndex1)+ '.' + str(segmentIndex2)+'\t'+ str(message.segment(segmentAbbrev)[segmentIndex1](segmentIndex2))
else:
#print('\t'+segmentAbbrev + ' ' + str(segmentIndex1)+ '.' + str(segmentIndex2)+ '.' + str(segmentIndex3)+'\t'+ str(message.segment(segmentAbbrev)[segmentIndex1](segmentIndex2)(segmentIndex3)))
return '\t'+segmentAbbrev + ' ' + str(segmentIndex1)+ '.' + str(segmentIndex2)+ '.' + str(segmentIndex3)+'\t'+ str(message.segment(segmentAbbrev)[segmentIndex1](segmentIndex2)(segmentIndex3))
#return message.segment(segmentAbbrev)[segmentIndex1](segmentIndex2)(segmentIndex3)
except Exception as e:
return segmentStr+'\t'+str(e)
def retrieveSegmentNoLabel(message, segmentAbbrev, segmentIndex1=None,segmentIndex2=None,segmentIndex3=None,segmentIndex4=None):
#segmentStr = segmentAbbrev +' '+ str(segmentIndex1)+'.'+ str(segmentIndex2)+'.'+ str(segmentIndex3)
try:
if segmentIndex1 == None:
#return message.segment(segmentAbbrev)
return str(message.segment(segmentAbbrev))
elif segmentIndex2 == None:
#return message.segment(segmentAbbrev)[segmentIndex1]
return str(message.segment(segmentAbbrev)[segmentIndex1])
elif segmentIndex3 == None:
#return message.segment(segmentAbbrev)[segmentIndex1](segmentIndex2)
return str(message.segment(segmentAbbrev)[segmentIndex1](segmentIndex2))
else:
#print('\t'+segmentAbbrev + ' ' + str(segmentIndex1)+ '.' + str(segmentIndex2)+ '.' + str(segmentIndex3)+'\t'+ str(message.segment(segmentAbbrev)[segmentIndex1](segmentIndex2)(segmentIndex3)))
return str(message.segment(segmentAbbrev)[segmentIndex1](segmentIndex2)(segmentIndex3))
#return message.segment(segmentAbbrev)[segmentIndex1](segmentIndex2)(segmentIndex3)
except Exception as e:
return str(e)
#for messageUnit in range(0, length):
#print(segment, str(strNumber)[messageUnit])
#return message.segment(segmentAbbrev)
def get_Folder():
root = Tk()
root.wm_withdraw()
data_folder = str(filedialog.askdirectory(initialdir =os.getcwd())) + ‘/’
root.destroy()
return data_folder #print(addressFile)
def py_goo_Enter(insertString): # creates a log entry when the application is started
insertString=insertString+‘\n’
frame2Text.configure(state=‘normal’) #enables text in Text widget to be altered by INSERT command in next line
frame2Text.insert(INSERT, insertString) #INSERTs argument into Text widget
frame2Text.see(‘end’)
frame2Text.configure(state=‘disabled’) #prevents text in Text widget from being altered by user. Purely for aesthetics
frame2Text.update_idletasks()
timestampString=DT.datetime.today().strftime(‘%Y%m%d%H%M%S’)
dataFolder = get_Folder()
parserOutputFilePath = dataFolder + ‘HL7_ParserOutput_v’+ timestampString +‘.csv’
parserOutputHeader = [‘fileName’,‘MSH’, ‘MSH.3’, ‘MSH.4.1.1’, ‘MSH.4.1.2’, ‘MSH.5’, ‘MSH.6’, ‘MSH.7’, ‘MSH.9.1.1’, ‘MSH.9.1.2’, ‘MSH.9.1.3’, ‘MSH.10’, ‘MSH.11’, ‘MSH.12’, ‘EVN’, ‘EVN.7.1.2’, ‘PID’, ‘PID.3.1.1’, ‘PID.5.1.1’, ‘PID.5.1.2’, ‘PID.7.1’, ‘PID.8.1’, ‘PID.10.1’, ‘PID.11.1.1’, ‘PID.11.1.2’, ‘PID.11.1.3’, ‘PID.11.1.4’, ‘PID.11.1.5’, ‘PID.11.1.6’, ‘PID.11.1.9’, ‘PID.13.1.1’, ‘PID.22.1’, ‘ORC’, ‘ORC.21.1.1’, ‘ORC.22.1.1’, ‘ORC.22.1.2’, ‘ORC.22.1.3’, ‘ORC.22.1.4’, ‘ORC.22.1.5’, ‘ORC.23.1.1’, ‘OBR’, ‘OBR.0’, ‘OBR.1’, ‘OBR.3.1.1’, ‘OBR.3.1.2’, ‘OBR.4.1.1’, ‘OBR.7.1’, ‘OBR.14.1’, ‘OBR.15’, ‘OBR.16.1.2’, ‘OBR.16.1.3’, ‘OBR.17.1.1’, ‘OBR.17.1.6’, ‘OBX’, ‘OBX.1.1’, ‘OBX.2.1’, ‘OBX.3.1.1’, ‘OBX.3.1.2’, ‘OBX.5.1.1’, ‘OBX.5.1.2’, ‘OBX.7’, ‘OBX.14.1’ ]
parserOutputFile = open(parserOutputFilePath, ‘w’, newline=‘’)
parserOutputWriter = csv.writer(parserOutputFile, delimiter=‘,’)
parserOutputWriter.writerow(parserOutputHeader)
py_goo_Window = Tk()
py_goo_Window.geometry(‘1200x700’)
py_goo_Window.title(‘PyParser7.exe’)
py_goo_Window.lift()
py_goo_Window.attributes(‘-topmost’, True)
py_goo_Window.attributes(‘-topmost’, False)
frame2 = Frame(py_goo_Window)
frame2.pack(side = BOTTOM )
frame2Scrollbar = Scrollbar(frame2,bd=3 )
frame2Scrollbar.pack( side = RIGHT, fill = Y )
frame2Text = Text(frame2, wrap=WORD, width = 131, height= 23, font=(“Garamond”, 14), spacing1=8, relief=GROOVE,bd=3)
frame2Text.pack(fill=“none”, expand=TRUE)
frame2Scrollbar.config( command = frame2Text.yview )
#currentPath = os.getcwd()
py_goo_Enter(‘----------------------------------------------------’)
py_goo_Enter(‘Data Path = ‘+ dataFolder)
py_goo_Enter(’----------------------------------------------------’)
py_goo_Enter(‘Output file = ’ + parserOutputFilePath)
py_goo_Enter(’----------------------------------------------------')
fileCounter=0
for root, dirs, files in os.walk(dataFolder):
fileCount = len(files)
for fileName in files:
fileCounter +=1
py_goo_Enter('----------------------------------------------------')
py_goo_Enter('Processing File: '+fileName+ '\t'+ str(fileCounter) + ' of ' + str( fileCount))
py_goo_Enter('----------------------------------------------------')
fileNamePath=dataFolder+fileName
messages = split_HL7file(fileNamePath)
messageCount = len(messages)
messageCounter = 1
for message in messages:
parsed_msg = hl7.parse(message)
py_goo_Enter('----------------------------------------------------')
py_goo_Enter('Message '+ str(messageCounter) + ' of ' + str(messageCount))
MSH = retrieveSegmentNoLabel(parsed_msg, 'MSH')
MSH_3 = retrieveSegmentNoLabel(parsed_msg, 'MSH', 3)
MSH_4_1_1 = retrieveSegmentNoLabel(parsed_msg, 'MSH', 4, 1, 1)
MSH_4_1_2 = retrieveSegmentNoLabel(parsed_msg, 'MSH', 4, 1, 2)
MSH_4_1_3 = retrieveSegmentNoLabel(parsed_msg, 'MSH', 4, 1, 3)
MSH_5 = retrieveSegmentNoLabel(parsed_msg, 'MSH', 5)
MSH_6 = retrieveSegmentNoLabel(parsed_msg, 'MSH', 6)
MSH_7 = retrieveSegmentNoLabel(parsed_msg, 'MSH', 7)
MSH_9_1_1 = retrieveSegmentNoLabel(parsed_msg, 'MSH', 9, 1, 1)
MSH_9_1_2 = retrieveSegmentNoLabel(parsed_msg, 'MSH', 9, 1, 2)
MSH_9_1_3 = retrieveSegmentNoLabel(parsed_msg, 'MSH', 9, 1, 3)
MSH_10 = retrieveSegmentNoLabel(parsed_msg, 'MSH', 10)
MSH_11 = retrieveSegmentNoLabel(parsed_msg, 'MSH', 11)
MSH_12 = retrieveSegmentNoLabel(parsed_msg, 'MSH', 12)
EVN = retrieveSegmentNoLabel(parsed_msg, 'EVN')
EVN_7_1_2 = retrieveSegmentNoLabel(parsed_msg, 'EVN', 7, 1,2)
PID = retrieveSegmentNoLabel(parsed_msg, 'PID')
PID_3_1_1 = retrieveSegmentNoLabel(parsed_msg, 'PID', 3, 1, 1)
PID_5_1_1 = retrieveSegmentNoLabel(parsed_msg, 'PID', 5, 1, 1)
PID_5_1_2 = retrieveSegmentNoLabel(parsed_msg, 'PID', 5, 1, 2)
PID_7_1 = retrieveSegmentNoLabel(parsed_msg, 'PID', 7, 1)
PID_8_1 = retrieveSegmentNoLabel(parsed_msg, 'PID', 8, 1)
PID_10_1 = retrieveSegmentNoLabel(parsed_msg, 'PID', 10, 1)
PID_11_1_1 = retrieveSegmentNoLabel(parsed_msg, 'PID', 11, 1, 1)
PID_11_1_2 = retrieveSegmentNoLabel(parsed_msg, 'PID', 11, 1, 2)
PID_11_1_3 = retrieveSegmentNoLabel(parsed_msg, 'PID', 11, 1, 3)
PID_11_1_4 = retrieveSegmentNoLabel(parsed_msg, 'PID', 11, 1, 4)
PID_11_1_5 = retrieveSegmentNoLabel(parsed_msg, 'PID', 11, 1, 5)
PID_11_1_6 = retrieveSegmentNoLabel(parsed_msg, 'PID', 11, 1, 6)
PID_11_1_9 = retrieveSegmentNoLabel(parsed_msg, 'PID', 11, 1, 9)
PID_13_1_1 = retrieveSegmentNoLabel(parsed_msg, 'PID', 13, 1, 1)
PID_22_1 = retrieveSegmentNoLabel(parsed_msg, 'PID', 22, 1)
ORC = retrieveSegmentNoLabel(parsed_msg, 'ORC')
ORC_21_1_1 = retrieveSegmentNoLabel(parsed_msg, 'ORC', 21, 1, 1)
ORC_22_1_1 = retrieveSegmentNoLabel(parsed_msg, 'ORC', 22, 1, 1)
ORC_22_1_2 = retrieveSegmentNoLabel(parsed_msg, 'ORC', 22, 1, 2)
ORC_22_1_3 = retrieveSegmentNoLabel(parsed_msg, 'ORC', 22, 1, 3)
ORC_22_1_4 = retrieveSegmentNoLabel(parsed_msg, 'ORC', 22, 1, 4)
ORC_22_1_5 = retrieveSegmentNoLabel(parsed_msg, 'ORC', 22, 1, 5)
ORC_23_1_1 = retrieveSegmentNoLabel(parsed_msg, 'ORC', 23, 1, 1)
OBR = retrieveSegmentNoLabel(parsed_msg, 'OBR')
OBR_0 = retrieveSegmentNoLabel(parsed_msg, 'OBR', 0)
OBR_1 = retrieveSegmentNoLabel(parsed_msg, 'OBR', 1)
OBR_3_1_1 = retrieveSegmentNoLabel(parsed_msg, 'OBR', 3, 1, 1)
OBR_3_1_2 = retrieveSegmentNoLabel(parsed_msg, 'OBR', 3, 1, 2)
OBR_4_1_1 = retrieveSegmentNoLabel(parsed_msg, 'OBR', 4, 1, 1)
OBR_7_1 = retrieveSegmentNoLabel(parsed_msg, 'OBR', 7, 1)
OBR_14_1 = retrieveSegmentNoLabel(parsed_msg, 'OBR', 14, 1)
OBR_15 = retrieveSegmentNoLabel(parsed_msg, 'OBR', 15)
OBR_16_1_2 = retrieveSegmentNoLabel(parsed_msg, 'OBR', 16, 1, 2)
OBR_16_1_3 = retrieveSegmentNoLabel(parsed_msg, 'OBR', 16, 1, 3)
OBR_17_1_1 = retrieveSegmentNoLabel(parsed_msg, 'OBR', 17, 1, 1)
OBR_17_1_6 = retrieveSegmentNoLabel(parsed_msg, 'OBR', 17, 1, 6)
OBR_38_1_1 = retrieveSegmentNoLabel(parsed_msg, 'OBR', 38, 1, 1)
OBX = retrieveSegmentNoLabel(parsed_msg, 'OBX')
OBX_1_1 = retrieveSegmentNoLabel(parsed_msg, 'OBX', 1, 1)
OBX_2_1 = retrieveSegmentNoLabel(parsed_msg, 'OBX', 2, 1)
OBX_3_1_1 = retrieveSegmentNoLabel(parsed_msg, 'OBX', 3, 1, 1)
OBX_3_1_2 = retrieveSegmentNoLabel(parsed_msg, 'OBX', 3, 1, 2)
OBX_5_1_1 = retrieveSegmentNoLabel(parsed_msg, 'OBX', 5, 1, 1)
OBX_5_1_2 = retrieveSegmentNoLabel(parsed_msg, 'OBX', 5, 1, 2)
OBX_7 = retrieveSegmentNoLabel(parsed_msg, 'OBX', 7)
OBX_14_1 = retrieveSegmentNoLabel(parsed_msg, 'OBX', 14, 1)
parserOutputRow = [fileName, MSH, MSH_3, MSH_4_1_1, MSH_4_1_2, MSH_4_1_3, MSH_5, MSH_6, MSH_7, MSH_9_1_1, MSH_9_1_2, MSH_9_1_3, MSH_10, MSH_11, MSH_12, EVN, EVN_7_1_2, PID, PID_3_1_1, PID_5_1_1, PID_5_1_2, PID_7_1, PID_8_1, PID_10_1, PID_11_1_1, PID_11_1_2, PID_11_1_3, PID_11_1_4, PID_11_1_5, PID_11_1_6, PID_11_1_9, PID_13_1_1, PID_22_1, ORC, ORC_21_1_1, ORC_22_1_1, ORC_22_1_2, ORC_22_1_3, ORC_22_1_4, ORC_22_1_5, ORC_23_1_1, OBR, OBR_0, OBR_1, OBR_3_1_1, OBR_3_1_2, OBR_4_1_1, OBR_7_1, OBR_14_1, OBR_15, OBR_16_1_2, OBR_16_1_3, OBR_17_1_1, OBR_17_1_6, OBR_38_1_1, OBX, OBX_1_1, OBX_2_1, OBX_3_1_1, OBX_3_1_2, OBX_5_1_1, OBX_5_1_2, OBX_7, OBX_14_1]
parserOutputWriter.writerow(parserOutputRow)
messageCounter +=1
parserOutputFile.close()
py_goo_Enter(‘----------------------------------------------------’)
py_goo_Enter(‘Output file = ’ + parserOutputFilePath)
py_goo_Enter(’----------------------------------------------------')
py_goo_Enter(‘\nend\n’)
beepFrequency = 1000 # Hertz
beepDuration = 500 # milliseconds
sleepDuration = .15
winsound.Beep(beepFrequency, beepDuration)
sleep(sleepDuration)
winsound.Beep(beepFrequency, beepDuration)
sleep(sleepDuration)
winsound.Beep(beepFrequency, beepDuration)
py_goo_Window.mainloop() # Whew!
Any suggestions on how to do the edits will be appreciated.
Thank you