HL7Spy 20.2.2 Released

  • Improvement – HL7 Sender Tool – Support for SSH Tunnel. Create a secure SSH tunnel to a remote HL7 Server – Requested by Paul C. from diridium.com
  • Improvement – Editor – Support for opening and drag-drop encrypted Cloverleaf smatdb files – requested by Keith M. from thechristhospital.com
  • Improvement – Sql Loader – Support for opening and drag-drop encrypted Cloverleaf smatdb files – requested by Keith M. from thechristhospital.com
  • Improvement – HL7 Editor – Better handling of large HL7 fields within a segment (OBX-5). Large fields are now collapsed to improve message readability. The size of the field is displayed in brackets. Do see the full field, double click on the collapsed region.
  • Improvement – HL7 Editor – Larger HL7 keyboard tooltips. They can be turned on/of (Ctrl+k,Ctrl+k). Hold down the Control key and move the mouse to a field with in the message also displays the tooltip.
  • Improvement – Segment Editor  – Support for OBX-5 variable data types
  • Improvement – Better sizing of columns in the SegmentEditor and HL7  Code table grids
  • Impvovement – HL7 Editor – Support for decoding a multi-part embedded OBX-5 field, for example an embedded pdf document split across multiple OBX segments
  • Improvement – HL7Standard Tool – Show Components/Subcomponents for search results
  • Improvement – HL7 Editor – Track temp files that were opened from OBX-5 encapsulated fields and delete them when HL7Spy exits
  • Improvement – Bulk Compare Tool – Sort field differences by Message Index, then HL7Path – request by Gavin M. from health.telstra.com
  • Improvement – Bulk Compare Tool – Save Ignore Paths when right-clicking and selecting “Ignore” in the Diff tool editor – requested by Gavin M. from health.telstra.com
  • Improvement – Diff Tool – Update DiffView when settings change in BulkCompareView’s ignore fields
  • Improvement – Speed up application startup
  • Improvement – Better handing of Windows Domain licenses for Enterprise customers
  • Improvement – Add support for per user settings for Enterprise customers
  • Improvement – Better display of Z-Segments in Segment Editor
  • Improvement – HL7 Transform Tool – Add more transform functions like Upper, Lower, Insert/Add Segment – requested by Len.F. health.qld.gov.au
  • Improvement – HL7 Transform Tool – Add a drop-down of available functions
  • Improvement – Custom Code Tool – Add right-click copy rows from Events table – requested by Len F. from health.qld.gov.au
  • Improvement – Rework the HL7 Send dialog for better space utilization
  • Bug Fix – File Save – Cannot set the Frame End setting to change the message end-of-frame character – reported by Mike T. from amwell.com
  • Bug Fix – Fix Batch Send View so that the FHS and BHS configurations can be modified
  • Bug Fix – HL7Sender Tool – Fix issue where SSL Validation in UI not happening at the correct time
  • Bug Fix – Show better error to user when Excel Export fails
  • Bug Fix – Advanced Statistics in v2020 do not report the same values as v3.1. Reported by Iris C. from cdph.ca.gov
  • Bug Fix – Highlight Field Tool- Fix exception when Segment Path is selected as a Highlight Path Support wildcard paths
  • Bug Fix – Bulk Compare Tool – Clear out Diff view when selecting a row in the Summary Grid row
  • Bug Fix – Ftp Explorer Tool – Fix issue with resetting the Master password
  • Bug Fix – Custom Code Tool – Fix [ArgumentOutOfRangeException] Specified argument was out of the range of valid values.
  • Bug Fix – HL7 Parser – Exception including entire contents of a large binary file with no messages
  • Bug Fix – HL7Spy not opening up a file when double-clicking it from Windows Explorer – reported by Jared R. from Queens University
  • Bug Fix – Fix spelling of Familiy name in v2.1 and v2.2 of the HL7 Standard

What’s new in HL7Spy 20.1?

Lots…

  • We have made HL7Spy faster. We improved the performance of loading the application, loading messages, query messages, performing statistics calculations on a field, and many other aspects of the application.
  • HL7Spy can handle more data. We have improved HL7Spy’s already unique ability to load 100’s of thousands of messages. In HL7Spy 2020.1 we have improved many features to handle the increased size of HL7 data streams. We have some customers that are loading 42,000,000 messages and running queries to generate reports. That’s a lot of messages!

Here is what its like to load 1.1 million messages from a 7-zip archive containing 10 files on a standard laptop.

Watch how fast it is when used to calculate the statistics on the MSH-9 field.

  • We went through the entire product and improved every window and dialog in the application. We asked ourselves how we can make them better, and we did. Check it out for yourself.
  • We added more options for saving the application layout, font sizing, opening behavior, saving/restoring application settings, and more.
  • We added the ability to set the font size of the editor and most data grids within the application. This is great if your eyes are getting older like mine.
  • We have updated all data grids, and tree grids in the application. Where useful, they now support searching, sorting, and data grouping.
  • The HL7 Editor has been revamped. In v2020 it is snappier, renders text more precisely,  handles large HL7 messages better, supports configurable field highlighting, and has a cool new search tool (shown below).
  • The Custom Code Tool – This tool is for power-users! It is amazing what you can do if you know a little C#. In v2020 this tool has been completely redone. It now supports the .NET 4.8 run-time, and C# 7.x language specification.
  • One of the great new features in HL7Spy v2020 is built for users who are migrating to a new HL7 Integration Engine, (like Rhapsody, or Corepoint –product plug intended). The Bulk Compare tool allows users to compare the output from their old integration engine with the output of their new one, to ensure that the outputs are equivalent before flipping the switch. The Bulk Compare Tool generates results that allow you to see exactly which messages and fields are different between two message streams. Statistics by message type and field are created. These results can be exported to PDF and Excel for reporting purposes.The Bulk Compare tool is fast, so fast. It can compare 100,000 messages in under 15 seconds. See it in action below.
  • HL7 Sender/Receiver – Improved SSL/TLS support.
  • Sql Loader tool – This tool has been updated for v2020.1 . We have also included  for InterSystems Caché/IRIS. (Thank you to Jeff Drumm for his help us get this feature into v2020!). Please see his article on how to set this up in your environment: https://community.intersystems.com/post/load-ensemble-messages-hl7-spy-v20201

HL7Spy v4 Beta – Bulk Compare Tool

New – HL7Spy v4 is ready for Beta testing!

HL7Spy v3 was released in June 2017. Since that time we have released over 40 new versions of HL7Spy in response to customer requests for new features and to make bug fixes (many more improvements that bug fixes :)). We are now releasing a major upgrade to HL7Spy with some great enhancements.

One of the great new features in HL7Spy v4 is built for users who are migrating to a new HL7 Integration Engine, (like Rhapsody, or Corepoint –product plug intended). The Bulk Compare tool allows users to compare the output from their old integration engine with the output of their new one to ensure that the outputs are equivalent before flipping the switch.

The Bulk Compare Tool generates results that allow you to see exactly which messages and fields are different between to message streams. Statistics by message type and field are created. These results can be export to PDF and Excel for reporting purposes.

The Bulk Compare tool is fast, so fast. It can compare 100,000 messages in under 15 seconds. See it in action below.

The Bulk Compare tool was developed in conjunction with Rhapsody’s Co-Creation Labs: https://rhapsody.health/co-creation-lab. It was a great opportunity for us to work with the experts in the integration space and create a comprehensive HL7 integration engine migration tool. We were happy and impressed with the co-creation result and we think you will be too.

More information about the Bulk Compare tool can be found in the HL7Spy v4 user manual here: Bulk Compare Tool.

Send and Receive HL7

In this example we are demonstrating sending HL7 messages from one instance of HL7Spy to another. Look how fast it sends 100,000 messages!

HL7Spy supports sending and receiving HL7 using SSL.

Write Custom Code in C#

Power users can write custom code in C# to do almost anything the .NET framework will allow you to do. In this simple example we are appending the text “-test” to the existing value of MSH-3.

Included in HL7Spy are examples of how to de-identify patient information, generate messages, and other more complex message processing routines.

Select All Messages for a Patient

By right-clicking on an HL7 field you can easy to select all messages for a patient. HL7Spy will query all messages, find those that match, and present an ordered list of messages.

If you want to compare any 2 messages, simply select any 2 messages from the list, then right-click and select the “Compare Messages”.

Getting Statistics on an HL7 Field

One of the most powerful features of HL7Spy is calculating statistics on a particular field. In this example we are loading 100,000 messages and getting the statistics on PV1-2. You will notice that 50,178 with value “O”, and 14,733 with the value “E”.

You can navigate values of a particular type by using the forward and back buttons as shown in the short clip.

You can also right-click on a field type, say “O” and send all messages with PV1-2=”O” to a separate tab.

Load Messages From Database

Messages can be loaded from Sql Server, Oracle, Postgres, My Sql and many other databases. HL7Spy will automatically detect which column contains the message data and will load the messages into the message editor. Clicking on a row in the result set will display the associated message in the Message Editor.

Load 100K Messages From a File

In this example we are loading 100,000 messages using the “Open File” menu option, then we are opening another 100,000+ messages by dragging and dropping them using Windows File Explorer.

HL7Spy v3.1.2360 Released

  • Improvement – Custom Code – HL7Field.IsEmpty() is inconsistent with property HL7Component.IsEmpty and HL7SubComponent.IsEmpty. Should replace with IsNullOrEmpty()
  • Improvement – Custom Code – Add helper methods to set the number of Fields, Repeats, Components, and Subcomponents
  • Improvement – Custom Code – Custom Code Events- Speed up “Copy All To Clipboard” – L.B. from cdph.ca.gov
  • Improvement – Open Folder – Remove annoying “No files found meeting the specified criteria” messagebox when there are no matches
  • Improvement – Installer – Add MessageBox when the .NET Framework cannot be downloaded
  • Bug Fix – Hex Editor – Fix Application Unhandled Exception. [NullReferenceException] Object reference not set to an instance of an object
  • Bug Fix – Field Statistics – System.NullReferenceException: ‘Object reference not set to an instance of an object.’
  • Bug Fix – [ObjectDisposedException] Cannot access a disposed object. Object name: ‘OpenFolderView’.
  • Bug fix – Custom Code – void OnError(Exception ex) not being called when there is no opened tab – reported by A.L. from musc.edu
  • Bug Fix – HL7 Parser – Fix index out of range exception
  • Bug Fix – HL7 Receiver – fix issue with SSL and security access error to cert.PrivateKey.KeyExchangeAlgorithm

HL7Spy v3.1.2345 Released

  • Improvement – Application – Improve startup performance by disabling checks for code-signed assemblies
  • Improvement – Statistics – Processing statistics across 21+ million messages resulted in an out of memory exception  – Reported by Larry B. from cdph.ca.gov
  • Improvement – UI components – Many bug fixes, usability and performance improvements
  • Improvement – Export to xls, and xlsx – Warn user when more than 65536 rows for xls, or 1048576 rows for xlsx are being exported (maximum number of rows allowed)
  • Improvement – FTP/SFTP libraries – Fixes a number of issues with connecting to some FTP/SFTP servers
  • Improvement – HL7 Receiver – Show SSL certs from both LocalMachine and LocalUser
  • Improvement – HL7 Receiver – Show thumbprint in Certificate window
  • Improvement – Open Folder – Speed up scanning when there are thousands of files
  • Improvement – Open Folder – Open Folder – Remove annoying “No files found meeting the specified criteria” message-box when there are no matches
  • Bug Fix- Open Folder – Fix potential issue when the Scan/Stop buttons are pressed quickly one after the other
  • Bug Fix- Open Folder – Clicking “Stop” during folder processing leaves the tool in an unusable state
  • Bug Fix- Open Folder – Unhandled exception when choosing Regex search with invalid Regex expression
  • Bug Fix – HL7 Send – SSL enabled and Certificate/Thumbprint empty does not encrypt the data but sends the data as clear text – Reported by Rick O. from hc1.com
  • Bug Fix – HL7 Receiver – fix issue with SSL and security access error to cert.PrivateKey.KeyExchangeAlgorithm
  • Bug Fix – Field Statistics – System.NullReferenceException: ‘Object reference not set to an instance of an object.’ in some rare situations

HL7Spy 3.1.2306 Released

  • Improvement – HL7 SQL – Add a “Save” button to manually save the query text  – Requested by Larry B. from cdph.ca.gov
  • Improvement – HL7 SQL – Add an option to not automatically save the Query text when the user clicks the “Execute” button
  • Improvement – Statistics – Speed up calculation of “Selected To Single New Tab” and “Not Selected To Single New Tab” – requested by Jeff D. from hshs.org
  • Bug Fix – Fix issue where results from a SELECT INTO new tab results in the messages indexes in the results being incorrect and therefore showing the incorrect message in the editor when clicked on in the results grid – Reported by Jeff B. from mhg.com
  • Bug Fix – Custom Code – Fix issue with Custom Code not saving correctly. All being saved to file “00000000-0000-0000-0000-000000000000.xml”
  • Bug Fix – Custom Code – Compile to user temp directory instead of the one in ProgramData\HL7Spy\temp
  • Bug Fix – Custom Code – Fix up location of the Actipro CacheSplash window
  • Bug Fix – Do not show files from the User’s temp directory in the Recent File List
  • Bug Fix – Save Recent File List on Application Exit

