Durchsuchbare Dokumentation aufrufen

Zurück zur Dokumentationsübersicht

Dokumente trainieren für Profis (JavaScript, regExp, OCR)

In dieser Dokumentation lernen Sie, wie Sie Dokumente mit docform trainieren. Der Fokus liegt hierbei auf das Trainieren für Profis. Folgende Bereiche lernen Sie kennen:

Voraussetzungen

Um ein Dokument zu trainieren, müssen folgende Voraussetzungen geschaffen sein:

Extraktor JavaScript im Ausleseelement

Sie können JavaScript in Ausleseelementen einbinden, um den ausgelesenen Wert von docform abzuändern.

Das nachfolgende Bild zeigt das im Feld "Parameter" ausgeführte JavaScript. In diesem Beispiel werden alle Buchstaben aus der ausgelesenen Rechnungsnummer entfernt, sodass nur die reine Zahl übrig bleibt. Aus "RE2017100003" wird "2017100003".

Wichtig

Die Variable value beinhaltet immer den extrahierten Text aus dem Dokument. Sie ändern somit bei der Extraktion JavaScript immer den value-Wert ab. Ihnen stehen dazu die Standard-Funktionen von JavaScript, sowie JavaScript-Modul "ac" zur Verfügung.

Beachten Sie zudem, dass der zurückgegebene Wert des Skriptes dem Typ des entsprechenden Metadatums entspricht. Wenn Sie den Trainingsmodus verlassen, versucht docform das Dokument abzulegen, und überprüft, ob alle Pflichtfelder gefüllt sind und ob der übergebene Wert dem Typ des Metadatums entspricht. Wird beispielsweise einem Datum eine Zeichenkette übergeben, wird der Wert entfernt. Handelt es sich um Pflichtfelder landet das Dokument im Audit, andernfalls wird es weitergereicht.

Die Überprüfung, ob der Wert zum Metadatentyp passt, findet nicht im Trainingsschritt statt! Sondern bei dem Versuch von docform, das Dokument an den folge Prozess zu übergeben.

Beachten Sie außerdem Folgendes:

Einstellbar unter:

MAIN_MODULE_MANAGEMENT/roi/control/scripting/security/MaxExecutionTime

Einstellbar unter:

MAIN_MODULE_MANAGEMENT/roi/control/scripting/security/[Blacklist/Whitelist]

Anwendungsbeispiele mit Skript


Liegt ein Buchstabe oder Symbol vor

in diesem Beispiel wird überprüft, ob ein Komma oder Punkt im value vorkommen. Wenn ja, wird true ausgegeben, wenn nein ein false:

/[\.,]/.test(value)

value.replace

Aufrufen der replace-Funktion:

value.replace(/[A-Z]/g, '')  // Erläuterung: (/Suchwert/g, 'Ersatzwert') 

Ohne das g würde nur das erste Suchergebnis ersetzt werden.


Leerzeichen

Die OCR-Engine hat in einem String überflüssige Leerzeichen erkannt. Mit diesem Skript entfernen Sie diese bzw. ersetzen Sie durch "Nichts":

value.replace(/ /g, '')


Punkte

Mit diesem Skript entfernen Sie alle Punkte:

value.replace(/[.]/g, '')


Alles außer Zahlen ersetzen

Mit diesem Skript werden alle Nicht-Zahlen mit "Nichts" ersetzt, also entfernt:

value.replace(/[^\d]+/g, '') // Erläuterung: [^\d]

Das ^ innerhalb der eckigen Klammer hat die Funktion einer Negierung. Der Ausdruck [^\d] bedeutet also "nicht Ziffer (Zahl)". Würde ^ außerhalb der eckigen Klammer stehen, bedeutet es "Anfang".


Alles außer Zahlen ersetzen und anhand RegEx extrahieren

value.replace(/[^\d]+/g, '').match(/30[0-9]{5}/)[0] // Erläuterung: .match(/30[0-9]{5}/)[0]

Nach dem Ersetzen wird der Teil, der auf die obige RegEx (insgesamt 7 Ziffern: 30 +  5 weitere Ziffern) passt, extrahiert.


Datum wird nicht sauber erkannt

Hinweis: Die Formatierung 'dd.MM.yyyy' oder 'yyyy-MM-dd' am Ende des Skripts gibt an, in welchem Format das Datum im String enthalten ist, damit es korrekt ausgelesen werden kann. Die Ausgabe eines Datums erfolgt standardisiert im Format dd.MM.yyyy.

In folgendem Beispiel hat der OCR anstatt dem 01.02.14 folgenden String erkannt:

