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>();
    return; // no pid segment

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

  // handle A03 Discharges
    if(!_discharged.TryGetValue(encounterId,out CSN)) // is patient already in the discharged dictionary?

    // 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.


  // For A08 patient updates, check if the patient is already discharged.
    if(_discharged.TryGetValue(encounterId,out CSN)) // is patient in the discharged dictionary?

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

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