HL7Spy 3.1.2295 Released

  • Improvement – Add Certificate Selector in HL7 Receiver
  • Improvement – Speed up HL7Spy Installer
  • Improvement – Update to latest 3rd party libraries. Improves speed and stability of application
  • Improvement – Remove file from the Recent File List if an attempt to open it results in a file not found error
  • Bug Fix -FTP Explorer – Fix issue when remote directory doesn’t start with /
  • Bug Fix – Custom Code – Unable to change default HL7 message encoding characters
  • Bug Fix – Custom Code – Fix issue where _global_ custom code does not display unless you click to another function and back
  • Bug Fix – Custom Code – Compile to user temp directory instead of the one in ProgramData\HL7Spy\temp
  • Bug Fix – Increase the size of the message selector in the Bulk Compare tool
  • Bug Fix – Fix tab stops in Open Folder, Save As, and other pop-up dialog boxes – Reported by Michael W.
  • Bug Fix – Fix potential duplicate key exception in BaseView.AddCommandKey
  • Bug Fix – Fix issue where a window’s OnLoad can be called multiple times
  • Bug Fix – Show proper error when the .NET framework cannot be downloaded

HL7Spy 3.1.2273 Released

  • Improvement – Remember the last directory where data was exported to and reuse it next time another export is initiated. Requested by Jeff D from hicgrp.com
  • Improvement – Remove all intermediate Export dialogs and show the standard Windows SaveAs dialog instead. Requested by Jeff D from hicgrp.com
  • Improvement – Clean-up exporting from the Watch List
  • Improvement – Custom Code – Add more overloads to HL7Message.CombineObxsToObx5Repeats for transforming many OBX segments into 1 with repeating OBX-5
  • Improvement – Add an application option to Auto Open Export Files, or to just open File Explorer and select the file
  • Improvement – Handle loading multiple files where one, or more, has an access denied issue
  • Improvement – When Exporting to Excel, PDF, etc., reuse the same File Explorer instance to navigate to the file rather than opening a new one each time
  • Improvement – Update shortcuts for Field/Component/Subcomponent statistics
  • Improvement – Speed up loading of xz, zip, gz, etc. compressed files
  • Bug Fix – Fix issue where vv is placed on versions of HL7 Standard in the Export to Xml tool
  • Bug Fix – Remove double MessageBox request to overwrite a file when Exporting to Excel, pdf, etc. Reported by Jeff D. from hicgrp.com
  • Bug Fix – Fix issue where Recent File List not saving properly
  • Bug Fix – Fix OpenFolder search issue where filtering is not working properly – Reported by Sandy D. from aurora.org
  • Bug Fix – Custom Code – HL7DateTime.TryParse returns the datetime as being in the local timezone even if not timezone is in the DTM string
  • Bug Fix – Issue with “Redact messages to new Tab” when when tab contains multiple sources. Reported by David R from AGFA
  • Bug Fix – HL7Query – Fix Unhandled Exception. [ObjectDisposedException] Cannot access a disposed object.
  • Bug Fix – Fix An exception that was thrown during handling the topic ‘MessageCollectionRemoved’
  • Bug Fix – F11 should show/hide the Ribbon Bar but does not
  • Bug Fix – EventBroker – [InvalidOperationException] Sequence contains more than one matching element
  • Bug Fix – FileExplorer – SFTP error when navigating a directory that contains a file marked as FIFO. Reported by Jeff D. from HSHS
  • Bug Fix – Split Tab – Fix Message Collection that is split shows up as empty in HL7Spy until re-opened

HL7Spy 3.1.2228 Released

  • Improvement – Randomize sample messages used for calculating global statistics – Requested by Jeff B from mhg
  • Improvement – Message Split Tool – Add support to split files based on their original file name
  • Improvement – Editor – Improve performance of loading many small files – Requested by Joe M. from vumc
  • Improvement – Custom Code – Support setting the unescaped value of a field. HL7Subcomponent.EscapedValue
  • Improvement – Sql Loader/HL7 Sql – Add Windows Folder Browser dialog to ExportForm. Requested by Jeff D. from hicgrp
  • Improvement – HL7 Diff – Speed improvements to the HL7 Differencing algorithm for large messages. Reported by Tony C. from MModal
  • Improvement – FTP Explorer – Add support for recursive searches. Requested by Barry V. from princetonhc
  • Improvement – FTP Explorer – Add additional logging information when in “debug” mode to help troubleshoot connection errors
  • Bug Fix – Error getting Authentication Info. Padding is invalid and cannot be removed. Reported by John B. from Cook Children’s
  • Bug Fix – FTP Explorer – Fix Connection Timeout string showing as blank

HL7Spy 3.1.2173 Released

  • Improvement – HL7 Sender – Add logging of SSL info
  • Improvement – Editor – Add custom framing options to File SaveAs – requested by Joe E./li>
  • Improvement – General – Miscellaneous performance improvements/li>
  • Improvement – General – Update 3rd Party libraries/li>
  • Bug Fix – File Browser – SSH Private Key not functioning correctly- reported by Jeff D.
  • Bug Fix – HL7 Transform – Fix issue with edits not being picked up until a new row/column is selected
  • Bug Fix – HL7 Transform – Cannot delete transform
  • Bug Fix – Editor – Loading many small files compressed in 7z format is very slow – warren K.
  • Bug Fix – Editor – Fix issue with some HL7 Standard Table values not showing properly. Reported by Paul R.
  • Bug Fix – Editor – Copy/paste of Unicode characters incorrectly interpreted as ASCII
  • Bug Fix – Sql Loader – Fix database selection issue when the item selected is the first item in the list

HL7Spy v3.1.2119 Released

  • Improvement – HL7 SQL – When exporting to Excel do not show the count column. Requested by Cleveland Clinic
  • Improvement – SQL Loader – When exporting to Excel do not show the count column. Requested by Cleveland Clinic
  • Improvement – Compare Tool – Show differences in grid rather than as text. Requested by Cleveland Clinic
  • Improvement – Compare Tool – Issue seeing small changes like the period and space characters. Requested by Cleveland Clinic
  • Improvement – Windows Registry no longer required for install. Requested by optum.com
  • Bug Fix – HL7 SQL – HL7 datatype interpretation does not work when lower case segment names are used in the query – Reported by mhg.com
  • Bug Fix – Custom Code – HL7 Anonymizer creating empty fields where in 2.x it did not. Reported by manifestmedex.org
  • Bug Fix – HL7 SQL – Add missing DISTINCT button in HL7 SQL
  • Bug Fix – Field Statistics – Fix tooltips for next/prev buttons – Reported by jb
  • Bug Fix – Compare Tool – issue where Compare tool launched from HL7 SQL tool does not display if the Compare window has never been selected
  • Bug Fix – Sql Loader – Fix issue where Database field is disabled when first displaying the DbConnection form
  • Bug Fix – Custom Code – Copying a field to itself produces incorrect results

HL7Spy v3.1.2036 Released

  • Improvement – Add ok button to close HL7TargetSelection popup
  • Improvement – Support for compressed file types: 7z ACE ARC ARJ B1 Cab cfs cpt dar DGCA LHA LZX RAR rzip sit SQX UDA Xar zoo ZIP ZPAQ – Requested by WK from New Mexico Health Information Collaborative
  • Improvement – HL7 Mllp Server performance impromements
  • Bug Fix – Fix name if it is ‘[no name]’ and there is only a single archived item
  • Bug Fix – Fix Don’t create empty file tabs when a bad password is entered
  • Bug Fix – Fix issue with Bulk Difference Report exporting results horizontally instead of vertically. Reported by RP from Cleveland Clinic
  • Bug Fix – Fix issue with Interpret data types not working HL7 SQL – Reported by RP from Cleveland Clinic
  • Bug Fix – Fix ArgumentOutOfRangeException in Export to Excel function
  • Bug Fix – Do not associate .zip/.txt files with HL7Spy because some user don’t know how to change the association

HL7Spy 3.1.2003 Released

  • Bug Fix – Fix issue with pasting/editing hl7 messages not clearing the error indicator
  • Bug Fix – Defect Connexion.Core.HL7 – Setting a repeated field with another repeated field that contains \R\ is not handled correctly. Reported by Len F., eHealth Queensland
  • Bug Fix – Line numbers not showing properly while editing the hl7 message
  • Bug Fix – Fix object disposed exception when closing a tab while a query is executing
  • Improvement – Add ok button to close HL7TargetSelection popup

HL7Spy v3.1.1974 Released

  • Improvement – Improve HL7Spy startup time by lazy loading the content of most ToolView tools
  • Improvement – Add Save Redacted Messages functionality. Requested by Cleveland Clinic

RedactMessages

  • Improvement – Show differences between the current and transformed message in Transform Test tool

TransformDifferences

  • Improvement – Use LaunchExisting option when file is placed on command line without the -lf option. This enables HL7Spy to be set as the default target for any file extension using the Windows “Open With” right-click option

  • Bug Fix – Fix Export so the progress is shown
  • Bug Fix – Fix look and feel of MessageCollectionView when it is popped out of the main window
  • Bug Fix – Fix progress bar in HL7 SQL
  • Bug Fix – Fix NullReferenceException in BindableQueryResults in HL7 SQL and SQL Loader
  • Bug Fix – Fix issue with registering the licensee/licensekey via the installer
  • Bug Fix – Fix NRE in HL7Subcomponent.EscapedValue
  • Bug Fix – Code sign HL7Spy.exe
  • Bug Fix – Fix issue where the name of a Custom Code snippet cannot be renamed.
  • Bug Fix – Fix issue where the watch list is not updated when no messages are loaded
  • Bug Fix – Fix potential NullReferenceException in Watch List
  • Bug Fix – Fix issue with the updating of the description when editing the watch list
  • Bug Fix – Stop button not working in HL7 SQL tool

How can I remove RXA-12, not just delete the value, but remove it?

Question: How can I remove RXA-12, not just delete the value, but remove it so that RXA-13 becomes the new RXA-12?

To do this you can use the simple function below. They way it works is to go through all RXA segments and calls the RemoveAt(12) on the segment fields. This will remove the field causing all fields after RXA-12 to be offset by one.

public override void Run()
{
   HL7Message message = GetParsedMessage();
   foreach(HL7Segment segment in message.GetSegments("RXA"))
   {
     segment.Fields.RemoveAt(12);
   }
    
   this.SaveMessage(message,"RXA-12 Removed");
}

HL7Spy 3.1.1910 Released

  • Improvement – HL7Spy performance improvements. Application startups are faster, as are loading files
  • Improvement – Improve performance HL7 Standard searches/lookups
  • Improvement – Highlight fields in message that match the search entered in the search textbox

    SearchTool
  • Improvement – Support cntrl-i and cntrl-shift-i for navigating text within the HL7 Editor
  • Improvement – Custom Code – Allow source code to be copied in HTML so it displays in emails better
  • Improvement – Improved IPv6 support
  • Improvement – HL7 Receive improved memory usage
  • Improvement – HL7 Send – Close HL7 Target selection popup on double-click
  • Improvement – Allow minimizing the Ribbon when document is dragged out of main window
  • Improvement – Clean-up bug report look and feel
  • Improvement – Custom Code – Add a dropdown list to the toolbar to show available functions/classes
  • Improvement – Better support for High Resolution monitors with .NET 4.7+
  • Bug Fix – With “Application Options/Explorer – Start New HL7Spy Instance” off, double-clicking on an HL7 file does not open existing HL7Spy instance
  • Bug Fix – Fix look and feel of MessageCollectionView when it is popped out of the main window
  • Bug Fix – Clean-up display of HL7 Standard tool
  • Bug Fix – Fix uncommon NullReferenceException in FieldStatistics
  • Bug Fix – Fix unhandled exception when file path is too long in FileSave dialog
  • Bug Fix – Fix Application Unhandled Exception. [EvaluationException] Invalid Expression
  • Bug Fix – Fix [InvalidOperationException] rectangle calculation must happen first
  • Bug Fix – Fix text in Custom Code splash screen
  • Bug Fix – Fix layout of HL7 Receiver configuration
  • Bug Fix – [NullReferenceException] Object reference not set to an instance of an object.
    at HL7Spy.Core.Hl7.HL7Message.UpdateOffsets()
  • Bug Fix – Fix: Error Firing topic SetStatus from HL7Spy.Shell.ShellPresenter. [InvalidOperationException] Sequence contains more than one matching element
  • Bug Fix – Fix sizing and placement of the message navigation control
  • Bug Fix – Custom Code not saved when switching between functions resulting in lost work

HL7Spy v3.0.1690 Released

  • Feature – Add “Exit HL7Spy” menu item – Larry B.
  • Feature – HL7 Send – Add the ability to log the low-level communications protocol. Requested by Philip D.

