Zum Inhalt springen

File

Der File-Trigger überwacht einen Ordner, den Pool. Jede Datei, die dort ankommt und zum Filter passt, startet einen Lauf. Typische Quellen sind ein ERP, das Belege als PDF ablegt, ein Scanner oder der PDF-Drucker von RUNOS.

Bevor der Lauf startet, liest der Trigger den Text der Datei. Enthält er Skriptblöcke (#RUNOS … #RUNOS), übernimmt RUNOS daraus Werte für diesen Lauf, zum Beispiel Rechnungsnummer und Empfänger aus dem ERP-Druck.

Ablauf je Datei:

  1. Bei jeder Prüfung (CronExpression) listet der Trigger die passenden Dateien im Pool auf.
  2. Er wartet kurz, bis eine Datei vollständig geschrieben und nicht leer ist. Ist sie nach etwa zwei Sekunden noch leer oder gesperrt, kommt sie bei der nächsten Prüfung dran.
  3. Die Datei wird in einen eigenen Jobordner verschoben: <Pool>\Spooler\<ID>\<Dateiname>. Damit gehört sie diesem Lauf, und keine Datei wird zweimal verarbeitet.
  4. Falls NewName gesetzt ist, wird sie umbenannt.
  5. Bei GetFileContent liest RUNOS den Text und wertet die Skriptblöcke aus.
  6. Der Lauf startet.
Ergebnis des Laufs Was mit der Datei passiert
erfolgreich, DeleteAfter: false bleibt im Jobordner im Spooler (Archiv)
erfolgreich, DeleteAfter: true wird gelöscht, samt Jobordner
fehlgeschlagen wird nach <Pool>\Spooler\Failed\<ID>\ verschoben. Nach dem Beheben der Ursache legen Sie sie wieder in den Pool.

Hat eine Aktion die Datei schon woanders hin verschoben, bleibt sie dort. Mehrere laufende Workflows können denselben Pool überwachen; welcher Workflow eine Datei bekommt, bestimmen dann ihre Skriptblöcke, siehe Gemeinsamer Pool. Zwei Workflows mit demselben Namen können einen Pool nicht teilen: Der zweite startet nicht, und RUNOS nennt den Workflow, der den Ordner belegt.

"Trigger": {
"Type": "File",
"Name": "Eingang",
"Parameters": {
"Pool": "C:\\RUNOS\\Rechnungen",
"Filter": "*.pdf",
"CronExpression": "0/15 * * * * ?",
"ProcessMode": "Single",
"ConcurrentJobs": 5,
"DeleteAfter": false,
"GetFileContent": true
}
}
Parameter Standard Bedeutung
Pool – Der überwachte Ordner. Wird angelegt, falls er fehlt. Platzhalter wie %userdocuments% sind erlaubt.
Filter *.* Dateimuster, z. B. *.pdf oder RE_*.txt
CronExpression 0/15 * * * * ? Wie oft der Ordner geprüft wird, siehe Cron-Ausdrücke. Standard: alle 15 Sekunden. Speichert der PDF-Drucker eine Datei in den Pool, prüft der Trigger zusätzlich sofort.
ProcessMode Single Single: ein Lauf je Datei. Multi: ein Lauf für alle Dateien einer Prüfung.
ConcurrentJobs 5 Im Modus Single: wie viele Dateien gleichzeitig verarbeitet werden
DeleteAfter false true: Nach einem erfolgreichen Lauf wird der Jobordner der Datei gelöscht, mit allem, was Aktionen dort abgelegt haben (z. B. die Teile von Split im PDFEditor). Gilt für den ganzen Lauf, nicht für eine einzelne Aktion.
NewName – Neuer Dateiname im Spooler, z. B. Rechnung_%yyyy%-%MM%-%dd%. Ohne Endung bleibt die alte Endung.
RepeatCount 0 Nach so vielen Prüfungen (nach CronExpression) stoppt der Trigger. 0 = unbegrenzt.
GetFileContent true Text der Datei lesen und als {{FileContent}} bereitstellen. Nötig für Skriptblöcke.
RemoveScriptFromFile false Skriptblöcke nach dem Lesen aus der Datei entfernen, bei TXT, JSON, XML und PDF. Im PDF wird der Text des Blocks gelöscht, nicht überdeckt: Er ist weder sichtbar noch kopierbar, der Rest der Seite bleibt, wo er war, auch Text, der unter oder neben dem Skript steht (z. B. ein kleines Skript über der Rechnungsposition). Druckt das ERP Zeichen zwischen die Blöcke, z. B. `
ScriptStart, ScriptEnd aus den Einstellungen Eigene Markierungen für Skriptblöcke dieses Triggers

Single ist fast immer die richtige Wahl: Jede Datei hat ihren eigenen Lauf mit eigenen Daten. Bei Multi enthält {{Trigger.Response.Results}} alle Dateien einer Prüfung, und {{FilePath}} zeigt auf die zuletzt gelesene.

Dateityp Wie
.txt, .json, .xml als Text
.pdf Text aller Seiten wird extrahiert. Gescannte PDFs ohne Textebene liefern keinen Text.
andere kein Text; der Workflow läuft trotzdem, ohne FileContent und Skriptblöcke
Platzhalter Inhalt
{{FilePath}} voller Pfad der Datei im Spooler
{{FileName}} Dateiname (nach NewName)
{{FileContent}} gelesener Text, bei PDF der extrahierte Text
{{Trigger.Response.Results}} Bericht je Datei, siehe unten
{{Trigger.Meta.SpoolerFolder}} Pfad des Spooler-Ordners
{
"FilePath": "C:\\RUNOS\\Rechnungen\\Spooler\\3f2a…\\RE-2026-0001.pdf",
"FileName": "RE-2026-0001.pdf",
"OriginalName": "RE-2026-0001.pdf",
"FileSize": 48211,
"Content": { "Loaded": true, "Chars": 1834, "Preview": "Rechnung Nr. …" },
"Scripts": { "Found": 1, "Parsed": 1, "Ignored": 0, "Invalid": 0 }
}

Mit RemoveScriptFromFile steht unter Scripts zusätzlich RemovedFromFile (true, wenn die Blöcke entfernt wurden) und bei PDFs RemovedBlocks (Anzahl der entfernten Blöcke).

Ein Skriptblock ist ein kurzer Text in der Datei, der diesen einen Lauf ändert: Er setzt Werte in InitialData, ändert Parameter von Aktionen oder fügt Aktionen hinzu. Das gespeicherte Workflow-JSON bleibt unverändert. So kann ein ERP, das nur drucken oder Textdateien schreiben kann, RUNOS sagen, an wen eine Rechnung geht und welche Daten in die XRechnung gehören.

#RUNOS InitialData.Invoice.BT1=RE-2026-0001 #RUNOS
#RUNOS SendMail.To=buchhaltung@kunde.de #RUNOS

Ein Block steht zwischen Start- und Endmarkierung, standardmäßig beide #RUNOS (änderbar unter Einstellungen → Skriptblöcke oder mit ScriptStart / ScriptEnd). Beginnt der Inhalt mit { und endet mit }, ist er JSON; beginnt er mit Pfad=, ist er die Kurzform; alles andere wird ignoriert.

Jeder Block enthält genau eine Anweisung Pfad=Wert. Der erste Teil des Pfads entscheidet das Ziel:

Pfad beginnt mit Ziel Beispiel
InitialData. ein Wert in InitialData dieses Laufs InitialData.Invoice.BT1=4711
Name einer Aktion ein Parameter dieser Aktion (.Parameters darf fehlen) SendMail.To=a@b.de
newAction. eine neue Aktion, siehe unten newAction.Notify=SMTP
alles andere ein globaler Wert, lesbar als {{Name}} Kunde=ACME → {{Kunde}}
  • Der Wert reicht vom ersten = bis zur Endmarkierung, auch über mehrere Zeilen (z. B. ein Mailtext).
  • Werte sind Text (Menge=5 → "5"). Als JSON geschriebene Werte werden als JSON gelesen: Tags=["a","b"] ist eine Liste.
  • "…" behält führende und folgende Leerzeichen. Text zwischen den Textmarkierungen (Standard ***) wird genau so übernommen.
  • {{…}}-Platzhalter bleiben Text und werden später beim Ausführen der Aktion aufgelöst.
#RUNOS {"InitialData":{"Invoice":{"BT1":"RE-2026-0001","BT2":"2026-10-08"}}} #RUNOS
Schlüssel Wirkung
InitialData wird über die InitialData des Laufs gelegt
Actions Parameter für Aktionen, {"SendMail":{"To":"a@b.de"}}, oder Aktionsblöcke {"Name":…, "Type":…, "Parameters":{…}}
alles andere globale Werte

Schreibt ein Programm einen langen JSON-Block in ein PDF und bricht dabei die Zeile mitten in einem Wert um, fügt RUNOS den Wert wieder zusammen.

  • Ein vorhandener Schlüssel bekommt den neuen Wert, ein neuer wird hinzugefügt, alles andere bleibt. Objekte werden Schlüssel für Schlüssel zusammengeführt, Listen werden komplett ersetzt.
  • Mehrere Blöcke werden in ihrer Reihenfolge angewendet; der spätere gewinnt.
  • Ein Zahlensegment im Pfad ist eine Zeile einer Liste, gezählt ab 1: InitialData.Positionen.2.Artikel=Mutter. Es darf keine Nummer fehlen.
  • Für die wiederholbaren Gruppen der XRechnung (BG-25 Positionen, BG-23, BG-17 …) geht es ohne Nummern: Ein Feld, das die aktuelle Zeile schon hat, beginnt die nächste. Siehe XRechnung-Beispiel.
#RUNOS newAction.Hinweis=SMTP #RUNOS
#RUNOS Hinweis.To=chef@example.de #RUNOS
#RUNOS Hinweis.Subject=Neue Datei {{FileName}} #RUNOS

Welche Blöcke eine Datei für einen bestimmten Workflow braucht, zeigt der Workflow-Editor unter Skript (neben Visuell / JSON):

  1. Links haken Sie an, was die Datei liefern soll: Werte aus InitialData und Parameter der Aktionen, auch der Aktionen in If, Loop und Parallel. Ein Haken an einer Gruppe (z. B. InitialData oder einer Aktion) setzt alles darunter. Listen wie Rechnungszeilen werden als Ganzes gewählt, weil ein Block eine Liste immer vollständig ersetzt. Beim ersten Öffnen ist InitialData angehakt.
  2. Rechts steht das fertige Skript mit den aktuellen Werten des Workflows als Beispiel, in der Kurzform (ein Block pro Wert, Listen Zeile für Zeile) oder als ein JSON-Block. Die Markierungen sind die dieses Triggers bzw. aus den Einstellungen.
  3. Kopieren legt es in die Zwischenablage. Im ERP oder der Vorlage, die die Datei erzeugt, ersetzen Sie die Beispielwerte durch die echten.

Das Skript wird aus dem JSON im Editor erzeugt, auch ungespeichert, und kann dort nicht bearbeitet werden. Ausgeschaltete Aktionen, Aktionen ohne Namen und OnError-Aktionen fehlen, weil der Trigger sie nicht findet. Auswahl und Format merkt sich RUNOS je Workflow. Hat der Workflow keinen File-Trigger, weist die Ansicht darauf hin. In der Kurzform sind alle Werte Text (5 kommt als "5" an); wo der Typ zählt, wählen Sie JSON.

Überwacht nur ein laufender Workflow den Pool, schreiben Sie die Blöcke wie oben, ohne Workflow-Namen.

Überwachen mehrere laufende Workflows denselben Pool, beginnt jeder Block mit dem Namen des Workflows, für den er gilt: Workflow.Aktion.Parameter=Wert. Jede Datei wird nur einmal aus dem Pool genommen und mit ihren Blöcken gelesen. Nur die Workflows, die die Datei nennt, laufen, jeder mit seiner eigenen Kopie in einem eigenen Jobordner und nur mit seinen eigenen Blöcken (ohne den Namen davor). Workflows, die die Datei nicht nennt, starten nicht.

#RUNOS Rechnung.InitialData.Nr=4711 #RUNOS
#RUNOS Rechnung.SendMail.To=kunde@example.com #RUNOS
#RUNOS Archiv.InitialData.Ordner=2026 #RUNOS

Hier laufen Rechnung und Archiv, ein dritter Workflow am selben Pool nicht. In der JSON-Form ist der Workflow-Name der äußere Schlüssel:

#RUNOS { "Rechnung": { "InitialData": { "Nr": "4711" } }, "Archiv": { "InitialData": { "Ordner": "2026" } } } #RUNOS
  • Groß-/Kleinschreibung zählt nicht. Leerzeichen und andere Zeichen außer Buchstaben, Ziffern, _ und - lassen Sie weg: Der Workflow Rechnung senden heißt im Block Rechnungsenden. Die Kurzform braucht einen Namen, der mit einem Buchstaben beginnt; sonst nehmen Sie die JSON-Form.
  • Nennt eine Datei keinen der laufenden Workflows des Pools (auch: Blöcke ohne Workflow-Namen), wird sie abgelehnt und landet im Failed-Ordner, mit einer Meldung, welche Workflows den Pool teilen.
  • Ein Name, den kein laufender Workflow des Pools trägt (z. B. ein Tippfehler oder ein gestoppter Workflow), wird ignoriert; das Protokoll meldet ihn als ScriptForUnknownWorkflow.
  • Jeder Workflow verarbeitet seine Kopie mit seinen eigenen Einstellungen (NewName, DeleteAfter, RemoveScriptFromFile, ProcessMode …). Welche Workflows eine Datei bekommen haben, steht im Protokoll unter FileShared.
  • Ob ein Pool geteilt ist, entscheidet sich beim Eintreffen der Datei: Wird ein Workflow gestoppt und bleibt nur einer übrig, gilt wieder die Form ohne Namen.

Ein Block, der nicht gelesen werden kann (ungültiges JSON, Pfad=Wert nicht erkennbar, fehlende Zeilennummer, unbekannter Aktionstyp …), lehnt die Datei ab: Sie landet im Failed-Ordner, und Sie erhalten eine Meldung mit der Nummer des Blocks und dem Grund. Dasselbe gilt für eine Datei, die erkennbar Skriptdaten enthält, aber keine Markierungen. Was RUNOS gelesen hat, steht im Protokoll unter ScriptShorthandParsed bzw. ScriptJsonParsed.

Im Diagramm des Workflow-Editors hat der Trigger ein Formular:

  • Ordner: Überwachter Ordner (Pool) und Dateifilter (Filter).
  • Prüfen: Ordner prüfen (CronExpression) und Stoppen nach (RepeatCount).
  • Verarbeitung: Läufe – ein Lauf je Datei oder für alle Dateien einer Prüfung (ProcessMode); Dateien gleichzeitig (ConcurrentJobs, nur bei einem Lauf je Datei); Datei umbenennen in (NewName); Datei nach erfolgreichem Lauf löschen (DeleteAfter).
  • Inhalt und Skriptblöcke: Text der Datei lesen (GetFileContent), Skriptblöcke aus der Datei entfernen (RemoveScriptFromFile), Startmarkierung und Endmarkierung (ScriptStart, ScriptEnd).

Der Zeitplan wird ausgewählt statt getippt: Alle … Sekunden, Alle … Minuten, Jede Stunde (zur Minute …), Jeden Tag, Montag bis Freitag, An bestimmten Wochentagen (Tage anklicken) oder Einmal im Monat (Tag 1–31 oder letzter Tag), jeweils mit Uhrzeit. Darunter steht der erzeugte Cron-Ausdruck. Für alles andere wählen Sie Eigener Zeitplan (Cron-Ausdruck) und tippen den Ausdruck selbst; ein Ausdruck, den die Auswahl nicht abbildet (z. B. 0 0 8-17 ? * MON-FRI), erscheint automatisch so. Parameter, die das Formular nicht kennt, stehen unter Weitere Parameter.

Jedes PDF, das im Ordner C:\RUNOS\Eingang landet, wird nach einem erfolgreichen Lauf gelöscht. Das Programm, das die PDFs erzeugt, schreibt den Empfänger als Skriptblock hinein:

#RUNOS Senden.To=kunde@example.com #RUNOS
{
"Name": "Eingang mailen",
"Autostart": true,
"Trigger": {
"Type": "File",
"Name": "Eingang",
"Parameters": {
"Pool": "C:\\RUNOS\\Eingang",
"Filter": "*.pdf",
"CronExpression": "0/10 * * * * ?",
"NewName": "Dokument_%yyyy%-%MM%-%dd%_%HH%%mm%%ss%",
"DeleteAfter": true
}
},
"Actions": [
{
"Type": "MAPI",
"Name": "Senden",
"Parameters": {
"Client": "Outlook",
"Mode": "Display",
"To": "",
"Subject": "Ihr Dokument {{FileName}}",
"Attachments": "{{FilePath}}"
}
}
]
}