|
<< Klicken Sie, um das Inhaltsverzeichnis anzuzeigen >> Navigation: Scripts > FELIX Scripts |
FELIX, die Schnittstellenkomponente von EMIL (siehe FELIX (HL7 Schnittstelle)), empfängt Nachrichten in den Formaten HL7, HCM oder xDT, übergibt sie an ein Script und schreibt die darin extrahierten Daten in die Patientenakte. Dieses Kapitel beschreibt die Grundfunktion eines FELIX-Scripts. Alle Funktionen mit Beispielen stehen in der FELIX Befehlsreferenz.
Die allgemeine Script-Sprache beschreibt das Kapitel Scripting-Grundlagen; dieses Kapitel setzt das Grundwissen voraus. Als Ausgangspunkt dient das Vorgabescript, das beim Anlegen eines HL7-Eingangskanals geladen wird; die Beispiele unten sind Ausschnitte daraus.
Eingehende Nachrichten (HL7, HCM, xDT) sind in Segmente zerlegt, die jeweils einen Datensatz tragen, z. B. MSH (Message Header), PID (Patient Identification), OBR (Observation Request), OBX (Observation Result). Das Script verarbeitet sie in einer Schleife: NextSegment liest jeweils das nächste Segment in eine Variable, per if prüfen Sie, um welches Segment es sich handelt. Innerhalb des Segments holt GetData die einzelnen Felder mit einer Positionsangabe im Format Feld-Subfeld-...-Komponente:
var
aSegment: String;
begin
while NextSegment(aSegment) do
begin
if aSegment = 'msh' then
begin
// ... Bearbeitung des MSH-Segments ...
end;
end;
end.
Mit debug geben Sie in der Testumgebung an beliebiger Stelle eine Zeile in der Konsole des Kanaleditors aus; writeln schreibt zusätzlich ins Protokoll und wirkt damit auch im Produktivbetrieb:
debug(aSegment);
writeln(aSegment);
Um Daten einer eventuell bereits vorhandenen EMIL-Patientenakte zuzuordnen, benötigen Sie die Patientennummer des sendenden Systems, die KIS-ID (PID), sowie Vorname, Nachname und Geburtsdatum. Diese lesen Sie mit GetData aus dem PID-Segment:
aPID := GetData('3-1-1-1');
aLastName := GetData('5-1-1-1');
aFirstname := GetData('5-1-2-1');
aBirthDate := StrToDateTime(GetData('7-1-1-1'), 'yyyymmdd');
Datumsangaben werden im Script als Fließkommazahlen (Double) verarbeitet und mit StrToDateTime anhand einer Formatangabe konvertiert. Mit diesen Daten wird die Akte gesucht oder angelegt:
if not FindOrCreateSubject(aPID, aFirstname, aLastName, aBirthDate) then exit;
FindOrCreateSubject sucht zunächst eine Akte, in der als KIS-ID exakt die angegebene PID eingetragen ist. Verglichen wird zeichengenau, nur Leerzeichen am Anfang und Ende werden ignoriert; führende Nullen werden nicht entfernt. Übermittelt ein System die PID mal mit, mal ohne führende Nullen, muss das Script das angleichen, sonst werden Nachrichten nicht zugeordnet oder es entstehen Dubletten. Auch nicht-numerische Identifikationen werden unterstützt.