HL7 Send - Log

 

  1. None – Turns off all debug information
  2. Debug – Includes information about the protocol exchanged minus the actual data in the transfer
  3. Full – Includes all protocol information and messaging data
  • Feature – Global Custom Code – A Custom Code function that can be used by other Custom Functions. This feature allows users to consolidate commonly used code into a centralized place that can be used across multiple functions.

  • Bug – Fix Error An exception was thrown during handling the topic ‘ShowMessageFramingView’ System.ArgumentException: Input array is longer than the number of columns in this table.
  • Bug – HL7 Send – Issue if the End of Frame markers in the ACK are sent in a separate network packet. Found by Philip D.
  • Bug – HL7 Tree Editor- Fix [InvalidOperationException] Sequence contains no elements

Read more

Find Last A08/Visit not discharged A03

Question: How do I find the last A08/Visit not discharged.

This code searches through a message set, pulling the last A08 per visit/encounter. If the visit gets an A03 discharge message, then the visit is excluded from the final data set.

The final data set loads in a new tab and has only the last A08 for non-discharged encounters. If you want to include the A04s, see below for lines to comment out.

Note: that some of the A08 messages could still be for discharged patients. The PV1-45 discharge date/time may contain a value, but the original message set not have contained a corresponding A03.

Thank you to Scott Hall for contributing this code.

string _fileName = @"c:\_test.txt";
Dictionary<string,Encounter> _data = new Dictionary<string,Encounter>(10000);
Dictionary<string,Encounter> _discharged = new Dictionary<string,Encounter>(10000);

public class Encounter
{
   public Encounter(string encounterId)
   {
    EncounterId = encounterId;
   }

   public IMessageData Message;
   public string EncounterId;
}

public override void Run()
{
  // Get an HL7 Message in parsed format
  HL7Message message = GetParsedMessage();
  MSH msh = message.Segments.First<MSH>();
  if(msh==null || (msh.MessageType_09.TriggerEvent_02.Value!="A08" && msh.MessageType_09.TriggerEvent_02.Value!="A03"))
    return; // not an ADT^A08 message
  PID pid = message.Segments.First<PID>();
  if(pid==null)
    return; // no pid segment

  PV1 pv1 = message.Segments.First<PV1>();
  if(pv1==null)
    return; // no PV1 segment for encounter number
  string encounterId = pv1.VisitNumber_19.ToString(); //pid.PatientIdentifierList_03.First.ToString();
  Encounter CSN;

  // handle A03 Discharges
  if(msh.MessageType_09.TriggerEvent_02.Value=="A03")
  {
    if(!_discharged.TryGetValue(encounterId,out CSN)) // is patient already in the discharged dictionary?
    {
      _discharged.Add(encounterId,CSN);
    }

    // If you want A04 messages included for discharged patients, then comment out these two lines.
    // Otherwise, your dataset will be A08 messages for patients w/o an A04.
    // If you comment these lines, you might also want to change the tab name in the SaveMessage at the end.

    _data.Remove(encounterId);
    return;
  }

  // For A08 patient updates, check if the patient is already discharged.
  if(msh.MessageType_09.TriggerEvent_02.Value=="A08")
  {
    if(_discharged.TryGetValue(encounterId,out CSN)) // is patient in the discharged dictionary?
    {
      return;
    }
  }

  if(!_data.TryGetValue(encounterId,out CSN)) //CSN not found in dictionary?
  {
     CSN = new Encounter(encounterId);
     _data.Add(encounterId,CSN);
  } 

  CSN.Message = Message;
}

// Called once after the last message has been processed.
// It is a good place to perform cleanup and to report information.
// Always called from the UI thread.
public override void OnFinish()
{
   SaveMessage(_data.Values.Select(p=>p.Message),"Last A08/Visit not discharged A03");
}

HL7Spy 3.0.1648

  • Feature – HL7 SQL/SQL Loader – Add menu items for Showing/Hiding: Auto Filter Row, Grouping Panel, and Find Panel
  • Feature – HL7 SQL/SQL Loader – Add support for exporting column to quoted list – Albert E.
  • Feature – HL7 SQL/SQL Loader – Add “Selected To Distinct List” to clipboard right-click option and keyboard shortcut

SelectedToList

  • Feature – HL7 Send – Improved performance and better memory usage
  • Feature – Add user help button that points to the on line user manual
  • Feature – Custom Code – Add function to Split OBX-5 repeats to and OBX segments with no repeats and back (HL7Message.SplitObx5RepeatToOBX/HL7Message.CombineObxsToObx5Repeats)
  • Feature – HL7 Receiver – Add error dialog when ssl is selected but no certificate is supplied
  • Feature – Allow configuring the Font used in the Compare Tool

  • Bug – Bulk Compare Tool – Escape double quotes and commas in Generate Report – Jeff D.
  • Bug – Sql Loader – Correct Integrated Security connection string value for Oracle
  • Bug – Sql Loader – Add support for Sqlite databases
  • Bug – Fix NRE when clearing the disposed Statistics Tool
  • Bug – Fix file save view error when there are no messages to save
  • Bug – HL7 Editor – Turn off vertical scrollbar when wordwrap is off
  • Bug – Split Tab – Split by file size should be in KB not MB
  • Bug – Fix clear-all/select-all in Open Folder tool
  • Bug – Fix issue where exporting and print preview causing MissingManifestResourceException and not able to display print preview dialog
  • Bug – HL7 Editor – Fix setting Font in editor settings not changing font in editor
  • Bug – Custom Code – HL7 Control Character Escape Sequences not properly handled by ToString()
  • Bug – Fix issue with PartialLoad Dialog not functioning properly when file size is greater than int.MaxValue
  • Bug – Fix extra message present in the tab when using Partial Load Dialog
  • Bug – HL7 Editor – Fix issue where “Unescaped Field To Clipboard” menu item is repeated each time the user right-clicks on a field. Reported by Jeff D.
  • Bug – Bulk Compare Tool – Full Segments not being ignored – Jeff D
  • Bug – Compare Tool – Find Next Change stopping at Ignored fields
  • Bug – Compare Tool – Ignored Segments should be ignored when comparing segment order

HL7Spy v3.0.1549

  • Feature – Improve memory use of the application
  • Feature – Improve performance of HL7 Sender and Receiver
  • Feature – Improved robustness of the HL7 Receiver
  • Feature – Add support for SSL in HL7 Sender and Receiver
  • Feature – SQL Loader/HL7 SQL – Add Enhanced Tools to Options menu
  • Find Panel – Allows the user to perform searches within the current result set
  • Group by Panel – Allows grouping of data by a column by dragging and dropping the column in the indicated area
  • Auto Filter Row – Filter the result set using the expression in the filter textbox. You can use %, or * as a wildcard

DataTools

  • Feature – Re-implement and improve Watch List tool
  • Feature – Watch List – Add support for displaying watch list highlighted in the message editor

watchWindow

  • Feature – Open Folder Dialog – Redesign
  • Feature – Open Folders Dialog – Improve search performance
  • Feature – Open Folders Dialog – Add support for Regular Expressions in the file name search
  • Feature – Open Folders Dialog – Show status of search to indicate level of completion
  • Feature – Open Folders Dialog – Save user settings across application restarts

OpenFolder


  • Bug – Remove annoying ding from SetFieldView
  • Bug – MLLP – Fix argument out of Range exception due to end-frame-bytes being ahead of the start-frame-bytes in customer message
  • Bug – Fix layout of MessageFramingControl so that the Character Encoding is visible
  • Bug – Fix Watch List item’s description not updating properly when editing the HL7 Path
  • Bug – Make the selected field the highest display priority so that it is not hidden by field highlighting
  • Bug – Fix missing status update during Watch List Report generation
  • Bug – Fix sizing of # of Samples in calculate statistics
  • Bug – Fix incorrect use eventhandlers which are preventing objects from being GC’d
  • Bug – Bulk Compare – Key Path field not staying empty when cleared by user – Reported by Jeff D.
  • Bug – Bulk Compare – HL7Spy does not properly launch the default application for CSV files

HL7Spy v3.0.1441 Released

  • Feature – Clean-up Messages in Tab. This feature allows you to find and remove unwanted messages from a tab. For instance, sometimes you want to remove duplicate messages, or remove messages coming from a particular source system. The Clean-up tool provides you with this capability.

CleanupTool2


  • Bug – Fix ArgumentOutOfRangeException in HL7 Send Tool
  • Bug – HL7 SQL and Sql Loader. Disable “Distinct” button while a query is executing
  • Bug – Fix saving/restoring Quick Access Toolbar
  • Bug – Bulk message compare – Fix segment paths not being excluded when added to ignore list
  • Bug – Set HL7 Field – Fix tab stops so they are ordered more logically

HL7Spy 3.0.1387 Released

  • Feature – BHS/BTS segments should be preserved by the HL7 Receiver
  • Feature – Add progress bar when initial Bulk Compare is calculated
  • Feature -Compare Tool Enhancement – Add to exclusion list by right-clicking on fields in the compare window

  • Bug – StackOverflowException when stopping an HL7 MLLP Transfer
  • Bug – Disable annoying ding when something is search via the navigation control
  • Bug – Total Query Time displayed in Sql Loader, and HL7 SQL are incorrect
  • Bug – HL7 SQL – Field name text is not always shown in the Columns of the result set
  • Bug – Sql Loader – Always show results if there are items returned in the query. Requested by Albert E.
  • Bug – Bulk Compare – An HL7 Segment Paths like OBX, OBX[2], and OBX[*] in the “Path(s) to Ignore” bulk compare settings, does not ignore all OBXs
  • Bug – Compare – Configuration dialog should not shut when enter key is hit

HL7Spy 3.0 Released!

Inner Harbour Software is please to announce HL7Spy 3.0, its latest release of its flagship product. HL7Spy 3.0 comes with a completely new user interface that makes HL7Spy more efficient and easier to use. HL7Spy 3.0 also comes packed with new features, enhancements, and performance improvements. A sampling of these can be found below.

New User Interface

The new user interface provides for a much richer user experience.  The new Ribbon Bar makes navigating HL7Spy’s functionality faster and easier. The tool buttons are larger and include text identifies the functionality being provided. Context sensitive help appears when hovering over a button. These new UI will make using HL7Spy more efficient for both beginners and existing HL7Spy pros alike.

RibbonBar

 

 

Additional User Interface Enhancements

  • Ribbon Bar can be shown/hidden with Cntr-F1 allowing the user to maximize message display area
  • HL7Spy skin, back shadowing, and Aero Glass can be changed allowing the user to optimize the look and feel of the UI

ApplicationOptions

  • Short-cuts can be added to the application title bar for quick access to frequently used tools

CustomizableShortcuts

  • The Ribbon tabs, menus, and buttons can be access via the keyboard using the Alt key followed by the short-code displayed after the Alt key is pressed.

KeyboardShortCuts

 

 

 

NEW HL7 Timeline Tool

The new HL7 Timeline Tool provides an over-view of the message volume over time for the currently displayed tab. This tool is useful when you are navigating a very large message stream and you want to see the messaging rate over time, or you want to quickly navigate to a particular date/time. In the example below, the message stream contains 100,000 messages. Note the spike in message throughput just before midnight every day.

Timeline

HL7 Timeline Tool Features

  • Can handle hundreds of thousands of messages
  • Clicking on the timeline navigates the editor to that date/time
  • Zoom In/Out using Shift-Click operations with the mouse
  • Right-Click to export graph to png image file
  • Right-Click to export raw data to Excel

New HL7 Transform Tool

The new HL7 Transform Tool allows users to make bulk modifications to messages within the current tab. While message transformation functionality has been available in HL7Spy since version 1.x, it has required users to write c# code snippets in the Custom Code tool. Now non-programmers can make bulk transformations to HL7 messages without having to write code.

HL7Transform

HL7 Transform Tool Features

  • Set fields to constant values. Eg, MSH-4=’FIXEDVALUE’ – sets MSH-4 to FIXEDVALUE
  • Copy fields from one part of the message to another. Eg, MSH-5=MSH-4 – sets MSH-5 to the value in MSH-4
  • Use a table to map one field to another. Eg PV1-2 = Table(PV1-2,’ER’ -> ‘E’, ‘OP’ -> ‘O’, ‘IP’ -> ‘I’) – maps ER to E, OP to O, and IP to I
  • Use conditions to control when a transformation is triggered. Eg, MSH-4=MSH-4+’-INPATIENT’  when  PV1-2=’I’ – appends ‘-INPATIENT’ to MSH-4 if PV1-2 is set to ‘I’
  • Test button runs the transform on the message currently displayed in the editor to test the results of the transform

New Other HL7Spy 3.0 Features/Improvements

  • Cloverleaf Smatdb files can now be opened with HL7Spy
  • Improved Bulk Message Compare tool
  • Improved Custom Code Selection UI
  • Improved Database Connection Selection and Configuration UI

DatabaseConfiguration

  • Improved HL7 Send Destination Selection and Configuration UI

HL7Destination

  • Support for decoding and opening large escaped HL7 fields including Base64 encoded data
  • Better, faster displays for displaying large amounts of data in Sql Loader, HL7 SQL, and Statistics tools

Sqlloader

  • Better Exporting tools

Export

  • Improved HL7 Receive Tool with support for receiving batch transfers

HL7Receive

  • Improved HL7 Send Tool with support for sending HL7 batch messages

BatchSend

  • Improved Split Messages  in Tab Tool with support for creating HL7 Batch messages

SplitMessages