0102. 14. 

Dies korrigieren Sie mit Hilfe von JavaScript und speichern es als Datum ab. Der folgende Ausdruck entfernt alle Zeichen außer Zahlen, nachfolgend wird es in ein Datum geparst:

transform(value).removeAll('[^0-9]+').date('ddMMyy') 


Datum aus String extrahieren

Beispiel: Aus dem String 8011370010/21.08.2018 soll das Datum extrahiert werden:

transform(value).extract(/\/(.+)*/).date('dd.MM.yyyy')

Ergebnis:

21.08.2018.

Beispiel: Der String ABCD BLA EIN FIRMEN NAMEN 5$$0A123$$2018-09-18$$1.2 enthält ein zu extrahierendes Datum:

transform(value).extract(/([^$]+)[$][$][^$]+$/).date('yyyy-MM-dd')

Ergebnis: 

18.09.2018


Dezimalzahl aus String extrahieren

Aus dem String 79,40 soll eine Dezimalzahl extrahiert werden. Wenn kein Wert vorhanden ist, soll '0' eingetragen werden:

transform(value || '0').float('de')

Ergebnis:

79,4

JavaScript in Konstanten

Neben der Nutzung von JavaScript innerhalb eines Ausleseelementes, können Sie ein Metadatum per Skript in einer Konstante berechnen. Diese beiden Skriptnutzungen unterscheiden sich untereinander, und somit auch deren Einsatz:

Sie nutzen JavaScript in Ausleseelementen, wenn Sie den ausgelesenen Wert (value) abändern möchten. Sie können auf keine anderen Variablen / Metadaten zugreifen!

Sie nutzen JavaScript in Konstanten, wenn Sie zur Berechnung des Metadatums Werte von mehreren Metadaten benötigen. Bespielsweise möchten Sie den Steuersatz ausrechnen, weil im Dokument nur der Nettto-, Brutto- und Mehrwertsteuerbetrag vorliegt. Sie greifen somit nicht auf value zu, das bei Konstanten ohnehin nicht existiert, sondern auf den internen Namen der Metadaten, die Sie im docform Training einsetzen.

Dabei müssen Sie die Reihenfolge im Auge halten! docform arbeiten den Elementenbaum von oben nach unten ab! Sie können daher in Ihrem Skript nur auf die zuvor ausgelesenen Metadaten zugreifen!

Allgemeines Beispiel zur Einrichtung

In dem vorliegenden Beispiel wird der Nettobetrag in einer Rechnung nicht angegeben. Wir benötigen dieses Pflichtfeld jedoch, und müssen es daher anhand des Brutto- und Mehrwertsteuerbetrages ausrechnen:

  1. Trainieren Sie das Dokument wie gewohnt, und stellen Sie sicher, dass der Brutto- und Mehrwertsteuerbetrag ausgelesen wird.
  2. Fügen Sie nach dem Brutto- und Mehrwertsteuerfeldern eine Konstante ein.

    Tipp: Setzen Sie die Konstante gerne in Abhängigkeit zum einem der Auslesefelder. Zum einen dient dies der visuellen Unterstützung, und zum anderen wird die Konstante nicht versucht zu errechnen, wenn der darüber liegende Wert "acmf_betragBrutto" nicht ausgelesen werden kann.
  3. Wählen Sie als Konstantennamen das Metadatum aus, das Sie nun berechnen wollen. In unserem Beispiel den Nettobetrag (acmf_betragNetto).
  4. Tragen Sie bei Wert Ihr JavaScript ein. Nutzen Sie dazu die internen Namen der Metadaten:
    js:
    acmf_betragBrutto - acmf_betragMwSt;

    Hinweis: Damit docform weiß, dass nun ein JavaScript und keine Zeichenkette folgt, müssen Sie mit js: beginnen.

    Ergebnis: Der Nettobetrag wird errechnet, und in der Inhalt-Spalte angezeigt. Hier 14,13 (Brutto) - 0,92 (MwSt) = 13,21.


Wichtiges

Beachten Sie, dass der zurückgegebene Wert des Skriptes dem Typ des entsprechenden Metadatums entspricht. Wenn Sie den Trainingsmodus verlassen, versucht docform das Dokument abzulegen, und überprüft, ob alle Pflichtfelder gefüllt sind und ob der übergebene Wert dem Typ des Metadatums entspricht. Wird beispielsweise einem Datum eine Zeichenkette übergeben, wird der Wert entfernt. Handelt es sich um Pflichtfelder landet das Dokument im Audit, andernfalls wird es weitergereicht.

