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{}
}

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