追加の手順
この章では、HL7 処理をプロダクションに追加するために必要な追加の手順について説明します。以下のトピックについて説明します。
これらのタスクはプロダクションが存在しているネームスペースで実行する必要があります。ルール・セット、変換、および検索テーブルを作成する場合は、予約パッケージ名を使用しないでください。"Ensemble プロダクションの開発" の “予約パッケージ名” を参照してください。
"Ensemble 仮想ドキュメント" の “検証ロジックの上書き” も参照してください。
HL7 のルーティング・ルール・セットの定義
HL7 インタフェースのルーティング・ルール・セットを作成する際の目的は、ソース・メッセージをその中にあるセグメントに基づいて処理する方法を Ensemble に指示することです。存在するセグメントが重要となる場合もあれば、それらのセグメント内にある値が重要となる場合もあります。
通常のルール・セットでは、そのルール・セットを呼び出したビジネス・プロセスにルールごとに値が返されます。ルーティング・ルール・セットでは、通常、個々のルールによって HL7 メッセージが宛先に送られます。送信前に HL7 メッセージが変換される場合もあります。
ルール・エディタの使用方法については、"ビジネス・ルールの開発" の “ルール・セットの作成および編集” を参照してください。
-
ビジネス・ルール・ウィザードを使用して新しい HL7 ルーティング・プロセスを作成すると、その新しいルーティング・プロセスに付随する新しい空のルーティング・ルール・セットが Ensemble によって作成されます。その情報テーブルには以下の値が格納されます。
-
[パッケージ名] — プロダクション・クラスを含むパッケージ。例えば、ウィザードを使用してルーティング・プロセスを TestRule.MyTest というプロダクションに追加した場合、関連付けられたルーティング・ルールは、以下の [パッケージ名] を持ちます。
TestRule
-
[ルール名] — ウィザードで選択した以下のような簡単な [ルーティング・ルール名]。
MyRule
[パッケージ名] と [ルール名] の組み合わせにより、Ensemble ネームスペース内で一意にルールが識別されます。ルール定義の完全名は、[パッケージ名] と [ルール名] がドット (.) で結合された以下のようなものになります。
TestRule.MyRule
[ルール名] よりこの完全名の方が、HL7 ルーティング・プロセスを構成する際に [BusinessRuleName] フィールドに使用する値として適しています。[ビジネス・プロセス] ウィザードはこれを自動的に設定します。
-
[ルーティング・エンジン・クラス] — ウィザードでのデフォルトの [ルータ・クラス] です。これは変更しないでください。
EnsLib.HL7.MsgRouter.RoutingEngine
-
-
独自のルール報告を目的として、次の追加フィールドに入力することもできます。
-
[レポート・グループ] — レポートの目的でルールをグループ化するための値
-
[レポート名] — ルール・レポート・グループの値を表示します
-
[簡単な説明] — このルール定義の簡単な説明 (省略可)
-
-
ルーティング・ルールの制約の入力に関する詳細は、"ビジネス・ルールの開発" の “ルール制約エディタの使用” を参照してください。
-
新しいルールを作成すると、これに [条件] および [アクション] を追加することができます。詳細は、"ビジネス・ルールの開発" の “ルール・セットの作成および編集” の章を参照してください。各ルールに [条件] を追加する際には、以下のヒントに注意してください。
-
[条件] は AND 演算子、OR 演算子の順に評価します。
-
[条件] は HL7 メッセージ・オブジェクトのプロパティを参照できます。[条件] 内で、特殊変数 Document は以下の例のように HL7 メッセージ・オブジェクトを表します。HL7 バッチ・ドキュメントの場合、特殊変数 Document.Parent を使用して親メッセージ・オブジェクトを表すことができます。
Document.Name Document.Parent.DocType Document.{PIDgrp.PV1grp.PV1:18} Document.{PIDgrp.PID:PatientName.familylastname} Document.{ORCgrp(1).OBRuniongrp.OBRunion.OBR:4.3}
Note:過去のリリースとの互換性を保つため、Document および Document.Parent の代替として特殊変数 HL7 および HL7.Parent がサポートされています。
ドットにより Document 変数とプロパティ名を区切ります。この名前は以下のようにすることができます。
-
任意のクラス・プロパティ : DocType、TypeCategory、BuildMapStatus、または Name。
-
以下の規則を使用して参照される仮想プロパティ :
-
{segmentPath:field}
-
[segmentName:field]
-
(multi-valued-property-path)
-
<context|expression>
詳細は、"Ensemble 仮想ドキュメント" の “構文ガイド” の節を参照してください。ただし、タイピングによりプロパティを入力する必要はありません。"ビジネス・ルールの開発" の “ルール・セットの作成および編集” で説明している方法でプロパティを参照できます。
-
-
-
-
ルーティング・ルール・セットで必要となる [ソース]、[ターゲット]、または [変換] の各項目を作成するには、次のいくつかのトピックの手順に従います。項目は以下のとおりです。
-
HL7 ビジネス・サービス (ルールへのメッセージのルーティング用)
-
DTL データ変換 (送信前のメッセージの変換用)
-
HL7 ビジネス・オペレーション (外部アプリケーションへのメッセージのルーティング用)
-
HL7 ルーティング・プロセス ([ソース] または [ターゲット])
項目を作成する際は、メッセージ・ルーティング・ルール・エディタに戻り、これらをルール定義の適切なフィールドに追加します。
-
-
Ensemble, プロダクション構成 ページのダイアグラムに戻ります。対応する HL7 ルーティング・プロセスを選択します。[BusinessRuleName] フィールドに新しいルーティング・ルール・セットの完全名を入力します。
HL7 の DTL データ変換の定義
各インタフェースでは、いくつかのデータ変換が必要になる場合があります。
データ変換内の HL7 エスケープ・シーケンスを手動で変更しないでください。これらは Ensemble によって自動的に処理されます。
データ変換を作成するには、Ensemble, データ変換ビルダ ページを使用します (管理ポータルでこのページにアクセスするには、[Ensemble]、[ビルド]、[データ変換] の順にクリックし、[OK] をクリックします)。このページの使用法に関する一般的な情報は、“DTL 変換の開発” を参照してください。
以下の図はこのページを示したものです。ここでは、ENSDEMO ネームスペースの MsgRouter.ADTLastNameTransform が表示されています。
以下のヒントに留意してください。
-
"DTL 変換の開発" を手元に置いておきます。このドキュメントでは、各種の DTL アクションの追加方法について説明します。
-
データ変換クラスの create オプションに必要な値について明確にします。create は、以下の値のいずれかを持つことができます。
-
new — データ変換内の要素を実行する前に、ターゲット・タイプの新しいオブジェクトを作成します。明示的にターゲット・オブジェクトに割り当てないソース・セグメントは無視されます。これがデフォルトです。
-
copy — 変換内の要素を実行する前に、ターゲット・オブジェクトとして使用するソース・オブジェクトのコピーを作成します。
-
existing — ターゲット・オブジェクトとしてデータ変換の呼び出し側により指定される既存のオブジェクトを使用します。
ソースの完全コピーであるターゲット・オブジェクトを作成するには、以下のようなアクションを使用しないでください。
<assign property='target' value='source' />
代わりに、データ変換クラス内の create='copy' 属性を使用します。
-
-
データ変換クラスが以下の正しいスキーマ・カテゴリを指定していることを確認します。
-
sourceDocType 属性
-
targetDocType 属性
ソース・オブジェクトとターゲット・オブジェクトで、スキーマ・カテゴリが同じ場合も、異なる場合もあります。
-
-
[変換] タブに、そのデータ変換内のすべての式および code アクションに使用するスクリプト言語が指定されていることを確認します。ObjectScript がデフォルト言語です。
-
assign アクションを使用して、ソース・メッセージの HL7 セグメントをターゲット・メッセージにドラッグ・アンド・ドロップ操作によって割り当てます。
場合により、いくつかの方法を組み合わせて使用することが必要になることもあります。まずコードのラインをドラッグして生成し、次にテキストを編集してそのコードを微調整することができます。
-
データ変換は、以下を含む HL7 メッセージ・オブジェクトのプロパティを参照できます。
-
クラス・プロパティ DocType、TypeCategory、BuildMapStatus、および Name。
-
"Ensemble 仮想ドキュメント" の “構文ガイド” の節にある “中かっこ {} の構文” で説明している仮想ドキュメント・プロパティ。
データ変換のクラス・コード内で、特殊変数 source および target は以下の例のようにそれぞれの HL7 メッセージ・オブジェクトを表します。
source.Name
target.DocType
source.{PIDgrp.PV1grp.PV1:18}
target.{PIDgrp.PID:PatientName.familylastname}
source.{ORCgrp(1).OBRuniongrp.OBRunion.OBR:4.3}
-
-
リテラル文字列の値の割り当てや条件の割り当てを行います。"DTL 変換の開発" の “構文規則” の章を参照してください。
Note:文字列リテラルには、XML 予約文字を含めることができません。また、HL7 で使用されるセパレータ文字を含めることもできません。
また、HL7 の NULL マッピング・コード "" には特殊な処理が必要です。以下の例は、ソース・メッセージ内の NULL マッピング・コードをテストし、ターゲット・メッセージ内でこれを空白文字列に置換します。
<if condition='source.{PV1:7().4}=""""""'> <true> <assign property='target.{PV1:7().4}' value='""' /> </true> </if>
詳細は、“ルーティング・プロダクションの構文” の章の “NULL マッピング・コード” を参照してください。
-
簡単な計算の場合、DTL データ変換は以下を行うことができます。
より複雑な計算の場合は、独自のクラス・メソッドを記述し、それらを code アクションから、または別の DTL 要素の値の文字列から呼び出すことができます。
-
変換と各アクションの説明を追加します。
-
データ変換のコンパイルはこの保存も行います。
-
DTL データ変換をプロダクションで使用するには、ルーティング・ルール・セットの [変換] フィールドに、DTL データ変換の完全なパッケージとクラス名を入力します。
NULL マッピング・コード
HL7 アプリケーションには NULL マッピング規則を適用するものがあります。この規則に従って、ソース・アプリケーションは、連続する 2 つの二重引用符文字 ("") で構成されるフィールドを送信できます。この値は、このフィールドにデータがある場合、これをアプリケーションから削除することを意味します。
多くのターゲット・アプリケーションはこのような指示を予想せず、これらに応答するよう設計されていません。このような場合、ターゲット・アプリケーションで二重引用符が実際の患者データとして保存され、このアプリケーション・ユーザには画面上に二重引用符文字が表示されます。これは厄介で、誤解を招く可能性があります。
ソース・アプリケーションが NULL マッピング規則を使用する場合、HL7 データ変換では HL7 フィールドの NULL マッピング・エントリをチェックしてこれらを空の文字列に置換することができます。NULL マッピング規則を使用しない場合は、ターゲット・アプリケーションに有効なデータを入力します。
以下の <if> 文は最も簡単なケースを表しています。ここでは、ソースで NULL マッピングをチェックし、ターゲットでこれを空の文字列に置き換えます。<if> condition は、2 組の引用符で囲まれた引用符を使用して NULL マッピング・コード "" をテストします。これにより、condition 値全体を囲む一重引用符以外に、合計 6 つの二重引用符文字が使用されます (注意してカウントしてください)。
<if condition='source.{PV1:7().4}=""""""'>
<true>
<assign property='target.{PV1:7().4}' value='""' />
</true>
</if>
上記の例で、<assign> value は、2 つの連続した二重引用符文字を使用し、一重引用符で value 全体を囲んで、空の文字列を示しています。
以下の構文も同様に有効です。
<if condition='source.{PV1:7().4}=""""""'>
<true>
<assign property='target.{PV1:7().4}' value='""' />
</true>
</if>
NULL マッピングを処理するため、より高度な目標を立てることができます。以下の例では、{PV1:3} に実際に値があるかどうかに基づいて代替アクションを取ります。フィールドに NULL マッピング・コードが含まれる場合、<true> 要素が実行されます。含まれない場合は <false> 要素が実行されます。
<if condition='source.{PV1:3}=""""""'>
<true>
<assign property='target.{PV1:3.1}' value='source.{PV1:PatientType}' />
<assign property='target.{PV1:3.2}' value='source.{PV1:PatientType}' />
</true>
<false>
<code>
// Dr Chart pulls subfields as follows:
// 1 location, 2 desc, 3 room, 4 bed, 5 wing, 6 floor
</code>
<assign property='target.{PV1:3.1}' value='source.{PV1:3.1}' />
<assign property='target.{PV1:3.2}' value='source.{PV1:3.1}' />
<assign property='target.{PV1:3.3}' value='source.{PV1:3.2}' />
<assign property='target.{PV1:3.4.1}' value='source.{PV1:3.3}' />
<assign property='target.{PV1:3.5}' value='source.{PV1:3.1}' />
</false>
</if>
HL7 検索テーブルの定義
HL7 検索テーブル・クラスの EnsLib.HL7.SearchTableOpens in a new tab は、一般的な HL7 プロパティに自動的にインデックスを付けます。“デフォルトでインデックスが付けられるプロパティ” を参照してください。
検索する項目を増やす場合は、サブクラスを作成できます。サブクラスは、Identifier プロパティに加えて、検索テーブルを機能させるインフラストラクチャを継承します。詳細は、"Ensemble 仮想ドキュメント" の “検索テーブル・クラスの定義” を参照してください。
HL7 では、Ensemble が PropType の追加の値をサポートしています。"Ensemble 仮想ドキュメント" に列挙されたタイプのほかに、DateTime:HL7 を使用できます。
デフォルトでインデックスが付けられるプロパティ
EnsLib.HL7.SearchTableOpens in a new tab を検索テーブル・クラスとして選択すると、Ensemble では、以下の仮想プロパティについて HL7 メッセージを検索できるようになります。
選択肢 | この値の参照方法 |
---|---|
MSHTypeName |
メッセージ構造名。この文字列を作成するには、Ensemble で HL7 メッセージの以下の値を連結します。
この結果、ADT_A01、ADT_A12、ORM_O01_2 などの形式のメッセージ構造名となります。 |
MSHControlID |
このメッセージの一意の識別番号。Ensemble ではこの値を以下より取得します。
Ensemble では、この値を大文字と小文字を区別する文字列として解釈します。 |
PatientID |
このメッセージの患者 ID。これは、HL7 標準が改訂された際に場所が移動されたフィールドです。このため、Ensemble では、以下のすべての場所でこの値を検索します。これにより、メッセージがどの HL7 スキーマ・カテゴリに適合するかに関係なく、患者 ID を見つけることができます。
|
PatientName |
PID 患者 ID セグメント フィールド 5 (患者名) |
PatientAcct |
PID 患者 ID セグメント フィールド 18 (患者アカウント番号) サブフィールド 1 (ID) |
例
以下の例には、{} 構文を使用する仮想プロパティ・パスが 1 つ含まれています。この <Item> 要素は、HL7 メッセージのセグメント 1、フィールド 10 の値を参照します。
<Item DocType=""
PropName="MSHControlID"
PropType="String:CaseSensitive"
StoreNulls="true" >
{1:10}
</Item>
以下のより複雑な <Item> 要素では、ObjectScript _ 演算子を使用して 3 つの文字列を連結します。これらの文字列は左から順に以下のようになります。
-
セグメント 1、フィールド 4 内の値
-
リテラル文字 -
-
セグメント 1、フィールド 3 内の値
<Item DocType=""
PropName="SendingFacilApp" >
{1:4}_"-"_{1:3}
</Item>
以下の <Item> の例では、連結、仮想プロパティ、リテラル・ハイフン文字 (-)、および ObjectScript 文字列関数 $PIECE という、有効な構文オプションのほとんどを使用しています。
XData SearchSpec [ XMLNamespace="http://www.intersystems.com/EnsSearchTable" ]
{
<Items>
<Item DocType="Mater:ORM_O01 "
PropName="RelationKey" >
$P(
{ORCgrp(1).OBRuniongrp.OBRunion.OBR:UniversalServiceID.text},"-",1,2
)_"-"_{MSH:12}
</Item>
</Items>}
以下の検索テーブル・クラスのサンプルには、有効な <Item> エントリのいくつかの例が示されています。このクラスは、HL7 検索テーブルで必要に応じて EnsLib.HL7.SearchTableOpens in a new tab から継承されます。<Item> エントリの各グループの上のコメントには、その一連のエントリの目的が示されています。{} または [] 構文の詳細は、"Ensemble 仮想ドキュメント" の “構文ガイド” の節を参照してください。
Class Demo.HL7.MsgRouter.SearchTable Extends EnsLib.HL7.SearchTable
{
XData SearchSpec [ XMLNamespace="http://www.intersystems.com/EnsSearchTable" ]
{
<Items>
<!-- Items that do not depend on DocType, indexing any HL7 message -->
<Item DocType="" PropName="SendingFacilApp" >{1:4}_"|"_{1:3}</Item>
<Item DocType="" PropName="RecvingFacilApp" >{1:6}_"|"_{1:5}</Item>
<Item DocType="" PropName="MSHDateTime" PropType="DateTime:HL7" >{1:7}</Item>
<!-- Get fields from named segments found in any HL7 message -->
<Item DocType="" PropName="PatientName" >[PID:5]</Item>
<Item DocType="" PropName="InsuranceCo" >[IN1:4]</Item>
<!-- Get patient name from any HL7 message declared type ADT_A05 -->
<Item DocType=":ADT_A05" PropName="PatientName" >{3:5}</Item>
<!-- Get specific field from specific segment when the -->
<!-- HL7 message is assigned a specific DocType. Only in this -->
<!-- case can you use names for segments, instead of numbers. -->
<Item DocType="Demo.HL7.MsgRouter.Schema:ORM_O01 " PropName="ServiceId" >
{ORCgrp().OBRuniongrp.OBRunion.OBR:UniversalServiceID.text}
</Item>
<Item DocType="2.3.1:ORU_R01 " PropName="ServiceId" >
{PIDgrpgrp().ORCgrp(1).OBR:UniversalServiceID.text}
</Item>
</Items>
}
}