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
与其对应的 OBR
和 OCR
相关联。我没有找到一种干净的方法来实现这一目标。我使用 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>
结果
大约 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
与其对应的 OBR
和 OCR
相关联。我没有找到一种干净的方法来实现这一目标。我使用 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>