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");
}

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");
  }
}