•Wird eine Akte mit dieser KIS-ID gefunden und stimmen weder Vor- noch Nachname überein, prüft FELIX zusätzlich das Geburtsdatum. Passt auch dieses nicht, wird die Akte nicht verwendet: Die Funktion liefert false, die Nachricht wird aus dem Puffer gelöscht (Protokolleintrag „Dropping message for PID …"). Weil das nur bei unterschiedlichem Vor- und Nachnamen greift, führt z. B. eine Namensänderung durch Heirat nicht zur Ablehnung.
•Wird keine Akte mit dieser KIS-ID gefunden, sucht FELIX über Vorname, Nachname und Geburtsdatum in den Akten, die noch keine KIS-ID tragen. Eine Dublette über all diese Angaben ist extrem unwahrscheinlich; die Akte wird deshalb übernommen und mit der PID versehen.
•Wird auch so keine Akte gefunden, legt FELIX eine neue an.
Sollen keine Akten angelegt werden, z. B. bei Laborbefunden, verwenden Sie stattdessen FindSubject bzw. FindSubjectWithBirthdate. Liefern diese false, bleibt die Nachricht im Puffer und wird später erneut versucht. Was in welchem Fall mit der Nachricht geschieht, fasst die Tabelle Pufferverhalten zusammen.
Ist die Akte gefunden oder angelegt, können Sie die Stammdaten aus der Nachricht aktualisieren. Überschreiben Sie dabei nicht mit leeren Angaben, um manuell nachgetragene Daten zu schonen:
if aLastName <> '' then setSubjectInfo('lastname', aLastName);
...
if GetData('11-1-3-1') <> '' then setSubjectInfo('city', GetData('11-1-3-1'));
Befunddaten werden in ORU-Nachrichten in OBR-, OBX- und NTE-Segmenten übertragen. Auf ein OBR-Segment können mehrere OBX/NTE-Gruppen folgen, auf ein OBX-Ergebnisfeld mehrere NTE-Freitextelemente. Deshalb sammelt das Script die Daten und übergibt einen Befund erst mit SetOrLearnResult an EMIL, wenn ein neues OBR- oder OBX-Segment beginnt oder die Schleife endet. Das folgende Beispiel liest das Befunddatum aus dem OBR-Segment und sammelt die Befunddaten aus OBX (in der Regel ein Zahlenwert) und NTE (Text):
...
else if aSegment = 'obr' then
begin
// Offenen Befund aus dem vorigen OBX/NTE-Block schreiben
if (aResultValue <> '') then
SetOrLearnResult(aResultDate, aResultIdent, aResultValue, aResultRange,
aResultUnit, aResultTitle)
else if (aResultText <> '') then
SetOrLearnResult(aResultDate, aResultIdent, aResultText, aResultRange,
aResultUnit, aResultTitle);
aResultDate := StrToDateTime(GetData('7-1-1-1'), 'yyyymmddhhnn');
if aResultDate = 0 then aResultDate := StrToDateTime(GetData('14-1-1-1'), 'yyyymmddhhnn');
if aResultDate = 0 then aResultDate := StrToDateTime(GetData('22-1-1-1'), 'yyyymmddhhnn');
aResultValue := '';
aResultText := '';
end
else if (aSegment = 'obx') and (aResultDate > 0) then
begin
// Offenen Befund aus dem vorigen OBX/NTE-Block schreiben
if (aResultValue <> '') then
SetOrLearnResult(aResultDate, aResultIdent, aResultValue, aResultRange,
aResultUnit, aResultTitle)
else if (aResultText <> '') then
SetOrLearnResult(aResultDate, aResultIdent, aResultText, aResultRange,
aResultUnit, aResultTitle);
// Neuen Befund einsammeln
aResultIdent := GetData('3-1-1-1');
aResultValue := GetData('5-1-1-1');
aResultRange := GetData('7-1-1-1');
aResultUnit := GetData('6-1-1-1');
aResultTitle := GetData('3-1-2-1') + ' ' + GetData('3-1-3-1');
aResultText := '';
end
else if (aSegment = 'nte') and (aResultDate > 0) and (GetData('3-1-1-1') <> '') then
aResultText := aResultText + ' ' + GetData('3-1-1-1');
end; // Ende der Segmentschleife
// Nach der Schleife: den letzten, noch offenen Befund schreiben
if (aResultValue <> '') then
SetOrLearnResult(aResultDate, aResultIdent, aResultValue, aResultRange,
aResultUnit, aResultTitle)
else if (aResultText <> '') then
SetOrLearnResult(aResultDate, aResultIdent, aResultText, aResultRange,
aResultUnit, aResultTitle);
Das Vorgabescript setzt den Titel aus weiteren Komponenten von OBX-3 zusammen und behandelt OBX-Segmente vom Typ ED (eingebettete Dokumente und Bilder) gesondert mit ImportDocument, siehe FELIX Befehlsreferenz.
Ist die Verarbeitung fehlerfrei durchgelaufen, schreibt SaveAndClose am Ende des Scripts die Daten in die Datenbank und löscht die Nachricht aus dem Puffer:
SaveAndClose(debugging);
Mit dem Parameter debugging bleibt die Nachricht in der Script-Entwicklungsumgebung erhalten, sonst müsste die Testnachricht nach jedem Lauf neu eingelesen werden (siehe Script-Debugger). Was mit einer Nachricht geschieht, wenn das Script vorher per exit endet oder mit einem Fehler abbricht, steht im Pufferverhalten.
Die Beschreibung für HL7-Kanäle gilt analog für HCM und xDT. Die Positionsangaben sind dort andere und müssen durch die passenden ersetzt werden; Aufbau und Arbeitsweise sind identisch.