NextGen Mirth:循环遍历所有 OBR/OBX 段以输出到 Document Writer

NextGen Mirth: Loop through all OBR/OBX segments for output to Document Writer

大约 10 年前我用过 Mirth,然后意识到我几乎忘记了一切,而且我的很多资源都不再可用。我希望遍历 OBR 和 OBX 段以将 OBR 4.2、7.1、16.2 用作部分 header 和 OBX 3.2、5.1、7.1 字段以在报告下方显示。

基本上就是这样:

MSH|^~\&|LAB|LIS||EMR|202107201651||ORU^R01|082017045701|P|2.3|| |NE|NE
PID|1||M1302^^^MR||TEST^PATIENT^T^^||19670101|M||| 123 8th street^apt.22b^long beach^CA^90802^||(714)555-1212|(714)222-5555||||873lfif|4441113||||||||||
PV1|1|O|RGH^^^RGH^^^^||||999999^TEST^TEST^^^^^L||||||||||288^ALBRIGHT^MD^^^^^L ||V4735|||||||||||||||||||||||||201008201648|
ORC|RE||15175|||||||||288^ALBRIGHT^MD^^^^^L|
OBR|1||15175|CBC^COMPLETE BLOOD COUNT^L|R|202107200800|202107200800|||BB^RGH^^^^^^ ^^^^^^RGH||||201008201648|B|288^ALBRIGHT^MD^^^^^L| |||||20100820170246|||F|^|||||100.0||||||||||||||G A
OBX|1|NM|WBC^WBC^L||4.0|10\S/MM\S|3.6-11.1||||F|||202107200759|RGH|ADM
OBX|2|NM|RBC^RBC^L||5.0|10\S/MM\S|4.50-5.90||||F|||202107200758|RGH|ADM
OBX|3|NM|HGB^HGB^L||12.5|g/dL|12.0-18.0||||F|||202107200757|RGH|ADM
ORC|RE||15175|||||||||288^ALBRIGHT^MD^^^^^L|
OBR|2||15175|ALC^ALCOHOL,ETHYL^L|R|202107201650|20 1008201648|||BB^RGH^^^^^^^^^^^^RGH||||201008201648 |B|288^ALBRIGHT^MD^^^^^L||||||20100820170246|||F|^ |||||||||||||||||||GA
OBX|1|NM|ALC^ALCOHOL (ETHANOL)^L||36|mg/dL|0-32|H|||F|||201008201650|RGH|ADM

并制作:

CBC 202107260800 ALBRIGHT
WBC 4.0 3.6-11.1
RBC 5.0 4.50-5.90
HGB 12.5 12.0-18.0
ALCOHOL, ETHYL 202107201650 ALBRIGHT
ALCOHOL (ETHANOL) 36 0-32

非常感谢任何帮助。

Mirth User Guide 提供了一些关于您要实现的目标的有趣文档。有一个名为 Iterating Over Message Segments 的部分对其进行了解释并提供了一些示例。

但是思路跟下面的很相似

//To iterate over all segments, follow this example:
for each (var segment in msg.children()) {
  if (segment.name().toString() == "ORC") {
    // Do something...
  }
} 

//To iterate through specifically named segments, use this formula:

for each (var segment in msg.OBX) {
  // Do something...
}

复杂的部分是如何将每个 OBX 与其对应的 OBROCR 相关联。我没有找到一种干净的方法来实现这一目标。我使用 Lists and Maps 并按顺序处理所有段,将相关字段添加到一些数据结构中,这有助于我获得最终结果。在你的情况下 table。

这是我所做的,它非常丑陋,还没有完全达到我的期望,所以请随时帮助我改进。我似乎无法在报告作者的 html 中获得嵌套的 foreach 以通过第二个 OBR 进行处理,所以希望在我弄清楚之前不要得到一个。

Source Transformer:我使用 Mapper

映射了患者信息

目标转换器:

