その他のアクションの追加
この章では、DTL 変換にその他の種類のアクションを追加する方法について詳しく説明します。この章は以下の節で構成されています。
assign アクションの追加方法は、前の章を参照してください。
If アクションの追加
if アクションは、指定された式の値に応じて、その他のアクションを条件付きで実行します。Ensemble では、それぞれの if アクションが DTL ダイアグラム内のコネクタ線で表現されます。
if アクションを追加するには:
-
条件がソース・プロパティの値に依存する場合は、そのプロパティをクリックします。
-
[アクションの選択] ドロップダウン・リストから [if] を選択します。
[アクション] タブでは、[条件] フィールドに、選択されたソース・プロパティの名前が自動的に入力されます。
ダイアグラムの下の領域に 3 つの新しい行が表示されます。次のように、これらの行のラベルが [アクション] 列に表示されます。
-
if — この行は、条件が真の場合に実行するアクションの始まりを表します。
-
else — この行は、条件が偽の場合に実行するアクションの始まりを表します。
-
endf — この行は、if アクションの終わりを表します。
-
-
真または偽に評価される式を含めるように [条件] フィールドを編集します。
以下に例を示します。
source.ABC = "XYZ"
注 :
-
条件が真の場合に実行するアクションを追加するには:
-
if 行をクリックします。
-
[アクション追加] ドロップダウン・リストから項目を選択します。
-
必要に応じて、[アクション] タブで値を編集します。
-
必要に応じて繰り返します。
assign アクション、if アクション、および for each アクションを含めることができます。
-
-
条件が偽の場合に実行するアクションを追加するには:
-
else 行をクリックします。
-
前の項目で説明したように先に進みます。
-
これで、DTL ダイアグラムの下のブロック内に詳細が表示されます。以下に例を示します。
if 分岐または else 分岐用のアクションを指定する必要はありません。どの分岐にもアクションが含まれていない場合は、if アクションが無視されます。
For Each アクションの追加
for each アクションでは、繰り返し実行される一連のアクションを、以下のいずれかの各メンバに対して 1 回定義できます。
-
コレクション・プロパティ (標準メッセージ)
-
繰り返しプロパティ (Ensemble 仮想ドキュメント)
-
ドキュメント内の一連のサブドキュメント (Ensemble 仮想ドキュメント)
Ensemble では、それぞれの for each アクションが DTL ダイアグラム内のコネクタ線で表現されます。
for each アクションを追加するには:
-
ソース・メッセージ内のコレクション・プロパティまたは繰り返しプロパティを選択します。
-
[アクションの選択] ドロップダウン・リストから [for each] を選択します。
[アクション] タブでは、[プロパティ] フィールドに、選択されたソース・プロパティの名前が自動的に入力されます。
また、[キー] フィールドに k1 が自動的に入力されます。for each アクションの場合は、[キー] フィールドでカウンタ変数の名前を指定します。
-
[アクション] タブの [プロパティ] フィールドでは、反復子キーを括弧内に含めることはできません。例として、以下は正しい指定です。
source.{PID:PatientIdentifierList( )}
これは、Ensemble が PatientIdentifierList 繰り返しフィールドを通して繰り返す (最初のフィールド (1 番) から始まって最後のフィールドで終わる) ことを意味します。
以下に例を示します。
-
for each ブロックにアクションを追加するには、for each アクションをクリックしてから、該当するアクションを追加します。
これで、DTL ダイアグラムの下のブロック内に詳細が表示されます。以下に例 (一部) を示します。
<foreach> がメッセージ内のコレクション・プロパティに適用される場合、一連のアクティビティは繰り返し実行されますが、コレクション・プロパティ内に存在するすべての要素に対して 1 回実行されます。要素が NULL の場合、このシーケンスは実行されません。このシーケンスは、要素に空の値がある場合に (つまり、セパレータはあるがその間に値がない場合に) 実行されます。しかし、NULL 値に対しては実行されません。つまり、フィールドが指定される前にメッセージが終了します。
For Each アクションのショートカット
仮想ドキュメントを操作している場合は、ドキュメント構造内の繰り返しフィールドのすべてのインスタンスを通して繰り返すショートカット表記が提供されます。これは、実際には、繰り返しフィールドを処理するためのネストされた複数の for each ループをセットアップする必要がないことを意味します。代わりに、中かっこ { } 構文内の空の丸かっこを含む仮想プロパティ・パスを使用して単一の assign アクションを作成します。詳細は、"Ensemble 仮想ドキュメント" の “中かっこ {} の構文” を参照してください。
ソースとターゲットのタイプが異なる場合は (EnsLib.HL7.MessageOpens in a new tab から EnsLib.EDI.XML.DocumentOpens in a new tab への変換など)、このショートカットを For Each アクションに対して使用することはできません。このような場合は、明示的な For Each アクションを使用してください。
ラージ・メッセージでの <STORE> エラーの回避
HL7 メッセージまたはオブジェクト・コレクションでセグメントのループ処理を行う際には、セグメントがメモリに書き込まれます。これらのオブジェクトによって現在のプロセスに割り当てられているすべてのメモリが消費されると、予期しないエラーが発生することがあります。
これを避けるために、不要になったオブジェクトはメモリから削除します。例えば、for each ループで複数の HL7 セグメントを処理している場合は、ループの最後のステップとしてソースとターゲットの両方に対する commitSegmentByPath() メソッドを呼び出すことができます。同様に、オブジェクト・コレクションの場合は、%UnSwizzleAt() メソッドを使用します。
例えば、最も内側の for each ループ内に、以下の ObjectScript を含む code アクションを追加します。
Do source.commitSegmentByPath("ORCgrp("_tORCkey_").OBRgrp("_tOBRkey_").OBXgrp("_tOBXkey_").OBX")
Do target.commitSegmentByPath("ORCgrp("_tORCkey_").OBRgrp("_tOBRkey_").OBXgrp("_tOBXkey_").OBX")
コードを変更できない場合の一時的な回避策としては、各プロセスに割り当てられているメモリの量を増やします。この変更を行うには、管理ポータルの [メモリ詳細設定] ページで bbsiz パラメータを設定します。この場合、システムを再起動する必要がある点に注意してください。また、この変更を行う前に、必ずシステム管理者に相談してください。
Subtransform アクションの追加
subtransform は通常、for each ループ内で別の変換 (一般変換) を呼び出します。EDI 形式は複数のメッセージ・タイプで使用されるセグメント・セットに基づいていることが多いため、サブ変換は、特に、仮想ドキュメントに有効です。別の変換内で変換を再利用できるということは、コード変換を複製しなくても必要に応じて呼び出すことが可能なセグメント変換の再利用可能ライブラリを作成できることを意味します。
DTL ダイアグラムには subtransform アクションが表示されません。
subtransform アクションを追加するには:
-
[アクションの選択] ドロップダウン・リストから [subtransform] を選択します。
-
[アクション] タブで、以下の情報を指定します。
-
[変換クラス] — 使用するデータ変換クラスを指定します。これは、DTL 変換にすることも、カスタム変換にすることもできます。カスタム変換の詳細は、"Ensemble プロダクションの開発" の “カスタム変換の定義” を参照してください。該当するクラスを入力する必要があります。
-
[ソースプロパティ] — 変換するプロパティを指定します。これは、オブジェクト・プロパティにすることも、仮想ドキュメント・プロパティ・パスにすることもできます。通常は、変換に使用されるソース・メッセージのプロパティです。該当するソース・プロパティを入力する必要があります。
-
[ターゲットプロパティ] — 変換された値が書き込まれるプロパティを指定します。 これは、オブジェクト・プロパティにすることも、仮想ドキュメント・プロパティ・パスにすることもできます。通常は、変換に使用されるターゲット・メッセージのプロパティです。該当するターゲット・プロパティを入力する必要があります。
-
[予備のプロパティ] — 必要に応じて、サブ変換に渡される値を指定します。サブ変換は、この値に aux 変数としてアクセスします。
-
[無効] — 必要に応じて、サブ変換を無効にするように指定します。
-
[説明] — 必要に応じて、サブ変換の説明文を入力します。
Note:[作成] が new または copy に設定されている subtransform の場合は、既存のターゲット・オブジェクトが含まれている必要がありません。
-
例
この例には、2 つの DTL 変換クラスが表示されています。2 つ目の変換は最初の変換をサブ変換として呼び出します。
-
以下の変換は、HL7 バージョン 2.3.1 メッセージ用の仮想ドキュメント・セグメント IN1 内のフィールドに適用されます。IN1 は、患者入院メッセージの ADT シリーズに関する保険情報を提供します。次の 2 つの変換クラスの例からもわかるように、subtransform アクションを使用してこの 1 つを呼び出しています。
一般的に、この役割を果たす変換はサブ変換と呼ばれています。ただし、実際には、これは単なる一般変換であり、直接呼び出すこともできます。
Class Test.HL7.SegDTLa Extends Ens.DataTransformDTL { Parameter REPORTERRORS = 1; XData DTL [ XMLNamespace = "http://www.intersystems.com/dtl" ] { <transform targetClass='EnsLib.HL7.Segment' targetDocType='2.5:IN1' sourceClass='EnsLib.HL7.Segment' sourceDocType='2.3.1:IN1' create='copy' language='objectscript'> <assign property='target.{InsurancePlanID.Identifier}' value='source.{InsuranceCompanyID(1).ID}' action='set'/> <assign property='target.{InsuranceCompanyID}' value='""' action='remove'/> <assign property='target.{InsuranceCompanyName}' value='..ToLower(source.{InsuranceCompanyName})' action='set'/> </transform> } }
-
以下の変換は先行する変換を呼び出します。
Class Test.HL7.A01SegDTLb Extends Ens.DataTransformDTL { Parameter REPORTERRORS = 1; XData DTL [ XMLNamespace = "http://www.intersystems.com/dtl" ] { <transform targetClass='EnsLib.HL7.Message' targetDocType='2.5:ADT_A01' sourceClass='EnsLib.HL7.Message' sourceDocType='Demo.HL7.MsgRouter.Schema:ADT_A01' create='copy' language='objectscript'> <foreach property='source.{()}' key='i'> <assign property='target.{(i):1}' value='i' action='set'/> <if condition='target.GetSegmentAt((i)).Name="IN1"'> <true> <subtransform class='Test.HL7.SegDTLa' targetObj='target.{(i)}' sourceObj='source.GetSegmentAt(i)'/> </true> </if> </foreach> </transform> } }
Trace アクションの追加
trace アクションは、診断に役立つトレース・メッセージを生成します。[トレース・イベントを記録] 設定が親ビジネス・ホストに対して有効になっている場合は、このメッセージがイベント・ログに書き込まれます。[フォアグラウンド] 設定が親ビジネス・ホストに対して有効になっている場合は、トレース・メッセージがターミナル・ウィンドウにも出力されます。
DTL ダイアグラムには trace アクションが表示されません。
trace アクションを追加するには:
-
[アクションの選択] ドロップダウン・リストから [trace] を選択します。
-
[アクション] タブで、以下を指定します。
trace アクションは、ユーザ優先度を持つトレース・メッセージを生成します。結果は、ObjectScript 内の $$$TRACE マクロまたは Basic 内の WriteTrace("user") ユーティリティを使用した場合と同じです。
Code アクションの追加
code アクションを使用すれば、DTL データ変換内で 1 行または複数行のユーザ作成コードを実行できます。 このオプションを使用すれば、DTL 要素では表現しづらい特殊なタスクを実行できます。DTL ダイアグラムには code アクションが表示されません。
code アクションを追加するには:
-
[アクションの選択] ドロップダウン・リストから [code] を選択します。
-
[アクション] タブで、以下を指定します。
-
[コード] — 変換用に指定されたスクリプティング言語で 1 行または複数行のコードを指定します。このコード内の式に関するルールは、“構文ルール” を参照してください。
Ensemble は、自動的に、コードを CDATA ブロックで囲みます。これは、アポストロフィ (') やアンパサンド (&) などの特殊な XML 文字でエスケープする必要がないことを意味します。
後述する注意も参照してください。
-
[説明] — 任意で説明を指定します。
-
デバッグを容易にするためのカスタム・コードを作成するには、ターミナルで実行できるようにクラス・メソッドまたはルーチン内にコードを含めます。ターミナルでコードをデバッグします。その後で、DTL の code アクション内部からそのメソッドまたはルーチンを呼び出します。
DTL 内でカスタム・コードを使用する場合のガイドライン
データ変換の実行を中断して再開できるようにするには、code アクションを使用するときに以下のガイドラインに従う必要があります。
-
実行時間は短くします。カスタム・コードがデータ変換の一般処理を妨げないようにしてください。
-
システム・リソースを割り当てる (ロックの取得やデバイスのオープンなど) 場合は、必ず同じ code アクション内でそのリソースを解放してください。
-
code アクションでトランザクションを開始する場合は、考えられるすべてのシナリオにおいて同じアクションでトランザクションが終了することを確認します。そうしなければ、トランザクションを閉じることができなくなる可能性があります。これにより他の処理が阻止されたり、重大なダウンタイムを発生することがあります。
SQL アクションの追加
SQL アクションを使用すれば、DTL 変換内部から SQL SELECT 文を実行できます。DTL ダイアグラムには sql アクションが表示されません。
sql アクションを追加するには:
-
[アクションの選択] ドロップダウン・リストから [sql] を選択します。
-
[アクション] タブで、以下を指定します。
-
SQL — 有効な SQL SELECT 文を指定します。
Ensemble は、自動的に、SQL を CDATA ブロックで囲みます。これは、アポストロフィ (') やアンパサンド (&) などの特殊な XML 文字でエスケープする必要がないことを意味します。
後述する注意も参照してください。
-
[説明] — 任意で説明を指定します。
-
DTL 内で SQL を使用する場合のガイドライン
必ず、以下のガイドラインを使用してください。
-
次のように、必ず、SQL スキーマ名とテーブル名の両方を含むテーブルの完全修飾名を使用します。
MyApp.PatientTable
上記の例の MyApp は SQL スキーマ名、PatientTable はテーブル名です。
-
FROM 節内に列挙するテーブルは、ローカル Ensemble データベース内に保存されているか、SQL ゲートウェイを通して外部リレーショナル・データベースにリンクされている必要があります。
-
SQL クエリの INTO 節と WHERE 節から、ソースまたはターゲット・オブジェクトのプロパティを参照できます。これを実現するには、プロパティ名の前にコロン (:) を付けます。以下に例を示します。
SELECT Name INTO :target.Name FROM MainFrame.EmployeeRecord WHERE SSN = :source.SSN AND City = :source.Home.City
-
使用されるのは、クエリで返された最初の行のみです。WHERE 節では、必要な行を正確に指定してください。