HL7Spy v2.3.555 Released

  • Improvement – Do not show the popup when pasting text into the HL7 Editor.
  • Improvement – Add a new right-click menu option to paste and replace text from the clipboard to the HL7 Editor
  • Improvement – Better logic for saving application size and location with multiple monitors

  • Bug Fix – Mask HL7: Fix issue where hitting the “Enter” key in mask fields dialog causes the dialog to exit.
  • Bug Fix – Sql Loader: Fix issue where error messages are not being cleared between queries
  • Bug Fix – Split Messages – Fix issue with a file being locked when exporting
  • Bug Fix – Split Messages – Fix issue with splitting messages by index range misses the last message in the index
  • Bug Fix – Split Messages – Fixed issue with splitting messages by file size not working correctly

How do I pull all OBX-5s where OBX-3.1=’SS003′

Question:

I am working on a syndromic surveillance feed for the CDC and hope you can help me with an HL7 SQL question. The messages contain multiple OBX lines. In those lines, I need to pull: 

data in OBX-5
from the segment
 where OBX-3.1 = ‘SS003’

The order and number of OBX segments varies, so I can’t always specify a specific OBX segment.
Is there a way to do this in HL7 Spy? I’m including a set of OBX segments below as an example.

OBX|1|NM|11289-6^BODY TEMPERATURE:TEMP:ENCTRFIRST:PATIENT:QN^LN||97.4|degF^FARENHEIT^UCUM|||||F
OBX|2|NM|59408-5^OXYGEN SATURATION:MFR:PT:BLDA:QN:PULSE OXIMETRY^LN||97|%^PERCENT^UCUM|||||F
OBX|3|CWE|8661-1^CHIEF COMPLAINT:FIND:PT:PATIENT:NOM:REPORTED^LN||||||||F
OBX|4|CWE|8661-1^CHIEF COMPLAINT:FIND:PT:PATIENT:NOM:REPORTED^LN||||||||F
OBX|5|NM|21612-7^AGE TIME PATIENT REPORTED^LN||60|a^YEAR^UCUM|||||F
OBX|6|CWE|SS003^FACILITY / VISIT TYPE^PHINQUESTION||225XN1300X||||||F
OBX|7|TX|44833-2^DIAGNOSIS.PRELIMINARY:IMP:PT:PATIENT:NOM:^LN||per ems pt with increased confusion. pt also presents with ulcers to bilateral feet||||||F
OBX|8|AD|SS002^TREATING FACILITY LOCATION^PHINQUESTION||701 10TH STREET SE||||||F

Answer:

The best way to accomplish this is to write a small amount of Custom Code. In the example below, all OBX-5 values where OBX-3.1 = ‘SS003’ will be placed in a file called obx5s.csv. Once all the messages have been processed the file will automatically be opened in excel, if it is installed on the computer.

private StreamWriter _writer;
private string _fileName = Path.Combine(Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop),"ob5s.csv");

public override void OnStart()
{
  _writer = new StreamWriter(_fileName,false);
}

// Called once or many times based on RunTypeRequested
public override void Run()
{
  // Get an HL7 Message in parsed format
  HL7Message message = GetParsedMessage();
  foreach(var obx in message.OBXs)
  {
    if(obx[3,1,1] == "SS003")
    _writer.WriteLine("{0}", obx[5]);
   }
}
public override void OnFinish()
{
   if(_writer!=null)
   {
     _writer.Close();
     _writer = null;
     System.Diagnostics.Process.Start(_fileName);
   }
}

HL7Spy 2.3.534 Released

  • Improvement – Better appication startup window positioning – Requested by Len F.

  • Bug Fix – Custom Code: HL7Message InsertAfter throws unexpected exception.
  • Bug Fix – HL7DocumentationProviderFactory.GetOrCreateProvider1 [ArgumentException] An item with the same key has already been added.
  • Bug Fix – Could not save configuration for HL7QueryViewSettings.
  • Bug Fix – Update help web links to point to new web location
  • Bug Fix – Fix missing tooltip issue when navigation bar is set to top – Report by Scott H.
  • Bug Fix – Fix a problem where the last char could be 0x1c or 0x0b and was included as part of the message
  • Bug Fix – Custom Code: Fix up code documentation so it properly shows the parameter information in the code editor

HL7Spy v2.2.501 Released

  • Improvement – Update Custom Code tool to support for C# 5.0 syntax
  • Improvement – Support REGEXP in addition to REGEX – Requested by Albert E
  • Improvement – Add menu option to reset application registry and folder permissions
  • Improvement – Message Editor should track WatchView path when WatchView is navigated with the keyboard
  • Improvement – Make HL7 text comparison case insensitive
  • Improvement – Add clear Watch functionality
  • Improvement – Select All/Clear all in the DISTINCT tool
  • Improvement – Print out duplicate keys as part of the Bulk Compare Report
  • Improvement – When generating a Bulk Diff Compare, print out indexes of messages with duplicate keys
  • Improvement – Turn high res mode on in app.config. Requires .NET 4.5 or above

  • Bug Fix – Do not use Courier New. Some systems in India do not seem to have this font.
  • Bug Fix – When I use the dropdown to select the ‘MySQL’ Database type, it doesn’t get selected and remains ‘SqlServer’. – Mike S
  • Bug Fix – Fix issue where buttons in Custom Code Device are being hidden.
  • Bug Fix – Fixed issue where \r\n in password prevented the FTP explorer from working
  • Bug Fix – Fix issue where the word “select” in region generates an error message
  • Bug Fix – Fix NRE when launching the Sql Loader when it has never been configured
  • Bug Fix – HL7Spy does NOT display message in file with MSH-18 equal “UNICODE UTF-8”

HL7Spy 2.1.448 Released

  • Improvement – HL7 SQL – Expand repeated fields when “*” is specified for the repeat – Requested by Albert E.
  • Improvement – Sql Loader – Improved DB connection dialog. Better cancel support. – Requested by Albert E.
  • Improvement – Add new Find Duplicates functionality. Finds messages in a tab that have duplicated MSH-10 (message Control ID). This new function can be found under the “Tools/Find Duplicate Messages” menu item.
  • Improvement – Add new Remove Duplicates functionality. Remove messages in a tab that have duplicated MSH-10 (message Control ID). This new function can be found in the toolbar and under the “Tools/Remove Duplicate Messages” menu item – Requested by Lonny K.
  • Improvement – Add new Set HL7 Field Value Function (see Set HL7 Field Value for details). This new feature can be found in the toolbar, and under the “Tools/Set HL7 Field Value…” menu option – Requested by Joseph Z.

    SetHL7Field

  • Bug Fix – Issue where very large subcomponents are not shown in the Segment Editor – Reported by Paul C
  • Bug Fix – Ack message received should not contain the framing characters
  • Bug Fix – Statistics at the *** message level are not always accurate. Reported by Adam F.
  • Bug Fix – Fix issue where progress bar not show during generation of Compare Report.

How do I export fields from repeated segments?

Question:

I am trying to pull data from multiple HL7 messages using the SQL query: SELECT *, PID-5.1 as ‘B Last Name’, PID-5.2 as ‘B First Name’, OBR-4.1 as ‘Order Number’, OBR-4.2 as ‘Order’ WHERE MSH-11 != ‘T’

The issue I’m having is messages with multiple OBRs. How can I get data all the data from the SQL statement and the data from each OBR on each message?

Answer: 

Unfortunately you cannot use the HL7 SQL tool for this. This tool returns at most 1 row per message. You would have to write some custom code to do this.

The code in the example below will create a file on the desktop called out.csv which will be a comma separated list of the fields

string _fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),"out.csv");
StreamWriter _fileWriter;

public override void OnStart() 
{
   _fileWriter = new StreamWriter(_fileName,false);
}

public override void Run() 
{   
  // Get an HL7 Message in parsed format
  HL7Message message = GetParsedMessage();
  
  // skip any test messages
  if(message.MSH[10]=="T")
    return;
  
  PID pid = message.Segments.First<PID>();
  if(pid == null)
    return;
  
  // Get the first PID segment
  foreach(OBR obr in message.Segments.OfType<OBR>())
  {
     _fileWriter.Write(pid[5,1,1]);
     _fileWriter.Write(", ");
     _fileWriter.Write(pid[5,1,2]);
     _fileWriter.Write(", ");
     _fileWriter.Write(obr.Segment.Path.Repeat);
     _fileWriter.Write(", ");
     _fileWriter.Write(obr[2,1,1]);
     _fileWriter.Write(", ");
     _fileWriter.Write(obr[2,1,2]);
     _fileWriter.WriteLine();
  }
  
}

public override void OnFinish() 
{
  if(_fileWriter != null)
  {    
    _fileWriter.Close(); // close the file
    _fileWriter = null;
    // launch notepad to display the file.
    System.Diagnostics.Process.Start("Notepad",_fileName);
  }
}

How do I copy the value in HL7 field OBX[1]-14.1 to HL7 field OBR[1]-7.1?

Question:

I have a file of hundreds of HL7 messages and would like to copy the value in HL7 field OBX[1]-14.1 to HL7 field OBR[1]-7.1.  Basically, I want to overwrite the contents of field OBR-7 with the contents of field OBX-14 on every message.

Answer: 

The following code will loop through all the OBR segments, and set OBR-17 to the value of the first OBX segment following the current OBR segment.

public override void Run() 
{
  HL7Message message = GetParsedMessage();
  foreach(OBR obr in message.Segments.OfType<OBR>())
  {
    OBX obx = obr.Segment.GetRelative<OBX>(1); // get the next OBX
    if(obx != null)
      obr[17] = obx[14];
  }
  
  SaveMessage(message.ToString(), "Result");
 }

HL7Spy 2.1.411 Released

  • Improvement – FTP Explorer – Add a folder search feature – Requested by Holly B.
  • Improvement – Message Tab – Add support for editing tab names – Requested by Justin N.
  • Improvement – Remove annoying ding when enter key is pressed
  • Improvement – Core – Change HL7Parser such that it if receives a second MSH, that it will create a parser error and stop parsing
  • Improvement – Custom Code – Add ClearFields and KeepFields function
  • Improvement – MLLP Maximum Message Size not being honored – Reported by Paul C.
  • Improvement – Changes to the HL7 MLLP feature to do 2 things when the configured Maximum Message Size has been exceeded:
    1) Stop the MLLP listener and display an error
    2) Append an ERR segment to the truncated message
  • Improvement – HL7 MLLP – Display a link that when clicked opens the debug log location
  • Improvement – HL7 MLLP – Add a button to clear the  debug logging output

  • Bug Fix – Search Dialog – Cannot edit the HL7Path. Reported by Jon S.
  • Bug Fix – HL7 Spy Version 2.x: Pasting Messages Problem
  • Bug Fix – Fix up resizing of the Message Properties Window
  • Bug Fix – Fix up Fonts in Message Properties Window and Hex Editor
  • Bug Fix – Clean up HexBox. Display was ugly because of how the characters were being aligned.
  • Bug Fix – Not properly identifying 4 character Z segments
  • Bug Fix – Version 2.x Issue – Highlighting of Fields and Pop-Up Field Counters not working properly. Thijs
  • Bug Fix – Wix installer should require only .NET 3.5 to run
  • Bug Fix – Compare tool not fully initialized when called from HL7 Sql, or other tool
  • Bug Fix – Custom Code Make sure the buttons are always re-enabled when switching between functions
  • Bug Fix – Cosmetic: Better alignment of FTP Explorer login settings
  • Bug Fix – Save FTP settings when a folder is created, or moved
  • Bug Fix – FTP Explorer – Modify Password Dialog so the login error is displayed
  • Bug Fix – MLLP Maximum Message Size not being honored – Reported by Paul C.

HL7Spy 2.1.334 Released

  • Improvement – Custom Code – Expose the collection of output MessageCollections in the Custom Code base class
  • Improvement – Bulk Compare – Add Ignore Case option in the Message Diff, and Bulk Message Diff functionality. Requested by Prasad K
  • Improvement – HL7 Editor – Change error messages for 4 letter Z-Segments to a warning
  • Improvement – HL7 Editor – Make the wrap text option more accessible by placing it in the toolbar
  • Improvement – Trim off any control characters at the start of an HL7Message
  • Improvement – Add auto-sizing option for the HL7 Statistics Grid
  • Improvement – Update to latest MySql nuget package v6.9.6
  • Improvement – Update to the latest postgres library
  • Improvement – FTP Explorer – Add Filtering cability. Requested by Justin N
  • Improvement – FTP Explorer – Add Home button. Requested by Justin N
  • Improvement – FTP Explorer – Auto-resize the Remote Directory Textbox to use all available space
  • Improvement – FTP Explorer – Support for AIX servers
  • Bug Fix – Highlight Field feature does not work
  • Bug Fix – Fixes to HL7 Message Statistics. Reported by Elizabeth S
  • Bug Fix – Show in HL7 Standard from Field Statistics right-click
  • Bug Fix – Segment Editor – Next/Prev segment button does not work. Reported by David G.
  • Bug Fix – Bulk Compare – Message differ report does not honor case-insensitivity. Found by Prasad K
  • Bug Fix – HL7 Editor – Issue where empty file creates a situation where the index is set to 0/0 and copy/paste fails to function properly. Reported by Cameron N