Die Überprüfung, ob der Wert zum Metadatentyp passt, findet nicht im Trainingsschritt statt! Sondern bei dem Versuch von docform, das Dokument an den folge Prozess zu übergeben.

Nutzen Sie zur Transformation unser JavaScript-Modul "ac".

Beachten Sie außerdem Folgendes:

Einstellbar unter:

MAIN_MODULE_MANAGEMENT/roi/control/scripting/security/MaxExecutionTime

Einstellbar unter:

MAIN_MODULE_MANAGEMENT/roi/control/scripting/security/[Blacklist/Whitelist]

Besonderheit hidden_ Variable am Beispiel zur Berechnung der Positionsnummer erklärt

Je nach JavaScript benötigen Sie temporäre Informationen, die keinem Metadatum zugeordnet werden sollen. Stattdessen können Sie mit dem Präfix hidden_ temporäre Variablen (Konstanten, Auslesefelder) erzeugen, die nur während des Ausleseprozesses existieren und niemals als Metadatum auf das Objekt gesetzt werden.

Der Aufbau einer hidden-Variable ist:

hidden_<freie Namenswahl ohne Leerzeichen>

Um nun die Positionsnummer automatisiert ausrechnen zu lassen, zählen wir eine Nummer hoch:

  1. Legen Sie unter einem Identifikationsmerkmal eine Konstante aus.
  2. Geben Sie den Namen an:
    js: hidden_init
  3. Tragen Sie folgendes Script zur Initialisierung der JavaScript-Variable posNr bei Wert ein (Abbildung 1):
    js: hidden_init
  4. Tragen Sie in der Positionsschleife das gewünschte Metadatum zur Positionsnummer als Konstante an. In diesem Beispiel acmf_positionsNummer.
  5. Tragen Sie folgendes Script ein, dass bei jeder Position die Zahl um 1 hochzählt (Abbildung 2)::
    js: ++posNr
  6. Die Positionsnummer wird nun für jede Position ausgerechnet.

 

hidden_ Variable anlegen

 

Positionsnummer errechnen lassen 

 

docform/transform & docform/validate

Jetzt wird für jede Position die Positionsnummer hochgezählt.

Hinweis: Die Module undefined>docform/transform und "docform/validate" werden automatisch eingebunden und können direkt ohne die Einbindung von require() verwendet werden.

Beispielhafte Verwendung von transform, um innerhalb eines Trainings ein speziell formatiertes Datum ("20170214") auszulesen:

js: transform(value).date('yyyyMMdd');

Beispielhafte Verwendung von validate, um Netto-, Brutto- und MwSt-Betrag zu prüfen:

validate(acmf_betragNetto + acmf_betragMwSt).equals(acmf_betragBrutto);

Beispielhafte Verwendung von validate, um eine UStID zu prüfen:

validate(acmf_ustID).taxId();

Beispielhafte Verwendung von validate, um eine IBAN zu prüfen:

validate(acmf_iban).iban();

Beispiel - Zahlungsziel errechnen

Sie möchten aus Ihren Rechnungen ein Zahlungsziel auslesen? Doch der Ersteller der Rechnung hat anstatt eines Datums einen Text wie "Bezahlbar innerhalb von 90 Tagen" hinterlegt? Nutzen Sie JavaScript um diese Tagesanzahl auf Ihr Rechnungsdatum zu addieren, und somit Ihr Rechnungsziel als Datumsformat hinterlegen zu können.

Anbei liegen Ihnen zwei Umsetzungsbeispiele vor.

Beispiel 1 - Tage auf ein Datum rechnen - Date zurückgeben

Dieses Beispiel dient für Dokumententypen deren Zahlungsziel den Metadatentypen date aufweist.

 

Das genutzte JavaScript innerhalb einer Konstante lautet:

js:
//Anstatt Rechnungsdatum verwenden Sie Ihren internen Namen des Metadatums auf das Sie die Zahlen addieren möchten. ​​​​​
thedate = new Date(Rechnungsdatum);
//hidden_termsOfPayment ist das Zahlungsziel in Tagen
thedate.setDate(thedate.getDate() + hidden_termsOfPayment);
thedate;

Beispiel 2 - Tage auf ein Datum rechnen - String zurückgeben

Dieses Beispiel dient für Dokumententypen deren Zahlungsziel den Metadatentypen string aufweist.

Passen Sie dieses Skript für Ihren docform-Prozess an:

let rechnungsdatum = "12.12.2018";
//Anstatt rechnungsdatum verwenden Sie Ihren internen Namen des Metadatums auf das Sie die Zahlen addieren möchten.
let rechnungsdatumArray = rechnungsdatum.split('.');