var _OBR45PanelName = Lists.list();
var _OBR71DateTime = Lists.list();
var _OBR163ProviderFirstName = Lists.list();
var _OBR162ProviderLastName = Lists.list();
var _OBX32TestName = Lists.list();
var _OBX51Result = Lists.list();
var _OBX61UnitofMeasure = Lists.list();
var _OBX71ReferenceRange = Lists.list();
var _OBX81AbnormalFlag = Lists.list();
for (var i = 0; i < getArrayOrXmlLength(msg['OBR']); i++) {
    var mapping;
    try {
        mapping = msg['OBR'][i]['OBR.4']['OBR.4.5'].toString().trim();
    } catch (e) {
        mapping = '';
    }
    _OBR45PanelName.add(validate(mapping, '', new Array()));
    var mapping;
    try {
        mapping = msg['OBR'][i]['OBR.7']['OBR.7.1'].toString().trim();
    } catch (e) {
        mapping = '';
    }
    _OBR71DateTime.add(validate(mapping, '', new Array()));
    var mapping;
    try {
        mapping = msg['OBR'][i]['OBR.16']['OBR.16.3'].toString().trim();
    } catch (e) {
        mapping = '';
    }
    _OBR163ProviderFirstName.add(validate(mapping, '', new Array()));
    var mapping;
    try {
        mapping = msg['OBR'][i]['OBR.16']['OBR.16.2'].toString().trim();
    } catch (e) {
        mapping = '';
    }
    _OBR162ProviderLastName.add(validate(mapping, '', new Array()));
    for (var J = 0; J < getArrayOrXmlLength(msg['OBX']); J++) {
        var mapping;
        try {
            mapping = msg['OBX'][J]['OBX.3']['OBX.3.2'].toString().trim();
        } catch (e) {
            mapping = '';
        }
        _OBX32TestName.add(validate(mapping, '', new Array()));
        var mapping;
        try {
            mapping = msg['OBX'][J]['OBX.5']['OBX.5.1'].toString().trim();
        } catch (e) {
            mapping = '';
        }
        _OBX51Result.add(validate(mapping, '', new Array()));
        var mapping;
        try {
            mapping = msg['OBX'][J]['OBX.6']['OBX.6.1'].toString().trim();
        } catch (e) {
            mapping = '';
        }
        _OBX61UnitofMeasure.add(validate(mapping, '', new Array()));
        var mapping;
        try {
            mapping = msg['OBX'][J]['OBX.7']['OBX.7.1'].toString().trim();
        } catch (e) {
            mapping = '';
        }
        _OBX71ReferenceRange.add(validate(mapping, '', new Array()));
        var mapping;
        try {
            mapping = msg['OBX'][J]['OBX.8']['OBX.8.1'].toString().trim();
        } catch (e) {
            mapping = '';
        }
        _OBX81AbnormalFlag.add(validate(mapping, '', new Array()));
    }
}
channelMap.put('OBR4.5 Panel Name', _OBR45PanelName.toArray());
channelMap.put('OBR7.1 DateTime', _OBR71DateTime.toArray());
channelMap.put('OBR16.3 Provider FirstName', _OBR163ProviderFirstName.toArray());
channelMap.put('OBR16.2 Provider LastName', _OBR162ProviderLastName.toArray());
channelMap.put('OBX3.2 Test Name', _OBX32TestName.toArray());
channelMap.put('OBX5.1 Result', _OBX51Result.toArray());
channelMap.put('OBX6.1 Unit of Measure', _OBX61UnitofMeasure.toArray());
channelMap.put('OBX7.1 Reference Range', _OBX71ReferenceRange.toArray());
channelMap.put('OBX8.1 Abnormal Flag', _OBX81AbnormalFlag.toArray());

对于报告作者我有:

<html>
<head>
<style type="text/css">
div table {
    float: left;
}
div table th, td {
    word-wrap: break-word;
    border: 1px solid lightgrey;
    padding-right: 5px;
    height: 25px;
    text-align: left;
}
</style>
</head>
<body>
<h1>Laboratory Results</h1>
<table>
<tr><th>Name:</th><th>DOB:</th></tr>
<tr><td>${maps.get('PID5.2 Patient FirstName')} ${maps.get('PID5.3 Patient MiddleName')} ${maps.get('PID5.1 Patient LastName')}</td><td>${maps.get('PID7.1 Patient DoB')}</td></tr>
<tr><th>Ordering Provider:</th><td>${maps.get('OBR16.3 Provider FirstName')} ${maps.get('OBR16.2 Provider LastName')}</td></tr>
</table>