HL7Spy 2.1.268 Released

  • Improvement – New and improved Field/Component/Sub Component Statistics Feature.
    • Very fast navigation of messages with matching fields.
    • Ability to select multiple items in the Statistics Grid, and navigate to matching messages. For example, below selecting ‘O’ and ‘OP’ in the Statistics Grid and then clicking the Next/Previous Arrow buttons navigates to messages in the tab that have either a PV1-2 field equal to ‘O’ or ‘P’.
    • Ability to select multiple items in the Statistics Grid and have messages meeting the criteria placed into separate tabs. For example, clicking the “All” button in the case below would create 2 tabs: one with messages where PV1-2 = ‘O’ and the other where PV1-2 = ‘OP’. Holding the Control Key down and clicking the “All” button will place messages with either PV1-2=’O’, or PV1-2=’OP’ into a single tab. – Requested by Cleveland Clinic

New Field, Component, Sub Component statistics tool

  • Improvement – Added option to increase log verbosity.
  • Bug Fix – Don’t launch HL7Spy from installer when in silent mode
  • Bug Fix – Fix case sensitivity issue with most recently used file list
  • Bug Fix – Progress bar not showing when downloading files in file explorer if the system has been running for a long time. Environment.TickCount returns a negative value.
  • Bug Fix: HL7DocumentationProviderFactory.GetOrCreateProvider Illegal characters in path exception.
  • Bug Fix: Field Statistics Performance issue introduced in v2.1.167

HL7Spy 2.1.219 Released

  • Improvement – Install Enterprise licenses using arguments on the installer. See: Automating HL7Spy’s Installation
  • Improvement – Additional Command Line Options Added. See: Command Line Options
  • Improvement – Custom Code: HL7Message class ToString() performance improvements
  • Improvement – Add native Oracle driver ODP.NET
  • Bug Fix – Fix issue with installing HL7Spy on Windows XP
  • Bug Fix – Fix sending command line arguments between instances of HL7Spy
  • Bug Fix -Fix issue where installing the licensee and license key via the command line fails. Reported by Michael S. from Cleveland Clinic
  • Bug Fix – Fix Unhandled Exception Error
  • Bug Fix – Segment Editor Exception: System.ArgumentOutOfRangeException: capacity was less than the current size. Reported by Biju K.
  • Bug Fix – Make the email verification dialog case insensitive. Reported by Michael S. from Cleveland Clinic
  • Bug Fix – Remove registry key when uninstalling
  • Bug Fix – Improve error detection of an invalid HL7Path

HL7Spy 2.1.165 Released

    • Improvement – A Cloverleaf New Line message framing option. Requested by Ron B.
    • Improvement – Allow enterprise licenses to be registered using the command-line
    • Improvement – Use Code Sign to sign the installer to avoid warnings during install
    • Improvement – Update to latest MySql and Postgres client library
    • Bug Fix – Custom Code – Setting a Field/Component/Subcomponent to null should leave the existing value untouched.
    • Bug Fix – HL7 Editor – NRE and duplicate settings key error.
    • Bug Fix – HL7 Editor – issue where no tool tips are provided for pasted in messages
    • New Feature – Mask Protected Health Information (PHI)

, or Control-M – Turn on/off whether or not the fields specified in “Options/Mask PHI Fields Settings…” are used to hide fields within the HL7 Editor.

“Fields to Mask” – Identify specific fields that will be masked in the HL7 message.
“Fields to NOT Mask” – All fields in the HL7 segment that are not identified here will be masked
“Fields to Mask” – Fields identified here will have PHI found in the “Fields to Mask” and “Fields to NOT Mask” sections masked.
“Mask Character” – Specify the character that will be used to “mask” the PHI.