let rechnungsdatumGedreht = rechnungsdatumArray[2] + "-" +  rechnungsdatumArray[1] + "-" + rechnungsdatumArray[0];

let zahlungsziel = 20;

let thedate = new Date(rechnungsdatumGedreht);
thedate.setDate(thedate.getDate() + zahlungsziel);

let d = thedate.getDate();
let m = thedate.getMonth() +1; //JavaScript-Besonderheit: Januar hat den Monat 0
let y = thedate.getFullYear();

let finalDate = d+"."+m+"."+y;

finalDate; //Sollte Ihr System dieses Wert nicht akzeptieren, stellen Sie sicher dass der Datentyp passt und Sie diesen als String oder Datum an docform zurückreichen!!! In diesem Beispiel reichen wir einen String zurück.

JavaScript in Positionsfeldern

Möchten Sie ein JavaScript einsetzen, um den Wert eines Positionsmetadatum auszurechnen, dann gehen Sie genauso vor, wie bei Kopfdaten. Sie erstellen keinen Loop, und versuchen somit die Berechnung der Positionen abzufangen. Die Schleife, die über alle Positionen läuft, organisiert docform selbst. Anbei ein Beispiel:

 

In dem folgenden Beispiel setzt sich der Gesamtpreis aus einem Preis und Zuschlägen zusammen. Die Zuschläge sind optional zu sehen, und können vorliegen. Sie verwenden dazu hidden_Variablen, um die entsprechenden Werte korrekt auszulesen:

js:
let ac = require('ac');
ac.round((hidden_preis1 || 0) + (hidden_preis2 || 0) + (hidden_preis3 || 0),2)

