1st Appearance: Version 1.0.6
Class Name: HTSQLHL7Message (HL7 Message Parser)
Scope: Public - Restricted ( License Required )
Accessed through the SQLSchemaAPIKey object NewHL7Message() methods or through other classes like the HL7StringAnalyzer.
When using the HTSQLHL7Message class it is important to review how HL7 messages are structured and to be able to relate that structure to an object-oriented .Net mindset. So first of all we need to understand that the purpose of the class is to address the HL7 data in the message. To do that we need to know what are the data elements that make up a message, and what is their precision and scope.
Start with the ATOM. In every HL7 message the "atomic" element, the smallest most precise piece of data that we can address is the Sub-Component value. Let's look at the structure of a message and see how we drill down from the top level HTSQLHL7Message class to the atomic elements that make up the data in the message speaking in .Net terminology.
•At the most basic level a HL7 Message is made of a List of HL7 Segments (see HTSQLHL7Segment) •A HL7 Segment is made up of a List of HL7 Fields (see HTSQLHL7Field). •HL7 Fields can repeat so the HL7 Field is the most complex class. It is made up of a List of List of HL7 Components ( C#: List<List<HTSQLHL7Component>> ) (see HTSQLHL7Component). •And finally the HL7 Component is made up of a List of Sub-Components, and each element in THAT List is the "atomic" Sub-Component value.
How to address the data. Consider the HL7 fragment below:
MSH|^~\&|Hospital 1|Lab 2|EMR|..........data.....data PID|1|87915261|1216960339..........data.....data PD1|||NULL^^0|491204^..........data.....data XYZ|1|2|A^B^C~D^E^F^G&SC2&????|..........data.....data
Our mission is retrieve the atomic data element ????. We do the following (Pseudo-Code)
1.Use our HTSQLHL7Message object to retrieve the XYZ segment from the message (if one exists) which we do through the various GetSegment() methods in this class. 2.Use the retrieved HTSQLHL7Segment object for the XYZ to retrieve Field #3 (if it exists) which we do using the FieldCount() and Field() methods in that class. 3.In our HTSQLHL7Field object for Field #3 of the XYZ Segment we could retrieve the value directly using the GetComponentValue() method but for the purposes of full illustration let's dig deeper. We can tell by the ~ that Field #3 is a repeating field and that the data we want to address is in the 2nd instance. The raw value for the 2nd instance of Field #3 is this ( D^E^F^G&SC2&???? ) what we want is Component #4 ( G&SC2&???? ). So in our HTSQLHL7Field object we can query if Component #4 exists by calling IF ComponentExists(4, 2) where 4 is the Component we want and 2 is the Instance to look in. If that returns True we can use GetComponent(4, 2) to retrieve our HTSQLComponent object. 4.Finally we are at the end and we have our HTSQLComponent object which represents Component #4 of Instance #2 of Field #3 of the XYZ segment of our HTSQLHL7Message. We can tell by the & that the data we want is in Sub-Component #3 ( G is #1, SC2 is #2) so we can access our data by calling GetSubComponentValue(3) and we will now know what exactly the real value of ???? is.
In real-life programming code you will rarely need to do a "deep dive" like this. You will use accessor methods in higher level objects to read this atomic level data but it is important to understand what those methods are actually doing when called.
|
Boolean IsLoaded - Is there a HL7 message loaded into the object.
String HL7RawValue - The value passed in to LoadHL7MessageString(). **NOTE: This value will ALWAYS be the String value that was used to initially load the object instance. The actual VALUE may vary slightly (see below). String Value - The Value property of this class object. It will typically be slightly different from the HL7RawValue depending on your PreferrredEncoder settings, OR if you have used any of the read/write MSH Accessor properties to change values in the MSH segment.
HTSQLHL7Segment MSHSegment - Will be Null if IsLoaded is False. Whenever a message is successfully loaded into this class the MSHSegment object property is instantiated for you automatically. This value is the functional equivalent of calling GetSegment(1).
String PartnerApp (*Special) (Read-Only) If not IsLoaded will be "". This field is a concatenation of MSH segment values which together with the MessageControlID are part of a Unique Index on your <prefix>_HL7DataTable. Used for identifying duplicate messages in the database. It is a concatenation of: SendingApplication + SendingFacility + ReceivingApplication + ReceivingFacility + MessageType + MessageEvent + MessageDate.
Integer SegmentCount - The number of segments contained in the message. Will be 0 if IsLoaded is False. Import Operations Properties
String MessageID - The internal GUID MessageID assigned to the HL7 message in the database AFTER a successful Import Operation. Will be "" otherwise. (The Primary Key in your <prefix>_HL7Data Table). Integer LoadCount - The number of times the HL7 message has been loaded into your Schema Tables. Will be 0 until AFTER a successful import operation. See the general help on this value. Unless you are testing or have a legitimate business reason to have processed the same message multiple times, a value greater than 1 in this field generally indicates a problem.
Performance Metrics Properties
Test the performance of various operations performed by this class using a standard .Net TimeSpan object. Evaluate (OperationEnded - OperationStarted).TotalSeconds.
DateTime OperationStarted - The starting time of various operations performed by this class (Import Operations, Training Operations, Parsing Operations, etc). The value is reset for each operation and the default value is SQLAPIGlobals.UndefinedDateValue.
DateTime OperationEnded - The ending time of various operations performed by this class (Import Operations, Training Operations, Parsing Operations, etc). The value is reset for each operation and the default value is SQLAPIGlobals.UndefinedDateValue.
NOTE: These properties always reflect the LAST qualifying operation performed by the class instance. If no operation has been performed the values will be SQLAPIGlobals.UndefinedDateValue. Valid operations for this class are Parsing Operations [ LoadHL7MessageString() ], Import Operations [ ImportMessage() ], and Training Operations [ TrainMessage() ]
|
MSH Accessor Properties
Component Level Accessors. Allows read/write access to specific atomic component values in the MSH segment. Example: MessageControlID is the functional equivalent of calling MSHSegment.Field(10).GetComponentValue(1,1).
If the class has been loaded (IsLoaded = True) you can access these properties into the MSH Segment.
String MessageControlID (MSH 10.1)
String SendingApplication (MSH 3.1) String SendingFacility (MSH 4.1) String ReceivingApplication (MSH 5.1) String ReceivingFacility (MSH 6.1) String MessageDate (MSH 7.1) (Read-Only) Set with SetMessageDate(DateTime) method. String MessageType (MSH 9.1) String MessageEvent (MSH 9.2) String TestProdFlag (MSH 11.1) String MessageVersion (MSH 12.1) String AcceptAcknowledgementType (MSH 15.1) String ApplicationAcknowledgementType (MSH 16.1) MSH Accessor Properties..Continued
Field Level Accessors - Properties above allow you to set individual component values. Field level accessors below allows read/write access to the entire HL7 field values in the MSH segment. Example: MessageControlIDField is the functional equivalent of calling MSHSegment.Field(10).Value
String MessageControlIDField (MSH 10.0)
String SendingApplicationField (MSH 3.0) String SendingFacilityField (MSH 4.0) String ReceivingApplicationField (MSH 5.0) String ReceivingFacilityField (MSH 6.0) String MessageDateField (MSH 7.0) String MessageTypeField (MSH 9.0) String MessageEvent (MSH 9.2) No need for this field it's part of MessasgeTypeField String TestProdFlagField (MSH 11.0) String MessageVersionField (MSH 12.0) String AcceptAcknowledgementTypeField (MSH 15.0) String ApplicationAcknowledgementTypeField (MSH 16.0)
|
HTSQLHL7Message Copy()
Returns: A copy of the HTSQLHL7Message object (even if empty).
Programming Note: See the discussion on "Object Ownership" at the bottom of this page. When you call the Copy() method the resulting message object will be "owned" by your code as if it were created using any of the SQLSchemaAPIKey.NewHL7Message() methods. It is also important to know that the HL7RawValue property of the new object will NOT necessarily be exactly identical to the HL7RawValue property of the source object. When Copy() is called the Value property of the source object is used to create the new object and thus the HL7RawValue property of the new object will be that.
HTSQLHL7Segment GetSegment(Integer) Parameter 1: Integer - index. The ordinal position within the message of the segment you wish.
Returns: The Segment object at ordinal position index in the message. Valid value for index are between 1 and SegmentCount. Null is returned and LastException is set if index is invalid.
Example: In a loaded object GetSegment(1) will always return the MSH segment (technically unnecessary because of the MSHSegment property). List<HTSQLHL7Segment> GetSegmentsNamed(2 Overloads) Overload 1: Parameter 1: String - segmentName. The name of the HL7 segment(s) you wish to retrieve. Overload 2: Parameter 1: List<String> - segmentNames. A string list containing the names of HL7 segments you wish to retrieve.
Returns: A standard List object containing all HL7 segments in the message with segment names that match your request. Empty List objects returned if not found or an Exception occurs.
Boolean LoadHL7MessageString(String) Parameter 1: String - hl7MessageString. String containing ONE (1) fully formed HL7 message
Returns: Boolean Success/Failure - Failure follows the common exception interface of other objects.
Description: Populates the object with a Parsing Operation. HL7MessageString is parsed and the message object is created. This method is automatically called by the constructor if you pass a hl7MessageString when creating the object. **You can get metrics on this operation with the OperationStarted and OperationEnded properties.
Programming Note: This object is designed for reuse. You will notice better performance when you create the object once and reuse it over and over again for the lifetime of the "parent" object by calling LoadHL7MessageString() with new messages. Import Operations **Performance Metrics are set for these operations (See Properties) HL7ImportResults ImportMessageResult()
Returns: HL7ImportResults - Results of the import operation. Description: Performs an Import Operation and attempts to import the HL7 message into the Schema Database as an inbound message. **You can get metrics on this operation with the OperationStarted and OperationEnded properties.
Boolean ImportMessage()
Returns: Boolean Success/Failure - Failure follows the common exception interface of other objects.
Description: Performs an Import Operation and attempts to import the HL7 message into the Schema Database as an inbound message. **You can get metrics on this operation with the OperationStarted and OperationEnded properties.
Boolean InitializeForImporting()
Returns: Boolean Success/Failure - Failure follows the common exception interface of other objects.
Description: You can call this method before you begin import operations. When performing import operations there is some initial overhead loading or refreshing the internal UPSInfo derived subclass. Calling this method ONCE before you begin multiple import operations will let you effectively "preload" that object instance. Calling this method is NOT mandatory, if you don't, it will be invoked automatically on the first import operation performed by the object instance. The only side-effect you might see is that if you are reusing your HTSQLHL7Message object (which you can and are encouraged to do for best performance) in a "LoadHL7MessageString() --> ImportMessage() -->Repeat--<" loop you might notice that the 1st operation takes slightly longer to complete.
Training Operations **Performance Metrics are set for these operations (See Properties)
SchemaTrainingResults TrainMessage(Boolean) Parameter 1: Boolean - autoFix (Optional Default is False). Automatically execute suggested SQL fixes if detected default is False.
Returns: SchemaTrainingResults - Results of the operation.
Description: Performs a schema training operation on a single message (see SchemaTrainingResults). **You can get metrics on this operation with the OperationStarted and OperationEnded properties.
Boolean SegmentExists(String) Parameter 1: String - segmentName. The name of the HL7 segment you wish to know if exists in the message ("PID", "IN1", "OBR", etc) .
Returns: Boolean True/False.
Integer SegmentIndex(String, Optional Integer) Parameter 1: String - segmentName. The name of the HL7 segment you wish get the index for. Parameter 2: Integer - startingIndex. Default = 1. Where to start looking for segmentName in the message.
Returns: Integer A value between 1 and SegmentCount or -1 if not found.
Integer SegmentsCount(String, Optional Integer) Parameter 1: String - segmentName. The name of the HL7 segment you wish get the count of. Parameter 2: Integer - startingIndex. Default = 1. Where to start looking for segmentName in the message. |
Returns: Integer The total number of HL7 segments named segmentName found in the HL7 message or 0 if none are found.
Void SetMessageDate(DateTime, HL7DateTimePrecision) - Parameter 1: DateTime - newMessageDate. The date value to set in the MSH segment. Parameter 2: HL7DateTimePrecision - optionalPrecision. What timestamp precision to use. The default is HL7DateTimePrecision.enSeconds.
|
Event TransactionRunning(object sender, eventArgs e) Parameter 1: sender will be of type HTSQLServerConnector. Parameter 2: e will be of derived class HTExceptionEventArg.
Trigger: Fired whenever a multi-command SQL transaction is underway. The event is fired before every command is executed. Implementation: This class uses the HTSQLServerConnector internally and passes this event through to be picked up and fired in other classes derived from the UPSInfo class. Set e.Cancel() to cancel the operation and rollback the SQL Transaction.
|
Important! Object "Ownership" and what that means
Some functionality with this class may be enabled or curtailed by HOW the object is created which can dictate which class object "owns" the HL7 message.
•Scenario #1: If the HL7 message object instance is created internally by the HL7StringAnalyzer class when you use it to "analyze" a String or LoadFromFile() that HL7StringAnalyzer "owns" the object instance. You can't retrieve an object from the string analyzer calling HL7StringAnalyzer.GetMessageObject() and then call any of the public Import Operations in that HTSQLHL7Message object or an exception will be thrown. In this instance you would need to call HL7StringAnalyzer.ImportMessage() to perform an Import Operation on that object instance. •Scenario #2: If the HL7 message object instance is created using any of the HL7DefinitionData.NewHL7Message() methods that HL7DefinitionData object "owns" the HTSQLHL7Message object instance. You can perform all operations BUT you can't modify the PreferredEncoder property (well, you can but any changes are ignored). In every parsing operation the HL7MessageEncoder returned from HL7DefinitionData.VendorMessageEncoder property will be used. •Scenario #3: IF the HL7 message object was created by your application from code using any of the SQLSchemaAPIKey.NewHL7Message() methods. Then you "own" that object instance and all methods and properties will perform "as expected" with no limitations. Additionally your code can "take ownership" of a copy of any HTSQLHL7Message object instance by calling the Copy() method described in Public Methods above.
|
Exception Handling: Follows the Common Exceptions Interface.