HL7Spy 2.1.123 Released

  • Improvement – SqlLoader – Added support for Oracle 8 using Oracle’s managed library
  • Improvement – HL7 Listener – Added support for starting the HL7 MLLP Listener from the command line: -mllp port (e.g. -mllp 12000 will start the listener on port 12000. Requested by Nick.
  • Improvement – Licensing – Added the ability to install Enterprise Licenses from the command line. Useful for IT departments that wish to deploy HL7Spy using active directory, or other enterprise software deployment software.
  • Improvement – HL7Spy Application – improved HL7Spy start-up time. HL7 Standard data structures are now loaded in the back-ground as needed instead of loading them all up at start-up time.
  • Improvement- Added support for LZW compressed files. Requested by Jonathan H.
  • Bug – Fixed issue where no tool tips are provided for pasted in messages.
  • Bug – Fixed NullReferenceException when accessing HL7 Standard information under some situations.
  • Bug – Fixed issue where pasted in messages are not handled correctly. Reported by Adam F.

HL7Spy v2.1.056 Released

  • Bug – Message Editor – Backslashes, ‘\’, are being automatically removed when a message is cut/pasted into HL7Spy. Reported by Adam F.
  • Bug – HL7 SQL – Show/Hide Path descriptions not working properly. Reported by Barry V.
  • Bug – HL7 SQL – TS values are not being interpreted into Date/Time values properly. Reported by Barry V.

HL7Spy 2.1.051 Released

  • Improvement – Support for HL7 2.7 messages with the Truncation character ‘#’ included in the encoding characters. Requested by Jose S.
  • Improvement – Option to control Message detection algorithm. The new option is found under: Option/File Settings/Use Strict Message Detection. When enabled, ‘Strict’ mode provides a more accurate message detection algorithm in some rare cases,  however; all messages have to have the same message encoding, and framing. This option is disabled by default.
  • Bug – Invalid HL7 message causes segment editor to display a big X. Segment editor never recovers from this
  • Bug – Fix flickering issue in the FTP Explorer
  • Bug – Fix copy to clipboard issues in the HL7 SQL tool
  • Bug – Message Compare – Drag/Drop from editor to Compare Window does not work properly
  • Bug – AppDomain Unhandled Exception caught System.Threading.ThreadAbortException: Thread was being aborted.
  • Bug – Add the Postgres database provider to the HL7Spy installer
  • Bug – Sql Loader: Fix issue with Database Connection Settings not saving properly
  • Bug – Custom Code Tool:  Segments.Append(“ZZ1”) does not function properly
  • Bug – Improve copy/paste message in Editor. Reported by Paul C.
  • Bug – Fix issues with the display of segments with errors in the Editor
  • Bug – HL7 SQL/SQL Loader: Distinct Button disappearing when multiple query result tabs displayed. Reported by Albert E.
  • Bug – HL7 SQL Tool: LEFT/RIGHT functions in the Expression language not implemented properly

HL7Spy 2.0.4245 Released

  • New – Bulk Message Compare Tool – Useful when migrating between HL7 Integration Engines
    • Compare messages across 2 different message streams
    • Single step through messages with the same correlation key (MSH-10 by default)
    • Ignore specific Segment, Fields, Components, and Subcomponents in the comparison
    • Generate a report summarizing the differences between 2 message streams

BulkCompare

  • New – Prompt for a password when opening encrypted Zip files
  • Improvement – Add option to link scrollbars in the Compare tool – requested by Albert E., Cleveland Clinic
  • Improvement – Add support for .NET 4.5.2 high resolution monitor improvements
  • Improvement – Do not adorn the message in the editor with highlighting if it is larger than 5MB to improve render performance of large messages.
  • Improvement – Add region markers around historical  queries in SqlLoader, and HL7 SQL – requested by Albert E., Cleveland Clinic
  • Improvement- Ctrl-F in code editor switches the UI to the Segment Editor tool. We would prefer searching in the code editor. – requested by Ankie B., Universitair Medisch Centrum Groningen
  • Improvement- Add additional Assert methods to Asserts class. – requested by Ankie B., Universitair Medisch Centrum Groningen
  • Bug- Remove annoying beep when enter is pressed in the message index textbox
  • Bug- Proper version of the HL7 Standard not always honored when selected from the toolstrip.
  • Bug – HL7 SQL does not interpret some date/times unless the path is fully qualified. – requested by Saravana K., Medicity
  • Bug- Change “Mother’S Maiden Name” to “Mother’s Maiden Name” – reported by Albert E., Cleveland Clinic
  • Bug – Database Connector form – Timeout is always greyed out for a particular user. – reported by Mike T, Cleveland Clinic
  • Bug – Bug: MSH-2 Encoding characters, in the statistics tool the example value shows “^~\&” and the Len value is 4. When you select the component statistics from this field the “&” is missing and the Len value is 3. – reported by Ankie B., Universitair Medisch Centrum Groningen
  • Bug – Copy All in Sql Loader and HL7 SQL only copies the selected row instead of all rows – reported by Albert E., Cleveland Clinic
  • Bug – Fix issue where hitting the escape key when being prompted about deleting a custom function still deletes the function.

HL7Spy v2.0.4118

  • Bug – Custom Code Tool: Add References Dialog not working properly
  • Bug – Custom Code Tool: Intellisense not working properly for some classes.

HL7Spy v2.0.4111 Released

– New Dialog for importing referenced assemblies
– Reference custom, or .NET framework assemblies
– Assembly information displayed on right
– Search/Filter assemblies
– Imported assemblies are now moved into the proper folder (c:\Program Data\Plugin) automatically.

AddReferencesDialog

  • Improvement – Custom Code: Add support for virtual void RunOnce and virtual void OnError
  • Improvement – Custom Code: Add support for modifying the text, and visibility of the Run/RunOnce/Previous/Next buttons are displayed (OnUserInterfaceSetup).
  • Improvement – Custom Code: Expose the MessageCollection object in the Custom Code function
  • Improvement – HL7 Statistics: Distinquish between NULL and Segment Not Present in HL7 Statistics.
  • Improvement – HL7 Statistics: Find Next/Previous Missing Segment

NextMissingSegment

  • Improvement – Support for opening remote gzip, bzip, and zip files via FTP
  • Improvement – HL7 Send: Replace X with Recycle bin icon, and add a deletion confirmation dialog to prevent accidental deletion of destination – Requested by Albert E.
  • Improvement – HL7 Query: Present the “Data Type” that is in the “Description column” to present in a separate column … or have an option to “suppress it” – Requested by Albert E.
  • Improvement – HL7 Compare: Highlight the first time the sequence in the message changes – Requested by Albert E.
  • Bug – HL7Parser: Application Unhandled Exception: System.ArgumentOutOfRangeException: Length cannot be less than zero.
  • Bug – Editor: Fix the issue with saving the ShowKeyboardTooltips option – Reported by Albert E.
  • Bug – Sql Loader: Fix issue where the number of messages in the results window is different than the number of messages in the report grid
  • Bug – Sql Loader, HL7 Query: Fix StackOverFlowException in the bowels of System.Windows.Forms.dll!System.Windows.Forms.DataGridViewCell.DataGridViewCellAccessibleObject.GetAccessibleObjectBounds

HL7Spy v2.0.4001 Released

  • Improvement – Various UI improvements to support 200%+ resolution modes in Windows 7/8
  • Improvement – Better positioning of Search Dialog (Cntr-F). It will now track  the location of the main application window.
  • Improvement – Add support for 4 character Z-Segment names. Yes, its not valid HL7 but we have customers using them. Why, I don’t know.
  • Improvement – Shrink the name of the file path when it gets longer then 150 characters
  • Improvement – Send HL7 View – Improve the layout, move some configurations to the configuration dialog to free up space, minor bug fixes.
  • Improvement – Update internal libraries used by HL7Spy to latest version
  • Improvement – Fix scaling of side toolbar in Compare tool on high res displays
  • Improvement – Add bz2 and gz in the Open File Dialog. Requested by Albert E.
  • Improvement – Add support for querying the HL7 Standard by data type
  • Bug – Fix add folder when right-clicking in the FTP Explorer
  • Bug – FTP Explorer – Make sure the MessabeBoxEx owner is a window that is visible otherwise the message being displayed is hidden.
  • Bug – Fix NullReferenceException in FTP Explorer
  • Bug – Fix OutOfRangeException in MessageCollection.GetRange
  • Bug – Fix selection mechanism so drag-selection works within the HL7 Editor
  • Bug – Fix issue with DISTINCT drop-down double spacing found by Albert E.
  • Bug – Fix Directory being created by the Custom Code Tool every time HL7Spy is started.
  • Bug – Fix Status is being inadvertently modified which results in Sorting… being displayed always.

HL7Spy v2.0.3901 Released

  • Bug – Fixed unexpected exception Index was out of range. Must be non-negative and less than the size of the collection.
  • Bug – Fixed the ADO.NET provider with invariant name ‘System.Data.SqlServerCe.4.0’ is either not registered in the machine or application config file, or could not be loaded.
  • Bug – Fix query when path is typed in as a lower case segment
  • Bug – Fix Unhandled Exception:|Appccelerate.EventBroker.Internals.Exceptions.RepeatedPublicationException: Cannot add more than one instance of the same publisher to one topic
  • Bug – Fix applications use of Clipboard.SetText. Clipboard.SetText throws an exception if string.empty, or null is passed into it.
  • Bug – Fix DiffView|Microsoft Windows NT 6.1.7601 Service Pack 1|Error comparing messages|System.ObjectDisposedException: Cannot access a closed file.
  • Bug – Fix Deadlock introduced in the EventBroker
  • Bug – Fix Search Highlight getting hidden if search text is the name of a segment
  • Bug – Fix searching forward/back from Navigation bar
  • Bug – Fix issue where querying for results does not properly clear older results in Sql query
  • Bug – Fix Sometimes SelectedPath is set to an invalid value which prevents statistics buttons from working
  • Bug – Hide Large Message Dialog in Compare tool when loading complete
  • Bug – Fix HL7TreeView|Microsoft Windows NT 6.1.7601 Service Pack 1|ShowTableValues|System.InvalidOperationException: No room is available to display rows.
  • Bug – Fixed Search from FieldStatistics view not advancing when double-clicking. Reported by Cleveland Clinic
  • Bug – Pasting passwords into the FTP Explore password dialogs does not work
  • Improvement – Add clear buttons to the Compare Tool
  • Improvement – Add support for exporting message difference to the clipboard.
  • Improvement – Speed start-up of application by natively compiling assemblies during install
  • Improvement – Remove flicker in HL7QueryView and SqlLoaderView when paging through messages using the Navigation bar
  • Improvement – Don’t show Message tab if there are no errors in HL7 Sql query
  • Improvement – Cleanup Message/Segment cloning in Custom Code
  • Improvement – Better DISTINCT Functionality. Right-Click DISTINCT context menu
  • Improvement – HL7 SQL, SQL Loader fixes to History, and HistoryProvider
    Add better tooltips
  • Improvement – Add support for multi-column DISTINCT in both HL7 SQL and Sql Loader tools. Requested by Albert E.
  • Improvement – Add Message Type name in the toolbar of the Statistics tool. Requested by Saravana
  • Improvement – Add name of Segment in the toolbar of the Segment Editor
  • Improvement – Add repeat functionality in the HL7 Send tool to repeatedly send the same messages
  • Improvement – Remember the number of rows returned when switching between HL7 SQL and Sql Loader results

HL7Spy 2.0.3771 Released

  • Bug – Excel Writer missing namespace on column definition. Reported by IHIE.
  • Bug – Statistics calculation time always shows 0 seconds.
  • Bug – Field description tooltips missing from Compare Messages tool.
  • Bug – Fixed issue where the HL7 SQL results were incorrect. Reported by Cleveland Clinic.
  • Bug – Fixed a crash on 64-bit systems when double-clicking on an HL7 file in Windows Explorer.
  • Improvement – Reduce application flicker.
  • Improvement – Reduce application start-up time.
  • Improvement – Add the ability to change the Message Editor Font.
  • Improvement – Better positioning of DropDown menu list items.
  • Improvement – New Visual Studio 2012 look and feel.
  • Improvement – Option to use HL7Spy 1.x look and feel.
  • Improvement – Option to hide/show the Menu items using F11.
  • Improvement – Database connection timeouts can now be set on a per-connection basis. Requested by Cleveland Clinic
  • Improvement – Sql Loader speed improvements.

HL7Spy 2.0.3640 Released

  • Bug – Too much memory being used when exporting HL7 SQL results to excel, or Clipboard. Reported by Huntington Hospital.
  • Bug – Message selection becomes broken if a message is deleted from the HL7 SQL query results. Reported by Huntington Hospital.
  • Bug – Too much memory being used when exporting SQL Loader results to excel, or Clipboard.
  • Bug – Better handling of Date/Times when exporting HL7 SQL query results.
  • Improvement –  Copy from HL7 SQL using Control-c. Requested by Cleveland Clinic.
  • Improvement –  Copy from SQL Loader using Control-c.
  • Improvement – Better handling of Date/Times when exporting the contents of the Segment Editor to Excel.
  • Improvement – Clean-up messages that are copied from Orion Rhapsody and pasted into HL7Spy. Reported by Cleveland Clinic.

HL7Spy 1.8.8 Released

  • Improvement – Clean-up messages that are copied from Orion Rhapsody and pasted into HL7Spy. Reported by Cleveland Clinic.
  • Bug – Too much memory being used when exporting HL7 SQL results to excel, or Clipboard. Reported by Huntington Hospital.
  • Bug – Message selection becomes broken if a message is deleted from the HL7 SQL query results. Reported by Huntington Hospital.
  • Bug – Too much memory being used when exporting Sql Loader results to excel, or Clipboard.
  • Bug – Message selection becomes broken if a message is deleted from the Sql Loader query results.

Please Note: If you upgrade to this version, you may experience problems with the Sql Loader and MySql. They MySql drivers no longer support the old style of passwords. Please see the following article for more information: http://stackoverflow.com/questions/1575807/cannot-connect-to-mysql-4-1-using-old-authentication.

What’s coming in HL7Spy 2.0?

New HL7 2.x Standard Definitions

  • Versions 2.1-2.7 are now supported
  • Automatic detection of the correct version based on MSH-12
  • Fully searchable in the HL7 Standard Tool

New Segment Editor

  • Hierarchical display of field information
  • Show/Hide missing fields
  • Expand a field to retrieve additional detail
  • Edit field values at any level in the hierarchy

New FTP/File Explorer

  • Display HL7 messages on remote systems using the FTP protocol
  • Support for local, and remote, file system short-cuts to commonly used directories
  • Securely connect using SFTP, or FTPS
  • Master password management
  • Hierarchical folder organization of local/remote
  • Import/Export folders with, or without, passwords
  • Tail functionality to display only the last few messages from a remote file
  • Sync functionality to retrieve additional messages from a remote file

Other Improvements

  • Added advanced TCP settings for KeepAlive, NoDelay, DontLinger, and IPv6
  • Protocol logging to capture HL7 message protocol information

  • Improved HL7 MLLP protocol handler. Reduced memory utilization.
  • Enhanced HL7 Message model for use in the Custom Code tool. Improved performance.
  • New Break(); statement allows debugging custom code from within Visual Studio
  • .NET 4/4.5 support
  • Full 64-bit support
  • Better scaling when running in Windows 7/8 200%+ resolution mode
  • Performance improvements in HL7 Sql and Sql Loader
  • Support for loading/querying millions of messages

HL7Spy 1.8.6 Released

  • Improvement – Support for 2.0 licensing to allow users with a license to HL7Spy 2.0 to use HL7Spy 1.x if they choose.
  • Improvement – HL7Spy no longer locks the underlining file. It is now possible to delete, or rename, a file that is opened within HL7Spy.
  • Improvement – Speed improvements to the starting of HL7Spy.
  • Improvement – Update to the latest MySql library.
  • Improvement – Add support for Windows Domain licensing.

Please Note: If you upgrade to this version, you may experience problems with the Sql Loader and MySql. They MySql drivers no longer support the old style of passwords. Please see the following article for more information: http://stackoverflow.com/questions/1575807/cannot-connect-to-mysql-4-1-using-old-authentication.

How do I find all A14 messages that do not have a matching A05?

Question:

Thanks for making such a great product. 🙂 Question, I have two tabs open with ADT messages. I need to do a query to see what patients are in the first tab and are not in the second. There is not select Join type function supported. My first tab is A04’s and the second is A14’s. Need to know which A04’s don’t have my patient in the A14’s list.

I send a quick registration (A14) to a system that returns a A05 (or it should).  I need to know when an A05 is not returned for an A14.  The field I am actually matching on is PV1-50 (we put special IDs there).

Answer:

Thank you for being a supportive customer.
The only way I can think of doing this is to merge the two tabs into a single tab and write a Custom Code function to perform the analysis. See my solution below.

private string _fileName = @"C:\temp\results.txt";
private class TrackedItem
{
   public int Index {get;set;}
   public string AlternateVisitNumber {get;set;}
   public string MessageControlId {get;set;}
}

Dictionary<string,TrackedItem> _a14s = new Dictionary<string,TrackedItem>(StringComparer.CurrentCultureIgnoreCase);
Dictionary<string,TrackedItem> _a05s = new Dictionary<string,TrackedItem>(StringComparer.CurrentCultureIgnoreCase);

public override void Run()
{
  // Get an HL7 Message in parsed format
  HL7Message message = GetParsedMessage();
  var pv1 = message.GetFirstSegment<PV1>();
  if(pv1 == null)
    return; // no PV1 segment

  Dictionary<string,TrackedItem> collection=null;
  if(message.TriggerEvent=="A14")
  {
  collection = _a14s;
  } else if(message.TriggerEvent=="A05")
  {
    collection = _a05s;
  }

  if(collection == null)
    return; // not an A05, or A04 message

  TrackedItem item=null;
  if(!collection.TryGetValue(pv1.AlternateVisitID_50.IDNumber_01.Value, out item))
  {
    // remember information about the message
   item = new TrackedItem
          {
            Index = MessageIndex,
            AlternateVisitNumber = pv1.AlternateVisitID_50.IDNumber_01.Value,
            MessageControlId = message.MSH.MessageControlID_10.Value,
          };
    collection.Add(pv1.AlternateVisitID_50.IDNumber_01.Value, item);
  }
}

// this is called at the very end
public override void OnFinish()
{
  using(var stream = new System.IO.StreamWriter(_fileName))
  {
    stream.WriteLine("A14s without a matching A05");
    ExportDiff(stream, _a14s, _a05s);
    stream.WriteLine("A05s without a matching A14");
    ExportDiff(stream, _a05s, _a14s);
  }
  try{
    System.Diagnostics.Process.Start("Notepad",_fileName);
  } catch{}
 }

// show the difference between two collections
private void ExportDiff(StreamWriter writer, Dictionary<string,TrackedItem> collection1, Dictionary<string,TrackedItem> collection2)
{
  foreach(TrackedItem item in collection1.Values.OrderBy(i=>i.Index))
  {
    if(!collection2.ContainsKey(item.AlternateVisitNumber))
    {
      writer.Write(item.Index.ToString());
      writer.Write(" ");
      writer.Write(item.AlternateVisitNumber);
      writer.Write(" ");
      writer.WriteLine(item.MessageControlId);
   }
 }
}

HL7Spy 1.8.3 Released

  • Improvement – .NET 3.5 Framework not required if .NET 4.0 is installed
  • Improvement – Better control layout when using Windows large font (120 DPI) mode
  • Improvement – Open Folder dialog search textboxes perform search when the enter key is pressed
  • Improvement – Open Folder dialog search text is automatically inserted in the message editor search textbox when the editor is loaded
  • Improvement – Open Folder dialog option to perform case-sensitive/insensitive searches
  • Improvement – Open Folder dialog results display fixes for long folder paths

HL7Spy 1.8.1 Released

  • Improvement – HL7 Send uses less memory. Better shutdown of socket.
  • Improvement – HL7 Send should not automatically retry on first error.
  • Improvement – Show Compiler Errors and missing References in the Events tab of the Custom Code tool
  • Improvement – Statistics UI performance improvements
  • Improvement – Better, faster, sizing of DataGridView columns
  • Improvement – HL7Parser Improvements
  • Improvement – Send the results of an HL7 SQL query, or HL7 Loader query, to a new tab
  • Improvement – Send selected the results of an HL7 SQL query, or HL7 Loader query, to a new tab
  • Improvement – Performance improvements when a large number of results are returned from an HL7 SQL Query
  • Improvement – Performance improvements when a large number of results are returned from an SQL Loader Query
  • Improvement – Speed up shift-select datagrid in both HL7 SQL and Sql Loader
  • Bug – Fix Unhandled Exception:|System.ArgumentException: Illegal characters in path in FileSaveView
  • Bug – When double-clicking on a cell in Sql Loader, the incorrect cell is displayed
  • Bug – NullReferenceException when closing a tab while receive SQL Loader query results
  • Bug – System.ArgumentException: Illegal characters in path in FileSaveView
  • Bug – Incorrect results returned MRG-1[*] is queried with no where clause
  • Bug – Fix tool tip on the “Split message button”

How to handle Z-Segments in Custom Code

Question:
How can we handle Z-Segments in HL7Spy’s Custom Code Tool?

Answer:
The following code demonstrates how use Z-Segments. We start by adding a couple of ZF1 segments (1), then we set a few fields (2), and finally print the fields out using the Log function.

public override void Run() {
  // Get an HL7 Message in parsed format
  HL7Message message = GetParsedMessage();
  // (1) Append a couple of ZF1 segments
  message.Append(new Segment("ZF1")); // Append ZF1
  message.Append(new Segment("ZF1")); // Append a second ZF1
  string today=DateTime.Today.ToString("yyyyMMdd");
  int count=0;
  foreach(Segment zf1 in message.GetSegments("ZF1"))
  {
    ++count;
    //(2) set ZF1-3.1, and ZF1-3.2 with information from the MSH 
    zf1[3,1,1] = message.MSH[3,1,1] + "-V" + today;
    zf1[3,1,2] = message.MSH[9,1,2] + "-TEST";
    zf1[6] = count.ToString();
  }
  
  // (3) Log the information out using the Hl7Message class
  string firstZF1_6 = message["ZF1-6"];
  string secondZF1_6 = message["ZF1[2]-6"];
  Log(Severity.Informational,string.Format("ZF1-6={0}", firstZF1_6));
  Log(Severity.Informational,string.Format("ZF1[2]-6={0}",secondZF1_6));
  
  // save the message out to a new tab
  SaveMessage(message, "Modified Messages");  
}

HL7Spy 1.7.79 Released

  • Bug – Fix exception that occurs when DataGridView is asked to show a row, but there is not enough room
  • Bug – Better error handing in OpenTcpPortView
  • Bug – Fixed issue pasting text into a message when the text is not a full message
  • Bug – Refresh button was duplicating messages within the message tab
  • Improvement – Auto-retry connection if HL7 MLLP Send fails on first attempt
  • Improvement – Support characters above 127 in the ASCII table in the Message Framing dialog
  • Improvement – Faster HL7 MLLP Receive

HL7Spy 1.7.77 Released

  • Bug – Fixed InvalidCastException when exporting the query results from the Sql Loader data grid to Excel.
  • Improvement – Better handling of messages pasted from emails or other applications that modify segment line endings
  • Improvement – Less flicker when tabs are closed
  • Improvement – Faster application shutdown
  • Improvement – Enable dragging/dropping messages from 1 tab to another. This is useful for creating an ad hoc collection of messages to be saved, or transmitted. The best way to utilize this feature is to drag one of the tabs out of the main document area, or to drag one of the tabs so that it side-by-side with the other tabs as shown in the figure below. Messages that are dragged and dropped are always inserted after the currently displayed message.

HL7Spy v1.7.75 Released

  • Improvement – Upgraded some 3rd Party libraries that we use within the application
  • Bug – Fixed an issue when you double-click on a file in Windows Explorer and an existing instance of HL7Spy is shutting down. (thank you George S. for reporting)
  • Bug – Fixed an issue in the Splitting Tool where splitting by message index range was not working
  • Improvement – Sped up start time by lazy initializing the Custom Code tool
  • Improvement – Sped up application start time by 5 seconds.
  • Bug – Fixed a problem with gzip handling
  • Bug – Fixed a FileDisposed exception being thrown when the last Query Results tab is closed
  • Bug – Fixed an issue in HL7 SQL where the left most column showed incorrect index numbers when DISTINCT is selected from the toolbar.
  • Bug – Fix the formatting of date/times in Excel (thanks to Larry E. for reporting and giving us the fix!)

Find last known allergies for each patient

Question:
How can we use HL7Spy to find the last set of known allergies for each patient in a set of messages?

Answer:
The best way is to write a custom function that remembers the last set of allergies for each patient. Then in the OnFinished function we print out all patients with their last set of known allergies.

string _fileName = @"c:\temp\_test.txt";
Dictionary<string,Patient> _data = new Dictionary<string,Patient>(10000);

public class Patient
{
   public Patient(string patientId) 
   { 
    Allergies = new HashSet<string>();
    PatientId = patientId;
   }
   public HashSet<string> Allergies;
   public string PatientId;
}

public override void Run() { 
  // Get an HL7 Message in parsed format
  HL7Message message = GetParsedMessage();
  MSH msh = message.Segments.First<MSH>();
  if(msh==null || msh.MessageType_09.TriggerEvent_02.Value!="A08")
    return; // not an ADT^A08 message
  
  PID pid = message.Segments.First<PID>();
  if(pid==null)
    return; // no pid segment
  
  List<AL1> patientAllergies = message.Segments.OfType<AL1>();
  if(patientAllergies.Count==0)
    return; // no allergies
  
  string patientId = pid.PatientIdentifierList_03.First.ToString();  
  
  Patient pat;
  if(!_data.TryGetValue(patientId,out pat))
  {
     pat = new Patient(patientId); 
     _data.Add(patientId,pat);
  }
  
  pat.Allergies.Clear();
  
  // loop through all AL1 segments
  foreach(AL1 al1 in patientAllergies)
  {
     pat.Allergies.Add(al1.AllergenTypeCode_02.ToString());
   }
}
// Called once after the last message has been processed.
// It is a good place to perform cleanup and to report information.
// Always called from the UI thread.
public override void OnFinish() 
{
  // to figure out the distribution of all allergies
  Dictionary<string, int> allergies = new Dictionary<string,int>(1000);
  
  // write the data out to a file
  using(System.IO.StreamWriter wr = new System.IO.StreamWriter(_fileName))
  {   
    wr.WriteLine("Patient ID vs Allergy for {0} patient samples",_data.Count);
    wr.WriteLine();
   
    foreach(Patient p in _data.Values.OrderByDescending(p=>p.Allergies.Count))
    {
        wr.Write(p.PatientId);
        wr.Write(',');
        wr.Write(p.Allergies.Count); 
        foreach(string s in p.Allergies)
        {
           wr.Write(',');
           wr.Write(s);         
           // calculate the total number of allergy types for the given set of patients
           int frequency=0;
           if(!allergies.TryGetValue(s,out frequency))
           {
              allergies.Add(s,1);
           } else {
              allergies[s]=++frequency;
           }
        }
        wr.WriteLine();
    }
    
    wr.WriteLine();
    wr.WriteLine();
    wr.WriteLine("Allergy distribution for {0} patient samples.",_data.Count);
    wr.WriteLine("Number of distinct allergies is {0}.",allergies.Count);    
    wr.WriteLine();
    
    foreach(KeyValuePair<string,int> d in allergies)
    {
      wr.Write(d.Key);
      wr.Write(',');
      wr.Write(d.Value);
      wr.WriteLine();
    }       
  }
// launch notepad to display the file.
System.Diagnostics.Process.Start("Notepad",_fileName);
 }

Segments where OBX-15 differ from each other

Question:
Dear HL7Spy,
A user has a request – am not able to find function within HL7 to execute.

Find all the segments(i.e. OBX 15:1) within a message where content is different from each other. For example: If first OBX 15:1 is ABC, then find all other OBX within same message with content other than ABC.

Not sure if HL7Spy has that capability but thought I’d check.

Answer:
Sure, no problem, you can write a custom function to display all messages where this is true in a few lines of code.

To add this code, go to the Custom Code tool, select the “+” to add a new custom function, and cut and paste this code over-top of the default code that is displayed.

To run the code, load up a set of messages into a tab and click “Run”. What you should see is a new tab created that will contain any messages where the OBX-15 value differs between segments.

 public override void Run() {
  // Get an HL7 Message in parsed format
  HL7Message message = GetParsedMessage();
  string obx15 = null;
  foreach(OBX obx in message.Segments.OfType<OBX>())
  {
    if(obx15==null)
    {
      obx15 = obx.ProducerSID_15.Value;
    }
    else if(obx15 != obx.ProducerSID_15.Value)
    {
      SaveMessage(message,"Different OBX-15");
      break;  
    }
  } 
} 

Find the last ADT^A08 message for each patient in the message collection?

Question:
How can I find the last ADT^A08 message for every patient in a collection of messages?

Answer:
The best way to do this is to create a dictionary based on the patient Medical Record Number (PID-3). For each message receive. Look up the patient in the dictionary, if there is no entry, add one. Otherwise, replace the existing entry’s message with the new version. See the code below.

string _fileName = @"c:\_test.txt";
Dictionary<string,Patient> _data = new Dictionary<string,Patient>(10000);

public class Patient
{
   public Patient(string patientId)
   {
    PatientId = patientId;
   }

   public IMessageData Message;
   public string PatientId;
}

public override void Run() {
  // Get an HL7 Message in parsed format
  HL7Message message = GetParsedMessage();
  MSH msh = message.GetFirstSegment<MSH>();
  if(msh==null || msh.MessageType_09.TriggerEvent_02.Value!="A08")
    return; // not an ADT^A08 message

  PID pid = message.GetFirstSegment<PID>();
  if(pid==null)
    return; // no pid segment

  string patientId = pid.PatientIdentifierList_03.First.Value; 
  Patient pat;
  if(!_data.TryGetValue(patientId,out pat))
  {
     pat = new Patient(patientId);
     _data.Add(patientId,pat);
  }

  pat.Message = Message;
}

// Called once after the last message has been processed.
// It is a good place to perform cleanup and to report information.
// Always called from the UI thread.
public override void OnFinish()
{
   SaveMessage(_data.Values.Select(p=>p.Message),"Last A08");
}

How do I remove PR1 segments?

Question:
Let’s say that I have a particular interface that is shipping me bad PR1 transactions, which is killing my interface. The vendor on the other side can’t make a change to his interface just yet, and I want to drop all those bad PR1s and let the vendor catch them up for me at a later date when he’s cleaned his data up. Is there a function that deals with including or deleting particular segments?

Answer:
If you create a new Custom Function and paste this code in, load up some messages with PR1 segments, and press “Run”, the PR1 segments will get stripped out.

 public override void Run()
 {
    // Get an HL7 Message in parsed format
    HL7Message message = GetParsedMessage();
    // remove any segment with name PR1"
    message.RemoveAll(s=>s.SegmentName=="PR1");
    // save the message into an new tab called No PR1s
    SaveMessage(message, "NO PR1s");
 }

HL7Spy v1.7.68 Released

  • Much reduced memory usage when opening thousands of files using “Open Folder”
  • Show a “Loading..” message when loading messages over 1MB in size
  • Right-Click option to export the unescaped field to a file and to attempt to interpret the MIME type of the data
  • Fixed the search dialog to be automatically pre-populated with the currently selected values – reported by Denise G.
  • Fixed occasional IndexOutOfRangeException when pasting into the Message editor
  • Better error information when executing HL7 Sql query with syntax error

HL7Spy v1.7.65 Released

  • Query Results from “HL7 SQL” queries are now shown on a per tab basis.
  • Added “Clone This Tab” option to the Right-Click on Tab Menu Items. This allows you to quickly copy the contents of a tab, and preform queries on it.
  • Fix Encoding character definition for the escaped Component was in correct. \C\ when it should have been \S\
  • Fix sorting of Message Editor Tabs for collections created via a query.
  • Fix out of range exception while parsing a message
  • Fix cancel on exit when there are pending changes to a message collection
  • Fix processing of hex values in the HL7Parser
  • Fix HL7 Compare in Sql Loader and HL7 Query displays items in the reverse order they were selected

HL7Spy 1.7.60 Released

  • Add an menu option to disable loading files into an existing instance of HL7Spy when double-clicking on file in Windows Explorer
  • Show name of Message Collection being searched in the title bar of the search window
  • Fix issue where copy/paste/undo/redo events are always being sent to the Message Editor window.
  • Add support for Undo/Redo to HL7 SQL and Sql Loader editors
  • Add Browse button to the “Add References Dialog” in the Custom Code Device
  • Fix key-binds for control-space, and ‘.’ in the Custom Code Device
  • Fix suggested file name to be a legal Windows file name when exporting to excel
  • HL7 parser should let tab (0x09) characters through. Currently TAB is being replaced with a space
  • When “Reuse Results Tab” is not selected, there should be a results grid per tab created – requested by Doug M. from Cleveland Clinic
  • Show the Query that was used to generate the tab when hovering over the Message Tab
  • Fix StackOverflowException when referencing Microsoft.Practices.Unity.dll in the Custom Code Device

Capture EVN-1, PID-3, PV1-2, FT1-2 to file

Question:
How can I capture a list of the following fields: EVN-1, PID-3, PV1-2, FT1-2 in a comma delimited list?
Answer:
Custom code is the best approach if you are expecting repeated FT1 segments. The following code will create a file in the c:\temp directory containing the specified list, and will display in Notepad upon completion.

string _fileName = @"c:\temp\_test.txt";
StreamWriter _file;

public override void Run() {
  // Get an HL7 Message in parsed format
  HL7Message message = GetParsedMessage();
  // Get the first FT1 segment
  EVN evn = message.Segments.OfType<EVN>().FirstOrDefault();
  PID pid = message.Segments.OfType<PID>().FirstOrDefault();
  PV1 pv1 = message.Segments.OfType<PV1>().FirstOrDefault();
  foreach(FT1 ft1 in message.Segments.OfType<FT1>())
  {
    _file.Write("{0},",evn != null ? evn.EventTypeCode_01.Value : null);
    _file.Write("{0},",pid != null ? pid.PatientIdentifierList_03.First.Value : null);
    _file.Write("{0},",pv1 != null ? pv1.PatientClass_02.Value : null);
    _file.Write("{0},",ft1 != null ? ft1.TransactionID_02.Value : null);
    _file.WriteLine();
  }
}

public override void OnStart()
{
  // create the file to be written out
  _file = new StreamWriter(_fileName,false);
  _file.WriteLine("EVN_EVENT_TYPE, PID_MRN, PV1_PATIENTCLAS", "FT1_TRANS_ID");
}

// Called once after the last message has been processed.
// It is a good place to perform cleanup and to report information.
// Always called from the UI thread.
public override void OnFinish() {
  // sort the data
  _file.Close();
  // launch notepad to display the file.
  System.Diagnostics.Process.Start("Notepad",_fileName);
}

Messages with duplicate OBR-3.1 to a new tab

Question:
I’m looking the way to get “DISTINCT” OBR-3.1 value messages. How can I do this in custom code. I want to show any messages that have duplicate OBR-3.1 values to a new tab. Please note we have multiple OBR segments per message.

Answer:
The following code should do the trick.

private class TrackedItem
{
   public List<IMessageData> Messages=new List<IMessageData>();
   public int Index {get;set;}
}

Dictionary<string,TrackedItem> _knownValues = new Dictionary<string,TrackedItem>(StringComparer.CurrentCultureIgnoreCase);

public override void OnStart() {
  _knownValues.Clear();
}

public override void Run() {
  // Get an HL7 Message in parsed format
  HL7Message message = GetParsedMessage();
  OBR obr = message.Segments.First<OBR>();
  if(obr != null && !string.IsNullOrEmpty(obr.FillerOrderNumber_03.Value))
  {
    string obrIdentifier = obr.FillerOrderNumber_03.Value;
    TrackedItem item;
    if(!_knownValues.TryGetValue(obrIdentifier,out item))
    {
       item = new TrackedItem();
       _knownValues.Add(obrIdentifier,item);
    } else
    {
       Log(Severity.Informational,string.Format("duplicates found at index",MessageIndex));
       if(item.Index==0)
        item.Index = MessageIndex;
    }
    item.Messages.Add(Message);
  }
}

public override void OnFinish() {
  var list = _knownValues.Values.Where(i=>i.Messages.Count>1).ToList();
  Log(Severity.Informational,string.Format("{0} duplicates found",list.Count));
  foreach(TrackedItem item in list)
  {
    SaveMessage(item.Messages,"Duplicates");
  }
}

How do I create test data from a set of messages?

Question:
I would like to book some of you and or your teams time to develop or enhance HL7spy custom codes or product for my team. We would like the custom code to do the following:

  1. Take HL7 transactions (loaded in the Query Results tab)
  2. Append “-” + OBR-2.1 … to OBR-3.1 + “-” + some variable, ‘date yyyymmdd’
  3. Append “-” + some variable like “TEST” to OBR-3.2
  4. Delete the contents of OBR-2

Answer:
No need to hire us. This is pretty easy to do. There are two ways of accomplishing this: using type safe classes, and using field position specifications. Type safe classes provide the benefit of automatically documenting the code.

public override void Run() {
  // Get an HL7 Message in parsed format
  HL7Message message = GetParsedMessage();
  string today=DateTime.Today.ToString("yyyyMMdd");
  // loop through all the OBR segments in the message
  foreach(OBR obr in message.GetSegments<OBR>())
  {
    //(2) Append "-" + OBR-2.1 ... to OBR-3.1 + "-" + some variable, 'date yyyymmdd'
    obr.FillerOrderNumber_03.EntityIdentifier_01.Value = obr.PlacerOrderNumber_02.EntityIdentifier_01.Value + "-V" + today; 
    //(3) Append "-" + some variable like "TEST" to OBR-3.2
    obr.FillerOrderNumber_03.NamespaceID_02.Value = obr.FillerOrderNumber_03.NamespaceID_02.Value + "-TEST";
    //(4) Delete the contents of OBR-2
    obr.PlacerOrderNumber_02.Value = "";
    // save the message out to a new tab
    SaveMessage(message, "Modified Messages");
  }
}
public override void Run() {
  // Get an HL7 Message in parsed format
  HL7Message message = GetParsedMessage();
  string today=DateTime.Today.ToString("yyyyMMdd");
  foreach(OBR obr in message.GetSegments<OBR>())
  {
    //(2) Append "-" + OBR-2.1 ... to OBR-3.1 + "-" + some variable, 'date yyyymmdd'
    obr[3,1,1] = obr[2,1,1] + "-V" + today;
    //(3) Append "-" + some variable like "TEST" to OBR-3.2
    obr[3,1,2] = obr[3,1,2] + "-TEST";
    //(4) Delete the contents of OBR-2
    obr[2] = "";
    // save the message out to a new tab
    SaveMessage(message, "Modified Messages");
  }
}

Find all unique OBX-3/OBR-3 values

Question:
Hi, I am using HL7Spy HL7 SQL for the first time and am trying to pull the values stored in obx-3.1.1 for repeating obx segments but it seems to be only pulling the first value. I thought that this query would accomplish what I needed but I do not believe it is.

SELECT OBx[*]-3.1.1,OBx[*]-3.2.1 WHERE OBx[*]-3.1.1 IS NOT NULL

I would also like to find all unique OBR-4 values too.

Answer:

The HL7 SQL function will only return one result per message, so it probably not what you are looking for.

It would be quite easy to write a Custom Function to do what you are looking for. Is your goal to get a list of OBX-3.1, OBX-3.2 pairs with perhaps a count of how many times each pair occurred? If so, here is some code that will do just that.

private class TrackedItem
{
   public string Key {get; set;}
   public string Value {get;set;}
   public int Counter {get;set;}
}

Dictionary<string,TrackedItem> _knownValues = new Dictionary<string,TrackedItem>(StringComparer.CurrentCultureIgnoreCase);


public override void Run() {
  // Get an HL7 Message in parsed format
  HL7Message message = GetParsedMessage();
  foreach(OBX obx in message.Segments.OfType<OBX>())
  {  
    string key = obx.ObservationIdentifier_03.Identifier_01.Value;   
    TrackedItem item;
    if(!_knownValues.TryGetValue(key,out item))
    {
       item = new TrackedItem {Key=key, Value=obx.ObservationIdentifier_03.Text_02.Value};
       _knownValues.Add(key,item);
    }
    item.Counter = item.Counter + 1;
  }
}

private string _fileName = @"C:\temp\_test.txt";
public override void OnFinish() {
  using(var stream = new System.IO.StreamWriter(_fileName))
  {
    stream.WriteLine("OBX-3.1, OBX-3.2, Count");
    foreach(TrackedItem item in _knownValues.Values.OrderByDescending(i=>i.Counter))
    {
      stream.Write(item.Key);    
      stream.Write("\t");
      stream.Write(item.Value);
      stream.Write("\t");
      stream.WriteLine(item.Counter.ToString());
    }
  }
 
  try{
    System.Diagnostics.Process.Start("Notepad",_fileName);
  } catch{}
}

And, a variation on the same theme for OBR-4

private class TrackedItem
{
   public string Key {get; set;}
   public string Value {get;set;}
   public int Counter {get;set;}
}

Dictionary<string,TrackedItem> _knownValues = new Dictionary<string,TrackedItem>(StringComparer.CurrentCultureIgnoreCase);

public override void Run() {
  // Get an HL7 Message in parsed format
  HL7Message message = GetParsedMessage();
  foreach(OBR obr in message.Segments.OfType<OBR>())
  {  
    string key = obr.universalServiceIdentifier_04.Identifier_01.Value;   
    TrackedItem item;
    if(!_knownValues.TryGetValue(key,out item))
    {
       item = new TrackedItem {Key=key, Value=obr.UniversalServiceIdentifier_04.Text_02.Value};
       _knownValues.Add(key,item);
    }
    item.Counter = item.Counter + 1;
  }
}

private string _fileName = @"C:\temp\_test.txt";
public override void OnFinish() {
  using(var stream = new System.IO.StreamWriter(_fileName))
  {
    stream.WriteLine("OBR-4.1, OBR-4.2, Count");
    foreach(TrackedItem item in _knownValues.Values.OrderByDescending(i=>i.Counter))
    {
      stream.Write(item.Key);    
      stream.Write("\t");
      stream.Write(item.Value);
      stream.Write("\t");
      stream.WriteLine(item.Counter.ToString());
    }
  }

  try{
    System.Diagnostics.Process.Start("Notepad",_fileName);
  } catch{}
}

HL7Spy 1.7.55 Released

  • SqlLoader – Remember users last setting for SqlLoader’s ReuseResultsTab
  • SqlLoader – Added counter to Query tab when “Reuse Results Tab” is unselected
  • Message Editor – Hook up menu item Alt- shortcuts
  • Message Editor – Added a save dialog when message collection has changed
  • Message Editor – Add “Split” Tools menu item
  • Message Editor – Fixed issue when Pasting muliple messages with non-standard encoding formats
  • Message Editor – Fixed Order Tabs by MSH-7 option
  • Message Editor – Added order by ascending/descending in right-click menu item of tab
  • Message Editor – Move Edit and Tools menu items from ToolStrip to main window’s menu
  • Message Editor – Added “Close All” right-click on tab menu item
  • Message Editor – Fixed focus problem where the active document changes when the active Application changes
  • Message Editor – Remap Alt-F,A to save as instead of Close All to conform to windows norm
  • Message Editor – Fixed issue where it was not possible to save messages if all messages had parsing errors
  • Message Editor – Fixed Copy/Paste in the following: Watch List, Sql Loader, HL7 SQL, Custom Code
  • Custom Code – Fixed issue where an exception is thrown when setting a field, component, or subcomponent to null
  • Custom Code – Fixed issue with Anonymizer.Replace function

Find all Unique OBR-4 – OBX-3 pairs in a message stream

Question:
Here is some custom code that you wrote for as a while back. The code exports a row for every unique OBR 4 and OBX 3 pair, and a count of the occurrences. This report is used by our lab mappers during the mapping process for a new laboratory. The lab mappers are requesting that the report contain additional information. Below is what they are requesting, with the more important item on top:

Include a full message with each OBR 4 – OBX 3 pair. It could be the 1st message for this pair, the last message for this pair, or any other message for this pair. Which message isn’t as import as actually having a message that contains the OBR 4 – OBX 3 pair. They plan to visually review this message as they are doing the mapping to resolve any issues with method, units, reference range, etc.

Include a list of OBR 4 terms only without any OBX information. They plan to use this for mapping the OBR 4 term, which we do for radiology and text reports.

Answer:
The following code will create a

private class TrackedItem
{
   public string Value {get;set;}
   public int Counter {get;set;}
}

Dictionary<string,TrackedItem> _knownValues = new Dictionary<string,TrackedItem>(StringComparer.CurrentCultureIgnoreCase);
private string _fileName = @"C:\temp\data.hl7";

public override void Run() {
  // Get an HL7 Message in parsed format
  HL7Message message = GetParsedMessage();
  foreach(OBX obx in message.GetSegments<OBX>())
  {
    string obrIdentifier = message["OBR-4.1.1"];
    string obxIdentifier = obx.ObservationIdentifier_03.Identifier_01.Value;
    string key = (obrIdentifier + "-" + obxIdentifier).Trim();
    TrackedItem item;
    if(key=="-")
      continue;
    
    if(!_knownValues.TryGetValue(key,out item))
    {
       item = new TrackedItem();
       item.Value = string.Format("{0}|{1}|{2}|{3}|{4}|{5}|{6}|{7}",message["OBR-4.1"],message["OBR-4.2"],message["OBR-4.3"],obx.ObservationIdentifier_03.Identifier_01, obx.ObservationIdentifier_03.Text_02, obx.ObservationIdentifier_03.NameOfCodingSystem_03,obx.Units_06,obx.ReferencesRange_07);
       _knownValues.Add(key,item);
    }
    item.Counter = item.Counter + 1;
  }
}

public override void OnFinish() {
  using(var stream = new System.IO.StreamWriter(_fileName))
  {
    foreach(TrackedItem item in _knownValues.Values.OrderByDescending(i=>i.Counter))
    {
      stream.Write(item.Counter.ToString());
      stream.Write("|");
      stream.WriteLine(item.Value);
    }
  }
  
  try{
   // System.Diagnostics.Process.Start("Notepad",_fileName);
  } catch{}
}

Find all CPT codes for each patient

Question:
What I want to do is for each of the three accounts contained in PID-18, show all PR1-3 fields for all PR1 segments. Typically, these are sequential segments, e.g., PR1|1…, PR1|2…, etc. The purpose is to generate a list of all procedure and CPT codes for each of the patients.

Answer:
please try the following code:

make sure you can access the c:\temp directory, that is where the file is being stored.

To narrow the search, use HL7 SQL to filter for the patient accounts you are interested in, into a separate tab (SELECT INTO).

or, modify the _patientAccount list below to include the patients you want included, and uncomment the code with the // (1) “Uncomment me” comment

string _fileName = @"c:\temp\_test.txt";
private StreamWriter _writer;

// patient Identifiers
private string[] _patientAccounts = new string[]{"952-11-3088", "H000759100", "H000759092", "H000759118"};

public override void OnStart() {
  _writer = new StreamWriter(_fileName);
}

public override void Run() {
  // Get an HL7 Message in parsed format
  HL7Message message = GetParsedMessage();
 
  PID pid = message.Segments.First<PID>();
  if(pid==null)
    return; // no pid segment
 
  // (1) Uncomment me
  //if(!_patientAccounts.Contains(pid[18,1,1]))
  //  return;
   
  foreach(var pr1 in message.Segments.OfType<PR1>())
  {
    if(pr1[3]!="")
    {
    _writer.WriteLine("{0},{1},{2},{3},{4},{5}",this.MessageIndex, pid[18], message.MSH[7], message.MSH[10], pid[5], pr1[3]);
    }
  }
}

// Called once after the last message has been processed.
// It is a good place to perform cleanup and to report information.
// Always called from the UI thread.
public override void OnFinish()
{
  if(_writer!=null)
  {
    _writer.Close();
    _writer = null;
  }
  // launch notepad to display the file.
  System.Diagnostics.Process.Start("Notepad",_fileName);
}