Achtung: Wird dir eine Fehlermeldung: DocFormError:ReferenceError: "hidden_XYZ" is not definied (#1) im Audit angezeigt? Dann konnte die angezeigte Variable für diese Position nicht ausgelesen werden.

 

Nehmen wir als Erklärung unser vorliegendes Beispiel: Der Silberzuschlag wird nicht bei jeder Position angegeben. Das bedeutet, die Variable existiert in der ein oder anderen Position, während andere den Wert nicht haben. Damit kann der Code ac.round((hidden_preis1 || 0) nicht umgehen. Damit er nicht in einen Fehler rennt, muss global. im JavaScript gesetzt werden:

 

js:
let ac = require('ac');
ac.round((global.hidden_preis1 || 0) + (global.hidden_preis2 || 0) + (global.hidden_preis3 || 0),2)

Damit stellen wir sicher, dass kein Error geworfen wird. Stattdessen wird null zurückgegeben, wenn die Variable für die entsprechende Position nicht vorliegt.

 

Dieser Kniff gilt natürlich nicht nur für Positionen, sondern immer sobald der ReferenceError erscheint.

 

Expressionen bei Suchelementen & Positionsanker

Sie können bei Suchelementen und dem Positionsanker nicht nur einen festen Wert hinterlegen, sondern zusätzlich mit Expressionen arbeiten. Expressionen sind reguläre Ausdrücke, die Ihnen die Chance geben nach variablen Ausdrücken auf einem Dokument zu suchen.

Ihnen steht es dabei frei eigene reguläre Ausdrücke zu hinterlegen, unsere Standards zu verwenden oder oft gebrauchte, eigene Expressionen als Standard zu hinterlegen.

Nutzung eigener Expressionen für ein Training

siehe Regular Expressions

Beschreibung der Standard- & Anlage eigener Expressionen

siehe Eigene Expressions definieren (docform)

Festgelegte Dokumentbereiche durch den OCR auslesen lassen

Sie kennen bereits den docform Prozess. Dabei werden Dokumente in einem aktiven Ordner abgelegt. Je nachdem, welche Einstellung dieser Aktiver Ordner hat, läuft das Dokument zuerst in den OCR,  oder, wenn Textinformationen bereits vorhanden sind, direkt nach docform.

Dort liest das System anhand Ihres festgelegten Trainings Werte aus. Diese werden als Metadaten an dem Dokument hinterlegt und durch einen Fileworkflow aus dem Aktiven Ordner in den finalen Ablageort verschoben.

Im Training selbst können wir die unterschiedlichsten Kniffe anwenden, um unsere Daten auslesen zu lassen. Hierbei lernt man niemals aus. Stattdessen wächst unser Wissen aufgrund der Komplexität und Qualität der Dokumente.

In dieser Dokumentation stellen wir Ihnen einen weitere Kniff vor: das Reprocessing von Dokumentenbereichen durch den OCR.

Achtung: Setzen Sie die Einstellung sparsam ein! Je öfter diese genutzt wird, desto mehr Dokumente werden an den OCR geschickt, was die Verarbeitung verzögert.

Beispielszenario

Sie nutzen den Reprocessing-Prozess, wenn Ihr Dokument prinzipiell sich wunderbar auslesen lässt, bis auf ganz wenige auszulesende Werte,

In dem folgenden Screenshot sehen Sie, dass das Rechnungsdatum schwer auszulesen ist, während die anderen Werte gut aussehen.

 

Und genau diesen Wert/diesen Datumsbereich lassen wir für diese Rechnung durch den OCR laufen.

Denn folgendes Prinzip greift nun: der OCR kann besser kleine Textbereiche auslesen und sich dahingehend orientieren, als bei ganzen Seiten.

Wieso? Nehmen Sie einfach mal an Ihr Handy in die Hand und machen Sie zwei Fotos von einem Blatt Papier. Dabei zoomen Sie einmal auf einen kleinen Bereich, und nehmen für das zweite Bild die komplette Seite auf. Im Vergleich wird deutlich, dass die komplette Seite nicht so perfekt aussieht, wie der kleine Dokumentausschnitt. Warum ist das so? Die Kamera setzt automatisch bestimmte Einstellungen fest, um einen Bildbereich zu schärfen und zu verstehen. Dabei greift diese eine Einstellung nicht für alle Bereiche des Dokumentes. Die eine Dokumenthälfte ist z. B. etwas dunkler belichtet als die andere. Auch Papierknicke, Krümel, oder eine hellere / ausgebleichtere Schriftfarbe können Gründe dafür sein, dass unser Dokument nicht perfekt abfotografiert werden kann. Da die gesetzten Einstellungen der Kamera für diese "Sonderfälle" nicht perfekt sind.

Ähnlich ist es für den OCR. Dieser versucht den Text des gesamten Dokumentes zu identifizieren und wählt hierzu allgemeine Werte aus. Aus diesem Grund besteht die Möglichkeit nur bestimmte Textausschnitte an den OCR weiterzureichen.

Umsetzung im Training

Um einen Dokumentausschnitt an den OCR zu senden, markieren Sie ein Textausleseelement. Erkennbar an dem Disketten-/Speichersymbol. In den dort gesetzten Eigenschaften, stellen Sie folgende Option unter Inhalt ein:

Verarbeiten als: OCR
(Im Standard steht hier "Bitte wählen")
 

Nun wird dieser Auslesebereich an die OCR-Engine übergeben. Diese führt den Erkennungsprozess aus und gibt das Ergebnis wieder an agorum core zurück, wo es bearbeitet wird.

Verarbeiten als Barcode oder Handschrift

Auch die beiden Einstellungen, Barcode oder Handschrift, führen zu demselben Resultat. Der ausgewählte Textbereich wird zurück an den OCR versendet. Allerdings mit bedacht einen Barcode oder einen handschriftlichen Text besser zu erkennen.

Handelt es sich, wie in unserem Beispiel, um einen normalen digital erstellen Text, nutzen Sie die Einstellung OCR.

 

Durch die Option "Bitte wählen" stellen Sie den Standard wieder ein. Das bedeutet, der ausgewählte Text des Speicherelements wird nicht zurück an den OCR weitergeleitet.

Perfektionierung durch den OCR Tuner

Stellen Sie fest, dass Ihr Wert dennoch nicht vom OCR gegriffen werden kann, bietet Ihnen der OCR -Tuner eine gute Möglichkeit, dieses Problem zu lösen. Durch diesen können Sie passende OCR Einstellungen finden, die diesen Textbereich erkenntlich machen.

Näheres erfahren Sie in folgender Dokumentation: agorum core ocr tuner Dokumentation

Achtung: Einbrüche in der Performance durch Setzen der beschriebenen OCR-Einstellung möglich. Die Einstellung geht zulasten der Performance, wodurch das System verlangsamt werden kann. Setzen Sie die Einstellung keinesfalls provisorisch für viele oder gar alle Elemente in Ihrem Training. Nutzen Sie diese Option nur in Ausnahmefällen!

Wenn nicht nur ein Element, sondern mehrere betroffen sind, sollten Sie grundsätzlich prüfen, ob Sie die betroffenen Dokumente in einen extra Aktiven Ordner ablegen, der mit vorgenommenen OCR-Einstellungen das komplette Dokument überarbeitet: agorum core ocr tuner Dokumentation