2016-09-29 6 views
1

HL7インターフェイスメッセージを解析するカスタム関数を書きました。これらは医療情報システム間で送信されるメッセージですが、基本的には長いテキスト文字列で、さまざまな文字で区切ってフィールドを指定し、Excelでセルにペーストします。私が作成した関数は、引数で指定されたフィールドを検索するために検索とカウントを行いました。カスタムHL7解析関数にオプション引数のロジックを追加する

免責事項:私はVBAを初めてお使いです。私は過去3〜4週間にわたりオンライン調査と試行錯誤を通じて自分自身を教えてきたので、私はVBAの専門家ではありません。私はそれを試したときにコードが複雑すぎてトラブルシューティングを行うことができないので、配列を使用したくないです。だから、私はコードが簡単に従うことが大丈夫ですが、最も速く/最も効率的であることとは対照的です。

とにかく、私が望むことをするにはかなりうまく動いていますが、OPTIONALの引数としてロジックを追加することに固執しています。

だから、これは私はそれが仕事をしたい方法です:唯一の3つの引数

結果、私はADT

NOTEをゲットADT^A08

の検索結果をしたい

=KWHL7(A1, "MSH", 8)

NOTE私は "HL7_SUBFIELD_DELIMITER"の次のインスタンスで停止するように言った"^"

=KWHL7(A1, "MSH", 8,1)

NOTEオプションの第四引数

結果、私が欲しいADT

=KWHL7(A1, "MSH", 8,2)

NOTEオプションの第四引数

結果、私はA08

をしたいです

内容のセルA1の "値":

<11>MSH|^~\&|OPS|384|RISIC|384|20160923093012||ADT^A08|Q1230569238T1410271390|P|2.3|||*PM_ALLERGY*|||8859/1<13> 
EVN||20160923<13> 
PID|1||000000808^^^SCH MRN^MRN^SC||ZZTEST^LEANN||20160706|F|||459 CORPORATION ST.^^BEAVER^PA^15009^USA||(724)775-7418^PRN|||S||000000008082^^^SCH Account Number^FIN NBR|||||||0<13> 
PV1|1|I|SCH Periop^^^^^^||||08888^Bullian^Leann~08888^Naylor^Daniel|||10|||||||08888^Nguyen-potter^Rose~00187^TEST^STCHRISRES^L^MD^^MD^^SCH Doc Number|1|1287593^^^TEMP FIN^VISITID||||||||||||||||||||384||A|||20160707131900<13> 
PV2|||PA^<13> 
OBX|1||Dosing Weight^WEIGHT||5|kg<13> 
OBX|2||Height^HEIGHT||25|cm<13> 
AL1|1|Drug|d00308^morphine^Multum Drug||66382015<13> 
ZAL|||16655315|16655315||Active|66382015^Anaphylaxis^673967||||20160923093008|^Naylor^Daniel|0<13> 
AL1|3|Drug|d00012^codeine^Multum Drug||103576018<13> 
ZAL|||16655323|16655307||Active|103576018^Diarrhea^673967||||20160923093008|^Naylor^Daniel|0<13> 
<28><13> 

私のVBAコード(すべてのコメントについて申し訳ありませんが、私はちょうど学んでいる!):