<table>
#foreach ($item in ${maps.get('OBR4.5 Panel Name')})
<tr><th>${maps.get('OBR4.5 Panel Name')}</th></tr>
<div>
<table>
<tr><th>Test</th></tr>
#foreach ($item in ${maps.get('OBX3.2 Test Name')})
<tr><td>$item</td></tr>
#end
</table>
<table>
<tr><th>Result</th></tr>
#foreach ($item in ${maps.get('OBX5.1 Result')})
<tr><td>$item</td></tr>
#end
</table>
<table>
<tr><th>Unit of Measure</th></tr>
#foreach ($item in ${maps.get('OBX6.1 Unit of Measure')})
<tr><td>$item</td></tr>
#end
</table>
<table>
<tr><th>Range</th></tr>
#foreach ($item in ${maps.get('OBX7.1 Reference Range')})
<tr><td>$item</td></tr>
#end
</table>
<table>
<tr><th>Flag</th></tr>
#foreach ($item in ${maps.get('OBX8.1 Abnormal Flag')})
<tr><td>$item</td></tr>
#end
</table>
</div>
#end
</table>
</body>
</html>

结果(又丑了)like this

您仍然可以使用 html 和 css,但这里是您组织数据并快速循环处理数据的方法。我们首先遍历 OBR 片段。然后我们使用 getSegmentsAfter 函数获取与当前 OBR 段关联的 OBX 段。函数 returns 将结果作为 xml 对象的数组,然后我们将其转换为纯 js 对象。

可在此处找到 getSegmentsAfter 函数的代码模板 https://github.com/nextgenhealthcare/connect-examples/tree/master/Code%20Templates/Get%20Segments%20After%20a%20Particular%20Segment

这是可行的,因为 javascript 数组实现了 java.util.Collection 接口,而 javascript 对象实现了 java.util.Map 接口,这两个速度都知道如何访问。

变形金刚

var reportData = [];
for each (var obr in msg.OBR) {
    var  sectionHeader = {
        panelName: obr['OBR.4']['OBR.4.2'].toString().trim(),
        dateTime: obr['OBR.7']['OBR.7.1'].toString().trim(),
        providerName: obr['OBR.16']['OBR.16.3'].toString().trim() + ' ' + obr['OBR.16']['OBR.16.2'].toString().trim()
    };
    var sectionData = getSegmentsAfter(msg, obr, 'OBX')
        .map(function(obx) {
            return {
                testName: obx['OBX.3']['OBX.3.2'].toString().trim(),
                result: obx['OBX.5']['OBX.5.1'].toString().trim(),
                unitOfMeasure: obx['OBX.6']['OBX.6.1'].toString().trim(),
                referenceRange: obx['OBX.7']['OBX.7.1'].toString().trim(),
                abnormalFlag: obx['OBX.8']['OBX.8.1'].toString().trim()
            }});
    reportData.push({
        header: sectionHeader,
        data: sectionData
    });
}
$co('reportData', reportData);

Document Writer 模板

<html>
<head>
  <style type="text/css">
  div table {
    width: 100%;
    margin-bottom: 5px;
  }
  div table th, td {
    word-wrap: break-word;
    border: 1px solid lightgrey;
    text-align: left;
  }
  div {
    border: 1px solid grey;
    margin: 5px;
  }
  </style>
</head>
<body>
  <h1>Laboratory Results</h1>

  #foreach ($section in $reportData)
  <div>
  <table>
  <tr>
    <th>Panel Name</th><th>DateTime</th><th>Provider</th>
  </tr>
  <tr>
    <td>$section.header.panelName</td>
    <td>$section.header.dateTime</td>
    <td>$section.header.providerName</td>
  </tr>
  </table>

  <table>
  <tr>
    <th>Test</th><th>Result</th><th>Unit of Measure</th><th>Range</th><th>Flag</th>
  </tr>
    #foreach ($row in $section.data)
    <tr>
      <td>$row.testName</td>
      <td>$row.result</td>
      <td>$row.unitOfMeasure</td>
      <td>$row.referenceRange</td>
      <td>$row.abnormalFlag</td>
    </tr>
    #end
  </table>
  </div>
  #end
</body>
</html>

结果