Public Function KWHL7(KW_Cell_With_HL7_Message As Variant, KW_HL7_Segment_Name As String, KW_HL7_Field_Number As Integer) 

        'KW_Cell_With_HL7_Message = KW_Cell_With_HL7_Message.Value 
        'KW_Cell_With_HL7_Message = ActiveCell.Value 
        'KW_HL7_Segment_Name = "PID" 
        'KW_HL7_Field_Number = 18 

     Const HL7_SEGMENT_DELIMITER = vbLf 'using "<13>" did not work due to carriage return 
     Const HL7_FIELD_DELIMITER = "|" ' Pipe means next field 
     Const HL7_SUBFIELD_DELIMITER = "^" 
      'Various carriage returns and line breaks: vbLf, vbCr, vbCrLf, vbNewLine, Chr(10), Chr(13) 

     KWSegmentStringToSearchFor = HL7_SEGMENT_DELIMITER & KW_HL7_Segment_Name 'Using the segment delimiter ("<13>" or "vbLf"/carriage return) before segment name implies that the segment/line STARTS with this text 

     KWSegmentCharacterPosition = InStr(1, KW_Cell_With_HL7_Message, KWSegmentStringToSearchFor) 
     '** FOR TESTING ** MsgBox ("Segment Character Position: " & KWSegmentCharacterPosition & ", 5 Characters starting there = " & Mid(KW_Cell_With_HL7_Message, KWSegmentCharacterPosition, 5)) 

     'Now we have the character position of the start of the proper SEGMENT/line 
     'Now we have to find the Proper Field in that segment 
     'So we'll use this position + the length of the end of the Segment Delimiter as the start 
     '***WARNING***: Still must add logic to make sure we stop if we encounter another Segment Delimiter 

     KWFieldCharacterPosition = KWSegmentCharacterPosition + Len(HL7_SEGMENT_DELIMITER) 'instead of starting at character 0, start at the beginning of the segment found previously 
     ' ** FOR TESTING ** MsgBox ("Length of Segment Delimiter = " & Len(HL7_SEGMENT_DELIMITER)) 
     ' ** FOR TESTING ** MsgBox ("Field Character Position: " & KWFieldCharacterPosition & ", 5 Characters starting there = " & Mid(KW_Cell_With_HL7_Message, KWFieldCharacterPosition, 5)) 

     For J = 1 To KW_HL7_Field_Number 
     KWFieldCharacterPosition = InStr(KWFieldCharacterPosition + 1, KW_Cell_With_HL7_Message, HL7_FIELD_DELIMITER) 
     If KWFieldCharacterPosition = 0 Then Exit For 
     Next 

     ' ** FOR TESTING ** MsgBox ("Field Character Position: " & KWFieldCharacterPosition & ", 5 Characters starting there = " & Mid(KW_Cell_With_HL7_Message, KWFieldCharacterPosition, 5)) 

     'Determine the number of characters to return after the start position 
     'Want to pull text UNTIL the next Segment Delimiter or Field Delimiter or Subfield Delimiter 

     'Find the position of the next Segment Delimiter or Field Delimiter or Subfield Delimiter 
     'Since the InStr function does not accept multiple substrings to search for, and does not allow OR statements inside... 
     Next_HL7_Segment_Delimiter = InStr(KWFieldCharacterPosition + 1, KW_Cell_With_HL7_Message, HL7_SEGMENT_DELIMITER) 
     Next_HL7_Field_Delimiter = InStr(KWFieldCharacterPosition + 1, KW_Cell_With_HL7_Message, HL7_FIELD_DELIMITER) 
     Next_HL7_Subfield_Delimiter = InStr(KWFieldCharacterPosition + 1, KW_Cell_With_HL7_Message, HL7_SUBFIELD_DELIMITER) 

     'Added logic to handle issue where the next delimiter was not found, making result 0, making it the lowest value in the next lines of code 
     If Next_HL7_Segment_Delimiter = 0 Then Next_HL7_Segment_Delimiter = 99999 
     If Next_HL7_Field_Delimiter = 0 Then Next_HL7_Field_Delimiter = 99999 
     If Next_HL7_Subfield_Delimiter = 0 Then Next_HL7_Subfield_Delimiter = 99999 

     'Set the Last Character Position to whichever Next Delimiter is the lowest/minimum number - Segment or Field or Subfield 
     KWLastCharacterPosition = WorksheetFunction.Min(Next_HL7_Segment_Delimiter, Next_HL7_Field_Delimiter, Next_HL7_Subfield_Delimiter) 
     ' ** FOR TESTING ** MsgBox ("Last Character Position: " & KWLastCharacterPosition & ", 5 Characters starting there = " & Mid(KW_Cell_With_HL7_Message, KWLastCharacterPosition, 5)) 

     'Determine the number of characters to return in the MID function by subtracting the first character position from the last character position 
     KWNumberOfCharactersToReturn = KWLastCharacterPosition - KWFieldCharacterPosition - 1 
     ' ** FOR TESTING ** MsgBox ("Number of characters to return: " & KWNumberOfCharactersToReturn) 

     KWResult = Mid(KW_Cell_With_HL7_Message, KWFieldCharacterPosition + 1, KWNumberOfCharactersToReturn) 
        'MsgBox ("Result: Segment " & KW_HL7_Segment_Name & ":" & KW_HL7_Field_Number & " is " & KWResult) 
        KWHL7 = KWResult 
End Function 

私が使用していた問題分割機能はすべてを配列に入れることでした。また、パイプ(|)文字を取り出す前に、FWSTでKWSegmentStringToSearchFor(つまり「MSH」または「PV1」)を検索する必要があったため、配列に別のネストされた配列を持たせる必要があり、

私は分割機能を放棄しました。私は最初に配列を使用する計画を立てていました。そこで、InStr()でKWSegmentStringToSearchFor(つまり「MSH」または「PV1」)を検索し、そこからパイプ(|)文字を数えて返す数値フィールドを決定します。

文字列の長さは可変ですが、特殊文字で区切られているので、次にMID関数で返す文字数を決定する必要があります。だから私は出発点として見つけたフィールドを使ってFROM THERE /の次の区切り文字を探し、それを私のフィールドの終わりと呼んでいます。

問題: ロジックは、3つの可能な区切り文字のいずれかをフィールドの最後と見なします。 これを取り除くと、コードは文字列の終わりがどこにあるのかわかりません。

オプションの第4引数が存在する場合(これは私がまだやっている方法がわからない)何らかのIF文を追加しても、THENは^を区切り文字として無視します。 (ADT^A08)。私が望むサブフィールド/コンポーネントだけを返しません。

ありがとうございます!

答えて

0

簡単な答えは、改行で分割することです、それは微調整が可能となる必要があるかもしれない、split(range("a1").value,"|")(intFieldNumber)
すなわち split("11>MSH|^~\&|OPS|384|RISIC|384|20160923093012||ADT^A08|Q1230569238T1410271390","|")(8)

はA08

^ ADT結果を提供します
関連する問題