<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>http://bafbal.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Michaelebner</id>
	<title>bafbal.de - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="http://bafbal.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Michaelebner"/>
	<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Spezial:Beitr%C3%A4ge/Michaelebner"/>
	<updated>2026-05-17T08:54:03Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.34.2</generator>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22564</id>
		<title>Modul VAR neu</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22564"/>
		<updated>2026-05-06T09:12:29Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #file_op */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das Modul Var sammelt neben den Variablen auch die grundlegenden Prozeduren und Funktionen.&lt;br /&gt;
&lt;br /&gt;
=Variable=&lt;br /&gt;
&lt;br /&gt;
==#var_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#setvar setzt den Wert einer Variablen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis: Variable sind global, auf sie kann auch in Sub-Kommandos zugegriffen werden. Values sind dagegen lokal.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*rf (replace functions) - Wenn Y, dann werden nach der Zuweisung auf die Variable nochmals die Funktionen ersetzt. Wird zum Beispiel benötigt, wenn Code mit Funktionen mittels $DATA() aus der Datenbank geladen wird; Funktionen werden ersetzt, default N; siehe Beispiel&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_set   n=test2  z=$GUID()&lt;br /&gt;
 #var_set   n=edt    z=$EDT(edt1)   ie=42&lt;br /&gt;
 #var_set   n=_page_kunde_adressänderung_ro   z=N   zn=Y   zr=Y   r=kundenservice&lt;br /&gt;
&lt;br /&gt;
Zum Parameter rf: $NOW() in die Zwischenablage kopieren und dann ausführen:&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=N&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=Y&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_setempty==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_setempty setzt den Wert einer Variablen, sofern sie (noch) leer ist.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Besteht der Variableninhalt aus Leerzeichen, gilt die Variable auch als leer.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_setempty   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_setempty   n=test2  z=$GUID()&lt;br /&gt;
 #var_setempty   n=edt    z=$EDT(edt1)    ie=42&lt;br /&gt;
&lt;br /&gt;
==#var_add==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_add fügt einer Variablen einen Wert hinzu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. &lt;br /&gt;
* y -Typ der Operation; default ''text''&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** month - Es wird dem Datum eine Anzahl von Monaten hinzugefügt&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
*z - Wert, welcher der Variablen hinzugefügt wird, Funktionen werden ersetzt, default ist ein leerer String oder eine 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$NOW()&lt;br /&gt;
 #var_add   n=test   z=1   y=datetime&lt;br /&gt;
 #cout   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_log==&lt;br /&gt;
&lt;br /&gt;
Schreibt den Inhalt aller Variablen in das Debug-Log.&lt;br /&gt;
&lt;br /&gt;
Wird nur zur Fehlersuche verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_log&lt;br /&gt;
&lt;br /&gt;
==$VAR()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $VAR() wird auf den Inhalt der Variable zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
# optional: Der Wert wird vor oder nach der Rückgabe als Funktionsergebnis verändert; nur für ganzzahlige Werte&lt;br /&gt;
## ib (&amp;quot;increment before&amp;quot;) - Der Wert wird vor der Rückgabe um eins erhöht&lt;br /&gt;
## db (&amp;quot;decrement before&amp;quot;) - Der Wert wird vor der Rückgabe um eins verringert&lt;br /&gt;
## ia (&amp;quot;increment after&amp;quot;) - Der Wert wird nach der Rückgabe um eins erhöht&lt;br /&gt;
## da (&amp;quot;decrement after&amp;quot;) - Der Wert wird nach der Rückgabe um eins verringert&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #message  c=$VAR(test)&lt;br /&gt;
 #var_set  n=neuer_wert   z=$VAR(wert)   ie=$VAR(alternativwert)&lt;br /&gt;
 #execsql   k_lfdnr=$VAR(lfdnr,ib)&lt;br /&gt;
&lt;br /&gt;
=Kommandos=&lt;br /&gt;
&lt;br /&gt;
(Primär- und Sub) Kommandos sind üblicherweise benannt und werden im Code-Dialog eingegeben.&lt;br /&gt;
&lt;br /&gt;
Es besteht jedoch auch die Möglichkeit, lokale Kommandos innerhalb eines anderen Kommandos zu definieren. Diese Kommandos haben statt eines Kommando-Namens dann dann eine Kommando-Nummer.&lt;br /&gt;
&lt;br /&gt;
Lokale Kommandos werden üblicherweise für folgende Zwecke verwendet:&lt;br /&gt;
&lt;br /&gt;
* Bei der Verwendung von xlive werden bisweilen Prozeduren eingesetzt, die ihrerseits ein Kommando aufrufen (z.B. #sql_open). Wenn dieses Kommando nichts bereits existiert, kann es nur als lokales Kommando erstellt werden.&lt;br /&gt;
&lt;br /&gt;
* Wenn das auszuführende Kommando auf derselben Seite stehen soll wie die aufrufende Prozedur.&lt;br /&gt;
&lt;br /&gt;
Siehe als Beispiel: [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd fügt dem Kommando eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd fügt dem ersten Kommando eine Zeile hinzu, #cmd2 fügt dem zweiten Kommando eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd hat keine benannten Parameter. Die ganze Zeile nach dem #cmd und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd3 #text $DATA(n,login);$DATA(n,shortname);$DATA(n,firstname);$DATA(n,lastname);$DATA(n,userid);&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clear löscht ein Kommando&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd_clear löscht das erste Kommando, #cmd_clear2 löscht das zweite Kommando, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #cmd_clear Zeichen, so werden die dem gerade gelöschten Kommando hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear3&lt;br /&gt;
 #cmd_clear #grd_add   i=grid   f_logtext=&amp;quot;Kunde angerufen und nicht erreicht.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#cmd_clearall==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clearall löscht alle Kommandos&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clearall&lt;br /&gt;
&lt;br /&gt;
=CSV=&lt;br /&gt;
&lt;br /&gt;
Die CSV-Routinen werden verwendet, um CSV-Dateien einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==#csv_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_open öffnet eine CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_open öffnet die erste CSV-Datei, #csv_open2 öffnet die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*ber - wenn Y, werden die Zeilenumbrüche innerhalb von Feldern durch Leerzeichen ersetzt. Die Felder müssen dabei in doppelten Anführungszeichen eingeschlossen sein.&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - (&amp;quot;Filename&amp;quot;) Dateiname der CSV-Datei&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich. Muss bereits hier gesetzt werden, wenn mit $CSV_LINE auf den Header zugegriffen werden soll, bevor #csv_line ausgeführt wird.&lt;br /&gt;
*txt (&amp;quot;Text&amp;quot;) - alternativ zum Dateinamen fn die Nummer eines Textes, der als CSV-Datei verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open  fn=c:\temp\text.csv&lt;br /&gt;
&lt;br /&gt;
==#csv_line==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_line geht zeilenweise durch die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_line geht durch die erste CSV-Datei, #csv_line2 geht durch die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;database&amp;quot;) - Die Datenbank, für welche die Transaktion ausgeführt wird, wenn ert=Y gesetzt ist. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
*er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
*ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt, Funktionen werden ersetzt&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich.&lt;br /&gt;
*m (&amp;quot;maximum&amp;quot;) - Maximale Anzahl der Zeilen, die verarbeitet wird. Wird gerne bei der Entwicklung verwendet, um die Bearbeitungsgeschwindigkeit zu erhöhen. Funktionen werden ersetzt&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird im Falle einer Exception die Bearbeitung nicht abgebrochen, sondern lediglich Warnungen geloggt; Default N, Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Semikolon, Funktionen werden ersetzt&lt;br /&gt;
*trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_line  er=test_csv_line   hhr=Y   m=3&lt;br /&gt;
&lt;br /&gt;
==#csv_check==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_check prüft die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnt (&amp;quot;count&amp;quot;) - Anzahl der Header-Einträge, die geprüft wird; Funktionen werden ersetzt&lt;br /&gt;
*h1, h2... (&amp;quot;header&amp;quot;) - Eintrag im Header, der auf existenz geprüft wird; Groß und Kleinschreibung ist unerheblich, Funktionen werden ersetzt.&lt;br /&gt;
*n (&amp;quot;name&amp;quot; / &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in die/den das Ergebnis (Y oder N) geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*res (&amp;quot;result&amp;quot;) - Name der Variable oder Nummer des Values, in die/den der Ergebnistext geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwischen den einzelnen Spalten; Funktionen werden ersetzt&lt;br /&gt;
*y - Typ der Prüfung; Funktionen werden ersetzt, default header&lt;br /&gt;
** header - Prüft die Existenz von Spaltennamen im Header. Die zu prüfenden Spaltennamen werden als h1, h2... übergeben, cnt ist entsprechend zu setzen. Wenn alle geprüften Spaltennamen vorhanden sind, wird Y zurück gegeben, ansonsten N. Die fehlenden Spaltennamen werden als Ergebnistext zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open   fn=C:\temp\mad\done\MTF3108_ET2607_selektion.CSV&lt;br /&gt;
 #csv_check   n=1   res=2   cnt=3   h1=eins   h2=zwei   h3=drei&lt;br /&gt;
 #coutl $VAL(1) - $VAL(2)&lt;br /&gt;
&lt;br /&gt;
==#csv_paste==&lt;br /&gt;
&lt;br /&gt;
Übernimmt eine CSV-Datei aus der Zwischenablage. Auf die Werte kann mit $SEPLINE() zugegriffen werden, siehe [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
'''Multi-Row'''&lt;br /&gt;
&lt;br /&gt;
Mit dem Multi-Row-Modus können Daten eingelesen werden, die in einer Zeile mehrere gleichartige Werte haben.&lt;br /&gt;
&lt;br /&gt;
Daten, die im Single-Row-Modus wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465&lt;br /&gt;
 01.01.2020     8574&lt;br /&gt;
 01.01.2020     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     3456&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     4457&lt;br /&gt;
 03.01.2020     7658&lt;br /&gt;
&lt;br /&gt;
Würden im Multi-Row-Modus wie folgt aussehen (und könnten auch so eingelesen werden):&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465     8574     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436     6578     3456     6578     4457     7658&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Wenn dieser Parameter einen Wert hat, dann muss die kopierte CSV-Datei in der ersten Zeile auch diesen Wert haben, oder die Aktion wird abgebrochen; Funktionen werden ersetzt&lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden.&lt;br /&gt;
* mrs (&amp;quot;multi row start&amp;quot;) - Erste Spalte für den Multi-Row-Bereich&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Tabulatorzeichen&lt;br /&gt;
* trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ; default s&lt;br /&gt;
** m - multi; siehe Abschnitt Multi-Row&lt;br /&gt;
** s - single; die CSV-Datei wird Zeile für Zeile eingelesen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
* [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
 #csv_paste   er=imp_line   hhr=Y&lt;br /&gt;
 #csv_paste   er=imp_line   y=m   mrs=1&lt;br /&gt;
&lt;br /&gt;
==$CSV()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV() greift auf einen Feldinhalt der aktuellen CSV-Zeile zu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Spalte oder 0-relative Spaltennummer. Name der Spalte setzt voraus, dass bei #csv_line der Parameter hhr gleich Y ist.&lt;br /&gt;
# optional: Stelle der Zeichens, ab dem der Inhalt des CSV-Feldes zurück gegeben wird&lt;br /&gt;
# optional: Anzahl der Zeichen, die maximal zurück gegeben werden; wird meist dafür verwendet, damit die maximale Länge von Datenbankfeldern nicht überschritten wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0)&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird in der ersten CSV-Datei (#csv_open) auf die erste Spalte (0, da 0-relativ) zugegriffen.&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0,1,30)&lt;br /&gt;
&lt;br /&gt;
Wie oben, nur werden nur die ersten 30 Zeichen zurück gegeben&lt;br /&gt;
&lt;br /&gt;
==$CSV_LINE()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV_LINE() Gibt eine ganze Zeile einer CSV-Datei zurück&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Zeile: header gibt die Header-Zeile zurück, current die aktuelle Zeile in #csv_line&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CSV_LINE wird insbesondere dafür verwendet, um CSV-Dateien mit Daten zu ergänzen. Hier im Beispiel wird jede Zeile mit einer GUID ergänzt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #text $CSV_LINE(1,current)$GUID();&lt;br /&gt;
 &lt;br /&gt;
 #csv_open   fn=c:\temp\ex.csv   hhr=Y&lt;br /&gt;
 #text_clear $CSV_LINE(1,header)guid;&lt;br /&gt;
 #csv_line   er=1   hhr=Y&lt;br /&gt;
 &lt;br /&gt;
 #text_save   fn=c:\temp\ex2.csv&lt;br /&gt;
&lt;br /&gt;
Nach dem Öffnen der bestehenden CSV-Datei (es muss hier bereits hhr gesetzt werden) wird zunächst der Header in Text 1 eingefügt, ergänzt um die Spalte ''guid'' und das abschließende Semikolon. Danach gehen wir mit #csv_line durch alle Zeile, fügen diese komplett in Text 1 ein und hängen eine GUID hinten dran. Danach wird die Datei gespeichert.&lt;br /&gt;
&lt;br /&gt;
=Text=&lt;br /&gt;
&lt;br /&gt;
==#text==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text fügt dem Text eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text fügt dem ersten Text eine Zeile hinzu, #text2 fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Und jetzt noch eine GUID: $GUID()&lt;br /&gt;
 #text Der folgende Text kommt in Großbuchstaben: $UPP(hello world)&lt;br /&gt;
&lt;br /&gt;
==#textn==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#textn fügt dem Text eine Zeile hinzu. Im Unterschied zu #text werden dabei keine Funktionen ersetzt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #textn fügt dem ersten Text eine Zeile hinzu, #text2n fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #textn und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden dabei '''nicht''' ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #textn Zeile 1&lt;br /&gt;
 #textn Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_clear löscht einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_clear löscht den ersten Text, #text_clear2 löscht den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #text_clear Zeichen, so werden die dem gerade gelöschten Text hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear7&lt;br /&gt;
 #text7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
Das vorangestellt #text_clear stellt sicher, dass Text7 leer ist. Alternativ könnte man formulieren:&lt;br /&gt;
&lt;br /&gt;
 #text_clear7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_save==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_save speichert einen Text in einer Datei.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_save speichert den ersten Text, #text_save2 speichert den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* bom (&amp;quot;Byte order mark&amp;quot;) - Wenn Y, dann wird die Datei mit BOM geschrieben; default Y&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu speichernden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname, unter dem die Datei gespeichert wird. Bestehende Dateien werden überschrieben, sofern das Betriebssystem das nicht verhindert (z.B, weil die Datei gerade geöffnet ist)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Öffnet die gespeicherte Datei gleich anschließend.&lt;br /&gt;
*sort - Wenn Y, dann wird die Datei vor dem Speichern sortiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Hello world&lt;br /&gt;
 #text_save  fn=$DIR(userroot)hello_world.txt&lt;br /&gt;
 #text_save  fn=c:\temp\export_vert_export.prepared_.csv   e=utf8   bom=N&lt;br /&gt;
&lt;br /&gt;
==#text_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_open öffnet einen Text aus einer Datei, der bisherige Inhalt der Datei wird überschrieben.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_open öffnet den ersten Text, #text_open2 öffnet den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname der Datei, die geöffnet wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_open  fn=$DIR(userroot)test.txt&lt;br /&gt;
 #text Eine weitere Zeile, $GUID()&lt;br /&gt;
 #text_save  fn=$DIR(userroot)test.txt&lt;br /&gt;
&lt;br /&gt;
==#text_props==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_props stellt Eigenschaften des Textes ein.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_props bezieht sich auf den ersten Text, #text_props2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* dub (&amp;quot;duplicates&amp;quot;) - Verhalten einer sortierten Liste bezüglich Dubletten&lt;br /&gt;
** acc (&amp;quot;accept&amp;quot;) - Dubletten werden akzeptiert&lt;br /&gt;
** err (&amp;quot;error&amp;quot;) - Dubletten führen zu Fehlern&lt;br /&gt;
** ign (&amp;quot;ignore) - Dubletten werden ignoriert&lt;br /&gt;
* srt (&amp;quot;sorted&amp;quot;) - Wenn ja, dann ist die Liste sortiert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_props   srt=Y   dup=ign&lt;br /&gt;
&lt;br /&gt;
==#text_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_set setzt eine bestimmte Zeile eines Textes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_set bezieht sich auf den ersten Text, #text_set2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;index&amp;quot;) - 0-relativer Index der Zeile, die geschrieben werden soll. Mit ''last'' kann die letzte Zeile geschrieben werden, mit ''all'' werden alle Zeilen ersetzt, das wird dann gebraucht, wenn mehrzeiliger Text zugewiesen werden soll; Funktionen werden ersetzt&lt;br /&gt;
* z - Text, der geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text_set   i=2   z=&amp;quot;dritte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=last   z=&amp;quot;letzte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=all   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
==#text_sort==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_sort sortiert einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_sort bezieht sich auf den ersten Text, #text_sort2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* y - Typ, default alpha, Funktionen werden ersetzt&lt;br /&gt;
** alpha - sortiert alphanumerisch&lt;br /&gt;
** inv - invertiert die gegebene Reihenfolge&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=&amp;quot;,OU=2nd_Level_T1,OU=Kundenservice,OU=Benutzer,OU=Testtours,OU=Travel&amp;quot;&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text_dissect   z=$VAL(1)   sep=&amp;quot;,OU=&amp;quot;&lt;br /&gt;
 #coutl  $TEXT(1)&lt;br /&gt;
 #text_sort   y=inv&lt;br /&gt;
 #text_compose   n=1   sep=.&lt;br /&gt;
 #val_set   n=1   z=tt.$VAL(1)&lt;br /&gt;
 #coutl $VAL(1)&lt;br /&gt;
&lt;br /&gt;
 Ergebnis ist:&lt;br /&gt;
 2nd_Level_T1&lt;br /&gt;
 Kundenservice&lt;br /&gt;
 Benutzer&lt;br /&gt;
 Testtours&lt;br /&gt;
 tt.Testtours.Benutzer.Kundenservice.2nd_Level_T1.&lt;br /&gt;
&lt;br /&gt;
==#text_dissect==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_dissect zerteilt einen String anhand einer vorgegebenen Trennzeichenfolge und fügt das Ergebnis dem betreffenden Text hinzu. Gegebenenfalls muss der Text vorher mit #text_clear geleert werden.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_dissect bezieht sich auf den ersten Text, #text_dissect bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - wenn Y, wird die sep-Zeichenfolge noch mal dem String angehängt; default N, Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, anhand der String zerteilt wird; Funktionen werden ersetzt&lt;br /&gt;
* z - String, der zerlegt wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_compose==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_compose setzt einen Text mithilfe eines Trennzeichens zu einem String zusammen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_compose bezieht sich auf den ersten Text, #text_compose bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - Wenn Y, wird die Trennzeichenfolge auch noch mal am Ende des Strings eingefügt; default N, Funktionen werden ersetzt&lt;br /&gt;
* n - Nummer des Values oder Name der Variable, in welche der String geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichenfolge, die beim Zusammenfügen des Textes verwendet wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_act==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_act bearbeitet einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_act bezieht sich auf den ersten Text, #text_act2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text der Zeile, die bei insert eingefügt werden soll; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* cu (&amp;quot;current&amp;quot;) - 0-relative Zeilennummer der Operation; default 0, Funktionen werden ersetzt&lt;br /&gt;
* ne (&amp;quot;new&amp;quot;) - 0-relative Zeilennummer als Ziel bei move; default 0, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt&lt;br /&gt;
** delete - Löscht die Zeile an Position cu (&amp;quot;current&amp;quot;)&lt;br /&gt;
** insert - Fügt den Text c an der Position cu (&amp;quot;current&amp;quot;) ein&lt;br /&gt;
** move - verschiebt die Zeile cu (&amp;quot;current&amp;quot;) nach Zeile ne (&amp;quot;new&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #text_act   y=move   cu=0&lt;br /&gt;
&lt;br /&gt;
==#text_loop==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_loop geht durch die Zeilen eines Textes und ruft für jede Zeile ''er'' auf&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_loop  bezieht sich auf den ersten Text, #text_loop2  bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich ert bezieht&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m - (&amp;quot;maximum&amp;quot;) Es wird maximal für die Anzahl der angegebenen Zeilen das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* n - Name der Variable, in welche die 0-relative Schleifenvariable geschrieben wird. (Es würde auch in einen Value geschrieben, wenn es sich um eine Nummer handelt, das ergibt in der Praxis aber meist nicht viel Sinn) Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear eins&lt;br /&gt;
 #text zwei&lt;br /&gt;
 #text drei&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear #coutl - $TEXT(1,$VAR(eins))&lt;br /&gt;
 #text_loop   er=1   n=eins&lt;br /&gt;
&lt;br /&gt;
==#tvl_add==&lt;br /&gt;
&lt;br /&gt;
Addiert dem Wert in einer Text-Valueliste einen Wert hinzu. Es handelt sich dabei um eine nummerierte Prozedur: #tvl_add arbeitet mit Text 1, #tvl_add2 mit Text 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Zeile, der ein Wert hinzugefügt wird; Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Operation, Funktionen werden ersetzt, default text&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
* z - Der Wert, der hinzugefügt wird&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text eins=1&lt;br /&gt;
 #text zwei=2&lt;br /&gt;
 #text drei=3&lt;br /&gt;
 #tvl_add   y=int   n=zwei   z=1&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==$TEXT()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $TEXT() wird auf den Inhalt des Textes zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# optional Zeile des Textes (0-relativ). Wenn es keinen zweiten Parameter gibt, wird der komplette Text zurück gegeben. Alternativ als zweiter Parameter eine Sonderfunktion:&lt;br /&gt;
## cnt / count - Gibt die Anzahl der Zeilen zurück&lt;br /&gt;
## last - Gibt die letzte Zeile zurück&lt;br /&gt;
## ix - Gibt die Position des Textes im dritten Parameter zurück&lt;br /&gt;
## as_line - Gibt den Text als eine Zeile zurück, Zeilenumbrüche werden durch den dritten Parameter ersetzt&lt;br /&gt;
# optional in abhängigkeit vom zweiten Paremeter&lt;br /&gt;
## wenn zweiter Parameter ix: Textzeile, nach der mit ix gesucht wird&lt;br /&gt;
## wenn zweiter Parameter as_line: Zeichenfolge, mit der die Zeilenumbrüche ersetzt werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Zeile 3&lt;br /&gt;
 #message  c=$TEXT(1)&lt;br /&gt;
&lt;br /&gt;
 #code url=$TEXT(1,as_line,&amp;amp;)&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich gilt in BAL: Eine Prozedur - eine Zeile.&lt;br /&gt;
&lt;br /&gt;
Bei vielen und/oder langen Parametern führt das zu recht langen Code-Zeilen und zu Unübersichtlichkeit. Hier können nun Teile der Parameter mit #code in weitere Zeile ausgelagert werden, deren Inhalt dann mit $CODE$ oder $CODE$ der eigentlichen Code-Zeile hinzugefügt wird.&lt;br /&gt;
&lt;br /&gt;
==#code==&lt;br /&gt;
&lt;br /&gt;
Fügt Text dem Code-Speicher hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#code hat keine benannten Parameter. Die ganze Zeile nach dem #code und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=G:\pics\pic5d68865cdaba62_62767562.jpg&lt;br /&gt;
 #code fn2=G:\pics\pic5d913c48682128_67979256.jpg&lt;br /&gt;
 #email_send   from=test@****.de   to=info@*****************.de   bcc=info@*****.de   subject=Testmail   text=$TEXT(1)   $CODE$&lt;br /&gt;
&lt;br /&gt;
==$CODE$ / $CODEN$==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CODE$ und $CODEN$ sind keine Funktionen, auch wenn sie auf den ersten Blick ähnlich aussehen. Sie haben keine Parameter und auch keine Klammern, dafür ein abschließendes $.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen fügen den Code-Speicher der jeweiligen Zeile hinzu. $CODE$ löscht danach den Code-Speicher, $CODEN$ tut das nicht, so dass dieselben Parameter wiederholt eingefügt werden können (beim letzten Einfügen sollte dann $CODE$ verwendet werden).&lt;br /&gt;
&lt;br /&gt;
=Separierte Zeile=&lt;br /&gt;
&lt;br /&gt;
Eine separierte Zeile ist eine Textzeile, die mehrere gleichartige Werte enthält, die durch Trennzeichen getrennt sind.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 3244,4465,7763,4536,4356,7777&lt;br /&gt;
&lt;br /&gt;
Solche Zeilen können mit #sepline aufgetrennt werden.&lt;br /&gt;
&lt;br /&gt;
==#sepline==&lt;br /&gt;
&lt;br /&gt;
Trennt eine separierte Zeile auf und führt für jeden Wert das mit er angegebene Kommando aus.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur (#sepline, #sepline2...)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y; Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, für welche die Transaktion gestartet wird, wenn ert=Y. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern (&amp;quot;each row no&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Wenn Y, wird für jeden Wert der separierten Zeile eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Es wird maximal für die Anzahl der angegebenen Werte das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten; Funktionen werden ersetzt.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N; Funktionen werden ersetzt.&lt;br /&gt;
* nn (&amp;quot;not null&amp;quot;) - Wenn Y, dann wird er nur für Werte der separierten Zeile aufgerufen, die nicht leer sind. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Das oder die Trennzeichen; default ist das Semikolon, Funktionen werden ersetzt.&lt;br /&gt;
* z - Der Inhalt der separierten Zeile; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(1)&lt;br /&gt;
 #sepline z=3244,4465,7763,4536,4356,7777   sep=,   er=1&lt;br /&gt;
&lt;br /&gt;
==$SEPLINE()==&lt;br /&gt;
&lt;br /&gt;
Greift auf den einzelnen Wert einer mit #sepline getrennten Zeile zu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der separierten Zeile&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(3)&lt;br /&gt;
 #sepline3 z=3244;4465;7763;4536;4356;7777     er=1&lt;br /&gt;
&lt;br /&gt;
=User und Rechte=&lt;br /&gt;
&lt;br /&gt;
Aus Gründen der Übersichtlichkeit ist die Rechtevergabe zweistufig:&lt;br /&gt;
&lt;br /&gt;
# Es werden (meist am Anfang eines Primär-Kommandos) Rechte-Definitionen erstellt, die einer oder mehreren Benutzergruppen Rechte (lesen oder lesen und schreiben) zuweisen. Die Rechte werden dabei implizit auch allen Untergruppen der angegebenen Benutzergruppe erteilt (Zum Beispiel: Rechte der Gruppe ''user'' hat auch implizit die Gruppe ''user.admin'').&lt;br /&gt;
# Dem Parameter r verschiedener Prozeduren kann dann eine Rechte-Definition zugewiesen werden.&lt;br /&gt;
&lt;br /&gt;
Den Parameter r als Rechte-Definition berücksichtigen die folgenden Prozeduren:&lt;br /&gt;
&lt;br /&gt;
* #frm&lt;br /&gt;
* Buttons (#btn, #btns_btn)&lt;br /&gt;
* Alle Segmente (#text_seg, #memo_seg, #btns_seg, vl_seg, #grd_seg, #xgrd_seg)&lt;br /&gt;
* Tree (#tree_add, #tree_fill, #tree_fillsql, Lese-Recht reicht)&lt;br /&gt;
* Grid-Spalten (#grd_col, #xgrd_col)&lt;br /&gt;
* #vl_line (für die komplette Zeile (r) und die einzelne Zelle (r1, r2, r3...))&lt;br /&gt;
&lt;br /&gt;
Wo der Parameter r nicht gesetzt ist, wird die Rechte-Definition der Formulars verwendet.&lt;br /&gt;
&lt;br /&gt;
==#rights==&lt;br /&gt;
&lt;br /&gt;
Setzt eine Rechte-Definition im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Rechte-Definition; default ist ''frm'', also dsa Default-Recht für das Formular.&lt;br /&gt;
* r_ (&amp;quot;right&amp;quot;) - Prefix für die Benutzergruppe. Für die Rechte-Definition sind die folgenden Werte zulässig&lt;br /&gt;
** n (&amp;quot;no&amp;quot;) - kein Recht&lt;br /&gt;
** r (&amp;quot;read&amp;quot;) - nur lesen&lt;br /&gt;
** w (&amp;quot;write&amp;quot;) - lesen und schreiben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights  n=frm   r_user=r   r_user.admin=w&lt;br /&gt;
&lt;br /&gt;
Setzt für alle User das Lese-Recht und für Administratoren das Lese- und Schreibrecht.&lt;br /&gt;
&lt;br /&gt;
==#rights_clear==&lt;br /&gt;
&lt;br /&gt;
Löscht alle Rechte-Definitionen im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
(Wird in der Praxis selten benötigt, weil Kommandos mit leerer Rechte-Definition starten.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights_clear&lt;br /&gt;
&lt;br /&gt;
==$USERID()==&lt;br /&gt;
&lt;br /&gt;
Die ID des angemeldeten Users&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kusr=$USERID()&lt;br /&gt;
&lt;br /&gt;
==$RIGHTUSERID()==&lt;br /&gt;
&lt;br /&gt;
Administratoren können andere User einstellen (Userliste links unten im BAF-Client), vor allem um deren Rechte zu prüfen. Die UserID dieses ausgewählten Users kann mit der Funktion $RIGHTUSERID() ermittelt werden.&lt;br /&gt;
&lt;br /&gt;
In fast allen Fällen gilt der folgende Grundsatz: Lesende Operationen mit $RIGHTUSERID(), schreibende Operationen mit $USERID().&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_open   kusr=$RIGHTUSERID()&lt;br /&gt;
&lt;br /&gt;
==$ADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der angemeldete User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $ADM()&lt;br /&gt;
&lt;br /&gt;
==$RADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der ausgewählte User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $RADM()&lt;br /&gt;
&lt;br /&gt;
=Ausführen=&lt;br /&gt;
&lt;br /&gt;
==#exec==&lt;br /&gt;
&lt;br /&gt;
Führt ein anderes Kommando aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Names des (Primär- oder Sub-) Kommandos, das ausgeführt werden soll.&lt;br /&gt;
* ex (&amp;quot;exception&amp;quot;) - Name oder Nummer des Kommandos, das ausgeführt wird, wenn bei der Ausführung von cmd eine Exception auftritt; siehe Beispiele&lt;br /&gt;
* fin (&amp;quot;finally&amp;quot;) - Name oder Nummer des Kommandos, das nach der Ausführung von cmd ausgeführt wird - egal ob eine Exception aufgetreten ist oder nicht. Wird nur berücksichtigt, wenn der Parameter ex nicht gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel löst das Problem, dass ein neues PDF unter demselben Dateinamen nicht erstellt werden kann, wenn beim vorherigen Versuche der Erstellung eine Exception aufgetreten ist. In einem solchen Fall wurde ein #pdf_start, aber kein #pdf_stop ausgeführt, und die geöffnete Datei sperrt diesen Dateiname, bis der BAF-Client geschlossen wird. Lösung dieses Problems ist es, im Parameter ex ein #pdf stop auszuführen; auf das Öffnen der Datei kann in einem solchen Fall verzichtet werden. Mit der Funktion $DATA() wird hier im Beispiel gezielt eine Exception ausgelöst.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test_pdf&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #pdf_text  c=&amp;quot;Hello World&amp;quot;&lt;br /&gt;
 -- #cmd #pdf_text  c=&amp;quot;Hello World $DATA(dat,test)&amp;quot;&lt;br /&gt;
 #cmd #pdf_stop   o=Y&lt;br /&gt;
 &lt;br /&gt;
 #pdf_start  fn=$DIR(doc)\test.pdf&lt;br /&gt;
 #exec   cmd=1   ex=&amp;quot;#pdf_stop   o=N&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test_pdf executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#exec_async==&lt;br /&gt;
&lt;br /&gt;
Führt ein anderes Kommando aus, allerdings asynchron (über einen Timer). Das wird beispielsweise dann benötigt, wenn mit einem chg-Parameter eines Grid oder eine VL-Segmentes die Seite neu aufgebaut wird. Würde hier mit #exec gearbeitet, würde nach dem Aufbau der Seite die Ausführung die diesem Segment zurückkehren, das es aber zu diesem Zeitpunkt gar nicht mehr gibt. Mit #exec_async tritt dieses Problem nicht auf.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter sind dieselben wie bei #exec&lt;br /&gt;
&lt;br /&gt;
==#batchexec==&lt;br /&gt;
&lt;br /&gt;
Speichert den Text n in der Datei batch.bat und führt diese aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clr (&amp;quot;clear&amp;quot;) - Wenn Y, wird der Text nach Ausführung des Batch-Datei gelöscht; Default Y; Funktionen werden ersetzt;&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes; der mit #text gespeicherte Text hat die Nummer 1 &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #batchexec   n=1&lt;br /&gt;
&lt;br /&gt;
==#file_open==&lt;br /&gt;
&lt;br /&gt;
Öffnet eine Datei (oder auch eine Webseite)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder die URL der Webseite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_open  fn=c:\temp\test.csv&lt;br /&gt;
 #file_open  fn=https://www.google.de&lt;br /&gt;
&lt;br /&gt;
==#loop==&lt;br /&gt;
&lt;br /&gt;
BAL kennt keine Schleifen als Sprachelement. Um Schleifen mit einer fest Schleifenzahl auszuführen, wird die Prozedur #loop verwendet. lf muss nicht kleiner als lt sein, #loop kann auch von oben nach unten zählen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* lf (&amp;quot;loop from&amp;quot;) - Anfangswert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* lt (&amp;quot;loop to&amp;quot;) - Endwert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in der die Schleifenvariable gespeichert wird (damit sie an anderer Stelle gelesen werden kann); Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #loop   lf=42   lt=1337   er=test_line&lt;br /&gt;
&lt;br /&gt;
==#exit==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #exit bricht die Ausführung auf der jeweiligen Code-Ebene (Kommando bzw. Sub-Kommando) ab&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 ~ $EMPTY($PVAL(vl,id))   and   $PVAL(vl,status) &amp;gt; 20&lt;br /&gt;
 #sql select nextval('ausza_id') as id&lt;br /&gt;
 #sql_openval   f_id=1&lt;br /&gt;
 #page_val   i=vl   f=id   z=$VAL(1)&lt;br /&gt;
 #save&lt;br /&gt;
 #exit&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Der Beispiel-Code befindet sich auf der Seite xausza_page_ausza und baut die entsprechende Seite auf. Er prüft, ob bereits eine ID-Gesetzt ist - wenn nicht, wird über eine Datenbank-Sequenz die nächste ID abgefragt, in das VL-Segment geschrieben und die Seite gespeichert. Beim Speichern der Seite wird sie jedoch neu aufgerufen, also komplett neu aufgebaut, was erst einmal kein Problem ist. Danach würde aber die Ausführung auf der Code-Ebene, auf der sich #save befindet, fortgeführt, was zur Folge hat, dass die dann folgenden Segmente doppelt erscheinen (zunächst die aus dem Neu-Aufbau der Seite, dann die, die von der Fortsetzung des Codes her stammen).&lt;br /&gt;
&lt;br /&gt;
Um dies zu vermeiden muss die Ausführung des Codes nach #save abgebrochen werden.&lt;br /&gt;
&lt;br /&gt;
==$EXEC==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando. Im ausgeführten Kommando kann eine Variable gesetzt werden, die dann als Funktionsergebnis von $EXEC zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll&lt;br /&gt;
# optional: Der Name der Variablen, in der das Ergebnis steht; default ist ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;test_funkexec&amp;quot;   y=console&lt;br /&gt;
 #cout   c=$EXEC(test_funkexec_line)&lt;br /&gt;
&lt;br /&gt;
 -- test_funkexec_line&lt;br /&gt;
 #var_set   n=result   z=42&lt;br /&gt;
&lt;br /&gt;
=Dateien und Verzeichnisse=&lt;br /&gt;
&lt;br /&gt;
==#file_op==&lt;br /&gt;
&lt;br /&gt;
Führt eine Operation mit einer Datei oder einem Verzeichnis aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder des Verzeichnisses&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in die/den das Ergebnis der Operation (Y oder N) geschrieben wird.&lt;br /&gt;
* on (&amp;quot;old name) - der bisherige Dateiname bei RenameFile&lt;br /&gt;
* y - Typ der Operation&lt;br /&gt;
** cd / createdir - Erzeugt ein Verzeichnis&lt;br /&gt;
** cf / copyfile - Kopiert eine Datei (von on zu fn)&lt;br /&gt;
** dac / deleteaftercopy - wenn sowohl die mit fn als auch die mit on spezifizierte Datei existiert, wird die mit on spezifizierte Datei gelöscht und das Kommando gibt Y zurück.&lt;br /&gt;
** df / deletefile - Löscht eine Datei&lt;br /&gt;
** fd / forcedirectories - Stellt sicher, dass ein Pfad vorhanden ist&lt;br /&gt;
** rd / removedir - Entfernt ein Verzeichnis&lt;br /&gt;
** rf / renamefile - Benennt eine Datei um, kann auch dazu verwendet werden, eine Datei zu verschieben&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #file_op   y=renamefile   on=c:\temp\debug.txt   fn=c:\temp\test\debug.txt   n=1&lt;br /&gt;
 #cout   c=$VAL(1)&lt;br /&gt;
 &lt;br /&gt;
 #file_op   y=fd   fn=c:\eins\zwei\drei\vier&lt;br /&gt;
&lt;br /&gt;
==#file_search==&lt;br /&gt;
&lt;br /&gt;
Sucht Dateien und schreibt die Ergebnisliste in einen Text.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* clr - (&amp;quot;clear&amp;quot;) wenn Y, wird der Text vor der Suche geleert. Default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, in den die Ergebnisliste geschrieben wird; default 1, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_search   fn=c:\*.ini   n=1   y=0   all_=Y&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==#file_wait==&lt;br /&gt;
&lt;br /&gt;
Wartet, bis zumindest eine Datei vorhanden ist, die den Kriterien entspricht, und führt dann cmd aus. Wird nach der in to eingestellten Zeit keine Datei gefunden, dann wird mit dem in cmdto eingestellten Kommando abgebrochen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* cmd - Kommando, das ausgeführt wird, sobald eine Datei gefunden wird; Funktionen werden ersetzt&lt;br /&gt;
* cmdto - Kommando, das ausgeführt wird, sobald die Prozedur wegen eines TimeOuts abgebrochen wird; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* sleep - Zeit in ms zwischen den einzelnen Suchen nach einer Datei, die den Kriterien entspricht; Default 1000, Funktionen werden ersetzt&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in ms, nach der die Ausführung abgebrochen wird; Default 15000, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #cout c=&amp;quot;Gefunden&amp;quot;&lt;br /&gt;
 #cmd_clear2 #cout c=&amp;quot;TimeOut&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #file_wait   fn=C:\temp\test\*.txt   cmd=1   cmdto=2&lt;br /&gt;
&lt;br /&gt;
==#dir_force==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass es den spezifizierten Verzeichnispfad gibt, indem erforderlichenfalls Verzeichnisse angelegt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Names des Pfads&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_force   n=c:\temp\pdf&lt;br /&gt;
&lt;br /&gt;
==#dir_proc==&lt;br /&gt;
&lt;br /&gt;
Durchsucht ein Verzeichnis nach Dateien, die den angegebenen Kriterien entsprechen, und führt für jede gefundene Datei ''cmd'' aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das für jede gefundene Datei ausgeführt wird&lt;br /&gt;
* dn (&amp;quot;DirectoryName&amp;quot;) - Pfad des Verzeichnisses, in dem die Dateien gesucht werden; Funktionen werden ersetzt.&lt;br /&gt;
* done - Verzeichnis, in das die Dateien nach Abarbeitung verschoben werden (sofern der Parameter nicht leer ist). Funktionen werden ersetzt.&lt;br /&gt;
* error- Verzeichnis, in das die Dateien nach Abarbeitung verschoben werden (sofern der Parameter nicht leer ist), wenn der Inhalte der unter ndone angegebenen Variablen E ist. Funktionen werden ersetzt.&lt;br /&gt;
* fn (&amp;quot;filename&amp;quot;) - Suchkriterium für den Dateinamen; Funktionen werden ersetzt; Default *&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in welcher der Dateiname der aktuell zu bearbeitenden Datei inklusive Pfad gespeichert wird; Funktionen werden ersetzt; Default dir_proc&lt;br /&gt;
* ndone(&amp;quot;name done&amp;quot;) - Name der Variablen, die bestimmt, ob eine Datei in das Done-Verzeichnis verschoben wird. Vor jedem Aufruf von cmd wird diese Variable auf 'Y' gesetzt. Sie kann während der Bearbeitung auf N gesetzt werden - damit wird verhindert, dass die Datei in das Done-Verzeichnis verschoben wird. Wir die Variable auf E gesetzt, wird die Datei ins Error-Verzeichnis verschoben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_proc   dn=c:\temp\in   done=c:\temp\done   fn=*.csv   cmd=importcsv_line&lt;br /&gt;
&lt;br /&gt;
==$FILEINFO()==&lt;br /&gt;
&lt;br /&gt;
Liefert Infos über eine Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Dateiname&lt;br /&gt;
# Typ der Information, es stehen dabei folgende Optionen zur Verfügung&lt;br /&gt;
#* size - Dateigröße in Byte&lt;br /&gt;
#* size_point - Dateigröße in Byte, Punkte alle drei Zeichen von rechts&lt;br /&gt;
#* size_auto - Dateigröße in Byte, kB, MB oder GB, je nach Größe; mit Einheit&lt;br /&gt;
#* size_kb - Dateigröße in kB (analog Windows-Explorer)&lt;br /&gt;
#* date - Datum im Format dd.mm.yyyy&lt;br /&gt;
#* date_yyyy - Datum im Format yyyymmdd&lt;br /&gt;
#* datetime - Datum und Uhrzeit im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
#* datetime_yyyy - Datum im Format yyyymmddhhmmss&lt;br /&gt;
#* exists - Y, wenn die Datei existiert, sonst N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=fn   z=&amp;quot;T:\Tools Gruppenrechte\BC3 light\BafClientFM.exe&amp;quot;&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_point)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_auto)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_kb)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),exists)&lt;br /&gt;
&lt;br /&gt;
Ergebnis&lt;br /&gt;
&lt;br /&gt;
 27668480&lt;br /&gt;
 27.668.480&lt;br /&gt;
 26,39 MB&lt;br /&gt;
 27.020 kB&lt;br /&gt;
 02.05.2023&lt;br /&gt;
 20230502&lt;br /&gt;
 02.05.2023 12:20:09&lt;br /&gt;
 20230502122009&lt;br /&gt;
 Y&lt;br /&gt;
&lt;br /&gt;
==$DIR()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Verzeichnisnamen. Trailing Path Delimiter (\ bei Windows) wird immer angehängt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bezeichnung des Verzeichnisses&lt;br /&gt;
## appdata - Verzeichnis für Anwendungsdaten des Users&lt;br /&gt;
## cappdata - gemeinsames Verzeichnis für Anwendungsdaten aller User&lt;br /&gt;
## cdoc - gemeinsames Dokumentenverzeichnis  aller User&lt;br /&gt;
## cfav / cfavorites - gemeinsames Favoritenverzeichnis aller User&lt;br /&gt;
## cmusic - gemeinsames Musikverzeichnis aller User&lt;br /&gt;
## cpic / cpictures - gemeinsames Bilderverzeichnis aller User&lt;br /&gt;
## cvideo - gemeinsames Videoverzeichnis aller User&lt;br /&gt;
## desktop - Desktopverzeichnis des Rechners&lt;br /&gt;
## '''doc''' / docdir - Dokumentenverzeichnis des Users&lt;br /&gt;
## downloads - Downloadsverzeichnis des Users&lt;br /&gt;
## fav / favorites - Favoritenverzeichnis des Users&lt;br /&gt;
## fonts - Fontsverzeichnis des Rechners&lt;br /&gt;
## music - Musikverzeichnis des Users&lt;br /&gt;
## pic / pictures - Bilderverzeichnis des Users&lt;br /&gt;
## prog / program - Programmverzeichnis des Rechners&lt;br /&gt;
## prog86 / program86 - Programm86-Verzeichnis des Rechners&lt;br /&gt;
## '''root''' - Root-Verzeichnis des BAF-Clients bzw. des BAF-Servers&lt;br /&gt;
## '''userroot''' / usrroot - User-Verzeichnis des BAF-Clients&lt;br /&gt;
## video - Videoverzeichnis des Users&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=$DIR(doc)test.txt&lt;br /&gt;
&lt;br /&gt;
==$FILEDIALOG()==&lt;br /&gt;
&lt;br /&gt;
Führt einen Dateiauswahl-Dialog aus und gibt den gewählten Dateinamen zurück. Im Falle des Abbruchs wird ''abort'' zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wenn der erste Parameter ''save'' lautet, wird ein Speichern-Dialog, sonst ein Öffnen-Dialog aufgerufen.&lt;br /&gt;
# Filter-Statement, immer Kombinationen aus Text (Text-Dateien *.txt) und Filter-Statement(*.txt), getrennt durch Pipes.&lt;br /&gt;
# Standard-Dateierweiterung&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=&amp;quot;$FILEDIALOG(save,Text-Dateien *.txt|*.txt|Alle Dateien *.*|*.*,txt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Bitte beachten: Wegen der Leerzeichen im Filter-Statement muss der ganze Parameter in doppelte Anführungszeichen gesetzt werden.)&lt;br /&gt;
&lt;br /&gt;
=ZIP=&lt;br /&gt;
&lt;br /&gt;
==#zip_create==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine ZIP-Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Dateien, die der ZIP-Datei hinzugefügt werden; Funktionen werden ersetzt&lt;br /&gt;
* dir (&amp;quot;directory&amp;quot;) - Verzeichnis, wenn das nicht bei allen fn1, fn2... angegeben werden soll&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Der Dateiname, unter dem die ZIP-Datei gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* fn1, fn2,... (&amp;quot;FileName&amp;quot;) - Die Dateien, die in der ZIP-Datei gespeichert werden; die Anzahl wird mit dem Parameter cnt bestimmt; Funktionen werden ersetzt&lt;br /&gt;
* list - Nummer eines Textes (#text, #text2...), in dem die Dateien gelistet sind, die der ZIP-Datei hinzugefügt werden sollen. Wenn list ein Wert größer 0 hat, werden cnt und fn1, fn2... ignoriert. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* pw (&amp;quot;PassWord&amp;quot;) - Password der erzeugten ZIP-Datei; Funktionen werden ersetzt.&lt;br /&gt;
* pwc (&amp;quot;PassWordCrypted&amp;quot;) - Wenn Y, dann ist das Passwort mit der Verschlüsselungsfunktion auf der Seite Tools des Code-Dialogs verschlüsselt. Hinweis: Mit dieser Verschlüsselung verhindert man lediglich, dass das Passwort direkt aus dem Code ausgelesen werden kann. Wird der BAF-Client mit dem Delphi-Debugger ausgeführt, lässt sich leicht an die betreffende Stelle ein Breakpoint setzen und das Passwort dann im Klartext auslesen (dieselbe Unit uBafCrypt vorausgesetzt).&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #zip_create   fn=$VAR(root).zip   list=1&lt;br /&gt;
 &lt;br /&gt;
 #var_set   n=fn_zip   z=tt_mail_$VAR(reise)-$VAR(reisename)_$PAD($VAR(lfdnr),4,L,0)_$NOWFMT(yyyymmdd).zip&lt;br /&gt;
 #file_op   y=df   fn=$VAR(path)\$VAR(fn_zip)&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=$VAR(filename).txt&lt;br /&gt;
 #code fn2=$VAR(filename).sab&lt;br /&gt;
 #zip_create   dir=$VAR(path)   fn=$VAR(path)\$VAR(fn_zip)    pw=$VAR(pw)   $CODE$&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #zip_create ersetzt nicht vorherige Dateien. Von daher im Zweifelsfall wie im zweiten Beispiel vorher eine Datei dieses Namens löschen.&lt;br /&gt;
&lt;br /&gt;
=Ini-Dateien=&lt;br /&gt;
&lt;br /&gt;
Der BAF-Client verwendet eine Ini-Datei im Root-Verzeichnis (vor allem für die Datenbankverbindungen) und eine Ini-Datei ''BafClientFM.ini'' im User-Anwendungsverzeichnis (vor allem für die Formularpositionen). Es können aber auch weitere Ini-Dateien verwendet werden.&lt;br /&gt;
&lt;br /&gt;
==#ini_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Ini-Datei. #ini_val ist eine nummerierte Prozedur: #ini_val schreibt in die erste Ini-Datei, #ini_val2 in die zweite Ini-Datei und so weiter. Diese Ini-Dateien werden zunächst nur im Speicher gehalten und müssen explizit aus einer Datei geladen oder in eine Datei gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;item&amp;quot; / &amp;quot;ident&amp;quot;) - Name des Eintrags in der Ini-Datei; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Wenn der Parameter n den Wert ''usr'' oder ''user'' hat, dann bleibt die Nummer der Ini-Datei unberücksichtigt und der Wert wird in die Datei ''BafClientFM.ini'' im im User-Anwendungsverzeichnis geschrieben.&lt;br /&gt;
* sec (&amp;quot;section&amp;quot;) - Abschnitt in der Ini-Datei; Funktionen werden ersetzt; default ''values''&lt;br /&gt;
* z - Wert, der in die Ini-Datei geschrieben wird; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_val  i=date_last   z=$NOW()&lt;br /&gt;
&lt;br /&gt;
==#ini_load==&lt;br /&gt;
&lt;br /&gt;
Lädt eine Ini-Datei aus einer Datei. Es handelt sich um eine nummerierte Prozedur: #ini_load lädt die Ini-Datei 1, #ini_load2 lädt die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, die geladen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_load   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==#ini_save==&lt;br /&gt;
&lt;br /&gt;
Speichert eine Ini-Datei ineine Datei. Es handelt sich um eine nummerierte Prozedur: #ini_save speichert die Ini-Datei 1, #ini_save2 speichert die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, in die gespeichert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_save   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==$INI()==&lt;br /&gt;
&lt;br /&gt;
Liest einen Wert aus einer Ini-Datei.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
# Item (Ident)&lt;br /&gt;
# optional: Sektion; wenn nicht vorhanden, dann ''values''. Wenn ''db!'', dann wird als Sektion die aktuell gewählte Datenbankverbindung verwendet (in diesem Fall sollte als erster Parameter ''root'' verwendet werden).&lt;br /&gt;
# optional: Default-Wert; wenn nicht vorhanden, dann ein leerer String&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum)&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum,bearbeitung,$TODAY())&lt;br /&gt;
&lt;br /&gt;
==$INITEXT()==&lt;br /&gt;
&lt;br /&gt;
Gibt die komplette Ini-Datei zurück. Wird vor allem beim Debugging verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $INITEXT(usr)&lt;br /&gt;
&lt;br /&gt;
=Zwischenablage=&lt;br /&gt;
&lt;br /&gt;
Das BAF-Framework unterstützt die Zwischenablage nur für Text.&lt;br /&gt;
&lt;br /&gt;
==#clipboard==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Text in die Zwischenablage&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* z - Wert, der in der Zwischenablage gespeichert werden soll; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #clipboard   z=$TEXT()&lt;br /&gt;
 #clipboard   z=$CHR(dquote)$PVAL(test,zahl,allsel,$CHR(crlf))$CHR(dquote)&lt;br /&gt;
&lt;br /&gt;
==$CLIPBOARD()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Text aus der Zwischenablage zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setvar   n=clp   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
=String-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben einen String zurück.&lt;br /&gt;
&lt;br /&gt;
==$BASE64()==&lt;br /&gt;
&lt;br /&gt;
En- oder Decodiert einen Text im Base64-Code&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Encoding oder Decoding:&lt;br /&gt;
## e - Encoding&lt;br /&gt;
## d - Decoding&lt;br /&gt;
# Text, der en-oder decodet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $BASE64(e,Dies ist ein Test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$CHR()==&lt;br /&gt;
&lt;br /&gt;
Gibt ein Zeichen (ggf zwei Zeichen) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Ansi-Zeichennummer oder eine der folgenden Bezeichnungen:&lt;br /&gt;
## crlf - Zeilenumbruch #13#10&lt;br /&gt;
## cr - Zeichen #13&lt;br /&gt;
## lf - Zeichen #10&lt;br /&gt;
## tab - Tabulator&lt;br /&gt;
## quote - ' (einfache Anführungszeichen)&lt;br /&gt;
## dquote - &amp;quot; (doppelte Anführungszeichen)&lt;br /&gt;
## space / leer - Leerzeichen&lt;br /&gt;
## comma / komma - , (Komma)&lt;br /&gt;
## questionmark / qmark / frage / fragezeichen - ?&lt;br /&gt;
## bro / bracket_open - (&lt;br /&gt;
## brc / bracket_close - )&lt;br /&gt;
## dollar - $&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CONVERT()==&lt;br /&gt;
&lt;br /&gt;
Konvertiert einen String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Konvertierungsfunktion&lt;br /&gt;
## isodate&lt;br /&gt;
## isodatetime&lt;br /&gt;
## truefalse&lt;br /&gt;
## pointfloat&lt;br /&gt;
## urlcode&lt;br /&gt;
## utf8&lt;br /&gt;
# String, der konvertiert werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $CONVERT(isodate,2025-03-12)&lt;br /&gt;
 #coutl $CONVERT(isodatetime,2025-03-12 12:03:17)&lt;br /&gt;
 #coutl $CONVERT(truefalse,true)&lt;br /&gt;
 #coutl $CONVERT(pointfloat,12.3)&lt;br /&gt;
 #coutl $CONVERT(urlcode,Für schönen Ärger)&lt;br /&gt;
 #coutl $CONVERT(utf8,Für schönen Ärger)&lt;br /&gt;
&lt;br /&gt;
(Ergebnis)&lt;br /&gt;
 12.03.2025&lt;br /&gt;
 12.03.2025 12:03:17&lt;br /&gt;
 Y&lt;br /&gt;
 12,3&lt;br /&gt;
 F%C3%BCr%20sch%C3%B6nen%20%C3%84rger&lt;br /&gt;
 Für schönen Ärger&lt;br /&gt;
&lt;br /&gt;
==$COPY()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$COPY($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$EXEC()==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando aus und gibt ein Funktionsergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll.&lt;br /&gt;
# optional: Name der Variable, die als Funktionsergebnis zurück gegeben werden soll; default ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=test   z=$EXEC(testkommando)&lt;br /&gt;
&lt;br /&gt;
==$GUID()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine GUID und gibt sie zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# optional: Name einer Variablen, in welcher die GUID zusätzlich gespeichert wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kid=$GUID()&lt;br /&gt;
&lt;br /&gt;
==$HASH()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt einen Hash-Wert vom String im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, von welchem der Hash gebildet werden soll.&lt;br /&gt;
# zu verwendender Hash-Algorithmus:&lt;br /&gt;
## sha512&lt;br /&gt;
## sha512_256&lt;br /&gt;
## sha512_224&lt;br /&gt;
## sha384&lt;br /&gt;
## sha256&lt;br /&gt;
## sha224&lt;br /&gt;
## sha1&lt;br /&gt;
## md5 (Hinweis: MD5 gilt seit Längerem als nicht mehr sicher. Verwenden Sie ihn nur, wenn dies aus Gründen der Abwärts-Kompatbilität zwingend ist.)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$HASH($PVAL(vl,1,2),sha512)&lt;br /&gt;
&lt;br /&gt;
==$INCLUDE()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass der als dritter Parameter übergebene Text am Anfang oder am Ende steht, gegebenenfalls wird er dort eingefügt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## lead(oder leading) - Text muss am Anfang stehen&lt;br /&gt;
## leadci(oder leadingci oder leadingcaseinsensitive) - Text muss am Anfang stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
## trail(oder trailing) - Text muss am Ende stehen&lt;br /&gt;
## trailci(oder trailci oder trailingcaseinsensitive) - Text muss am Ende stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
# Text, in den gegebenenfalls eingefügt wird&lt;br /&gt;
# Text, der gegebenenfalls eingefügt wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCLUDE(trailci,test.PDF,.pdf)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$INVLOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Key aus einer Nachschlageliste bei Übergabe des Values.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Value des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$INVLOOKUP(general_status,aktiv,Wert nicht vorhanden)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus einer Nachschlageliste.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Key des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$LOOKUP(general_status,1,Status nicht gesetzt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOW()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Kleinbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Kleinbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LOW($EDT(edt1)) = bus&lt;br /&gt;
&lt;br /&gt;
==$LOWNOSPACE()==&lt;br /&gt;
&lt;br /&gt;
Wandelt einen String in Kleinbuchstaben und ersetzt alle Leerzeichen durch Unterstriche.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der gewandelt werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$LOWNOSPACE($PVAL(vl,1,2))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$NOCRLF()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Zeilenumbrüche&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem die Zeilenumbrüche entfernt werden sollen&lt;br /&gt;
# optional: Zeichenfolge, die an Stelle der Zeilenumbrüche eingefügt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=2   z=$NOCRLF($VAL(1),;)&lt;br /&gt;
&lt;br /&gt;
==$NVL()==&lt;br /&gt;
&lt;br /&gt;
Liefert einen Ersatzwert, wenn der Wert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird, wenn der erste Parameter leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   where ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0)&lt;br /&gt;
&lt;br /&gt;
Liefert $PVAL einen leeren Wert zurück (z.B., weil die Gridzeile neu angelegt wurde und daher noch keine Nummer eingetragen ist), so wird statt dessen 0 verwendet, damit die WHERE-Klausel syntaktisch korrekt ist.&lt;br /&gt;
&lt;br /&gt;
==$ONLYCHAR()==&lt;br /&gt;
&lt;br /&gt;
Entfernt unerwünschte Zeichen aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# optional: Typ der Funktion&lt;br /&gt;
## (leer) - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z', 'ä', 'ö', 'ü', 'Ä','Ö', 'Ü', 'ß']) sind&lt;br /&gt;
## charnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind&lt;br /&gt;
## low - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## upp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## charnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## charnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## uml - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z') sind, Umlaute werden konvertiert (ä -&amp;gt; ae, ö -&amp;gt; oe, ü -&amp;gt; ue, Ä -&amp;gt; Ae, Ö -&amp;gt; Oe, Ü -&amp;gt; Ue, ß -&amp;gt; ss)&lt;br /&gt;
## umlcharnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Umlaute werden konvertiert&lt;br /&gt;
## umllow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## no191 / not191 - Es werden alle Zeichen mit der ANSI-Nummer 191 (¿) entfernt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg)&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg,umllow)&lt;br /&gt;
&lt;br /&gt;
==$PAD()==&lt;br /&gt;
&lt;br /&gt;
Füllt links oder rechts bis zur vorgegebenen Länge mit Zeichen auf.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# Soll-Länge. Ist der ursprüngliche String bereits länger, wird er nicht gekürzt, es werden aber auch keine weiteren Zeichen hinzugefügt&lt;br /&gt;
# Wenn L, werden die Zeichen vorne hinzugefügt, andernfalls hinten&lt;br /&gt;
# Zeichen, die soweit und so oft hinzugefügt werden, bis die Soll-Länge erreicht ist. Umfasst der Parameter mehrere Zeichen, werden diese ggf. nicht alle hinzugefügt.&lt;br /&gt;
# optional: Länge, auf die der ursprüngliche String vor der weiteren Verarbeitung gekürzt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   text1 = '$PAD($VAR(text1),70,R, )'&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ des Ergebnisses&lt;br /&gt;
## curr - Zahl mit zwei Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## curr4 - Zahl mit vier Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## date - Datum in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## int - ganze Zahl  in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## ld - Key einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ldv - Value einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ls - Key eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## lsv - Value eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## text, text2, text3... - Zeile eines Textes&lt;br /&gt;
# untere Grenze bzw. Name der Nachschlageliste oder des Specials&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $RANDOM(date,01.01.2022,31.12.2022)&lt;br /&gt;
 #coutl $RANDOM(text2)&lt;br /&gt;
&lt;br /&gt;
==$SUBSTR()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Selbe Funktionalität wie $COPY())&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$SUBSTR($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$STREP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string replace&amp;quot;) Ersetzt Zeichen im String durch andere Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, in welchen Zeichen ersetzt werden sollen.&lt;br /&gt;
# Zeichen, die ersetzt werden sollen&lt;br /&gt;
# Zeichen, die an deren Stelle treten sollen&lt;br /&gt;
# optional: Optionen (kombinierbar)&lt;br /&gt;
## i - Groß- und Kleinschreibung ignorieren &lt;br /&gt;
## a - Alle Vorkommen ersetzen (andernfalls wird nur das erste Vorkommen ersetzt)&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=&amp;quot;$STREP($PVAL(vl,1,2), ,_,a)&amp;quot;&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$STREP($PVAL(vl,1,2),$CHR(space),_,a)&lt;br /&gt;
&lt;br /&gt;
Hinweis: Beide Beispiele haben exakt dieselbe Funktion. Im oberen Beispiel steht das Leerzeichen direkt im Text, dafür muss der komplette Parameter in doppelte Anführungszeichen, im unteren Beispiel wird das Leerzeichen durch $CHR(space) eingefügt, dafür können die Leerzeichen unterbleiben.&lt;br /&gt;
&lt;br /&gt;
==$STROP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string operation&amp;quot;) Sammelsurium von String-Operationen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## trim - entfernt führende und folgende Leerzeichen&lt;br /&gt;
## trimleft - entfernt führende Leerzeichen&lt;br /&gt;
## trimright - entferne folgende Leerzeichen&lt;br /&gt;
## quote - setzt den String in einfache Anführungszeichen&lt;br /&gt;
## unquote - entfernt einschließende einfache Anführungszeichen&lt;br /&gt;
## dquote - setzt den String in doppelte Anführungszeichen&lt;br /&gt;
## unqduote - entfernt einschließende doppelte Anführungszeichen&lt;br /&gt;
## ex_filepath - entspricht der Delphi-Funktion ExtractFilePath&lt;br /&gt;
## ex_filedir - entspricht der Delphi-Funktion ExtractFileDir&lt;br /&gt;
## ex_filedrive - entspricht der Delphi-Funktion ExtractFileDrive&lt;br /&gt;
## ex_filename - entspricht der Delphi-Funktion ExtractFileName&lt;br /&gt;
## ex_fileext - entspricht der Delphi-Funktion ExtractFileExt&lt;br /&gt;
# String, der bearbeitet werden soll&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$STROP(quote,Test)&lt;br /&gt;
&lt;br /&gt;
==$STREXTR()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string extract&amp;quot;) Extrahiert einen Teil aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem extrahiert werden soll&lt;br /&gt;
# Extraktionstyp&lt;br /&gt;
## ffe (&amp;quot;from first exclude&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## ffi (&amp;quot;from first include&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tfe (&amp;quot;to first exclude&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tfi (&amp;quot;to first include&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## fle (&amp;quot;from last exclude&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## fli (&amp;quot;from last include&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tle (&amp;quot;to last  exclude&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tli (&amp;quot;to last include&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Trennzeichen&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffe,;)&amp;quot;    -- Ergebnis: test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffi,;)&amp;quot;    -- Ergebnis: ;test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfe,;)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfi,;)&amp;quot;    -- Ergebnis: test;&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;!§§test2,tfe,;!§§)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
&lt;br /&gt;
==$TRIM()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Leerzeichen und Zeilenumbrüche am Rand des Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der getrimmt werden soll&lt;br /&gt;
# optional&lt;br /&gt;
## L - trimmt nur auf der linken Seite&lt;br /&gt;
## R - trimmt nur auf der rechten Seite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$TRIM($VAL(1),R)&lt;br /&gt;
&lt;br /&gt;
==$UPP()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Großbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Großbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $UPP($EDT(edt1)) = BUS&lt;br /&gt;
&lt;br /&gt;
==$VT()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VT (&amp;quot;Value Translate&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Vergleichswert 1&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 1 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 2&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 2 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 3&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 3 dem ersten Parameter entspricht &lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VT(Frau,1,Herr,2,Frau,3)&lt;br /&gt;
 -- Frau -&amp;gt; 3&lt;br /&gt;
 -- Herr -&amp;gt; 2&lt;br /&gt;
 -- Test -&amp;gt; 1&lt;br /&gt;
 -- Firma -&amp;gt; 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$VTRDB()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VTRDB (&amp;quot;Value Translate Root Database&amp;quot;) gibt eine String zurück, der von einem Wert im Datenbank-Segment der Root-Ini abhängt. Diese Ini-Datei (BafClientFM.ini im selben Verzeichnis wie die BafClientFM.exe) enthält die Datenbank-Zugangsdaten. Diese könnte den folgenden Block (Auszug) enthalten:&lt;br /&gt;
&lt;br /&gt;
 [DB_PGPROD]&lt;br /&gt;
 prefix=prod&lt;br /&gt;
 Name=Postgres PROD&lt;br /&gt;
 DriverName=Postgres&lt;br /&gt;
 Database=postgres&lt;br /&gt;
 User=ttbaf3prodadmin&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Der Wert in ''prefix'' spezifiziert, ob es sich um das Produktiv- oder das Test-System handelt. In Abhängigkeit davon gibt diese Funktion dann unterschiedliche Werte zurück. Es wird immer die Sektion der gerade ausgewählten Datenbank verwendet. &lt;br /&gt;
&lt;br /&gt;
Der Hauptanwendungsfall dieser Funktion, die Notwendigkeit einer Änderung des Codes bei der Migration vom Test- in das Produktiv-System oder umgekehrt zu vermeiden. Statt dessen ermittelt die Funktion, ob sie gerade im Test- oder Produktiv-System ausgeführt wird und gibt den passenden Wert (Verzeichnis-Name, URL, ...) zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Item (Ident) in der Root-Ini (die Sektion ist immer die der aktuell ausgewählten Datenbank)&lt;br /&gt;
# Vergleichswert 1&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 1 dem Wert in der Ini-Datei entspricht&lt;br /&gt;
# Vergleichswert 2&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 2 dem Wert in der Ini-Datei entspricht&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$VTRDB(prefix,test,Test-System,prod,Produktiv-System)&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$VTRDB(prefix,test,C:\temp\export\busdaten,prod,T:\files\export\busdaten)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$VTVL()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VTVL (&amp;quot;Value Translate ValueList&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu $VT werden die zu prüfenden Werte und deren Entsprechungen nicht über Parameter übergeben, sondern aus einer Werte-Liste geholt, die in einem Text gespeichert sein muss.&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich wie folgt aufbauen&lt;br /&gt;
&lt;br /&gt;
 key1=value1&lt;br /&gt;
 key2=value2&lt;br /&gt;
 key3=value3&lt;br /&gt;
 key4=value4&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich auch mit #sql_opentvl erzeugen, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Nummer des Textes, in dem sich die Werteliste befindet.&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select userid as ckey, shortname as cvalue from user_user&lt;br /&gt;
 #sql_opentvl n=1&lt;br /&gt;
 #coutl $VTVL(591,(nicht gefunden),1)&lt;br /&gt;
&lt;br /&gt;
==$XR()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $XR (&amp;quot;XmlReplace&amp;quot;) ersetzt in XML nicht zulässige Zeichen:&lt;br /&gt;
* aus &amp;amp; wird $amp ;&lt;br /&gt;
* aus &amp;lt; wird &amp;amp;lt ;&lt;br /&gt;
* aus &amp;gt; wird &amp;amp;gt ;&lt;br /&gt;
* aus &amp;quot; wird &amp;amp;quot ;&lt;br /&gt;
* aus ' wird &amp;amp;apos ;&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Das Leerzeichen vor dem Semikolon soll verhindern, dass die Zeichen hier in der Darstellung ersetzt werden und wird nicht eingefügt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text &amp;lt;firmenname&amp;gt;$XR($DATA(dat,firmenname))&amp;lt;/firmenname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==$XRR()==&lt;br /&gt;
&lt;br /&gt;
Umkehrfunktion von $XR()&lt;br /&gt;
* aus $amp ; wird &amp;amp;&lt;br /&gt;
* aus &amp;amp;lt ; wird &amp;lt;&lt;br /&gt;
* aus &amp;amp;gt ; wird &amp;gt;&lt;br /&gt;
* aus &amp;amp;quot ; wird &amp;quot;&lt;br /&gt;
* aus &amp;amp;apos ; wird '&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
=Integer-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben eine ganze Zahl zurück&lt;br /&gt;
&lt;br /&gt;
==$DEC()==&lt;br /&gt;
&lt;br /&gt;
Verringert die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die verringert werden soll.&lt;br /&gt;
# optional: Zahl, um die verringert werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$DEC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ICALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit ganzzahligen Werten durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator, es stehen zur Verfügung&lt;br /&gt;
## +&lt;br /&gt;
## -&lt;br /&gt;
## *&lt;br /&gt;
## div&lt;br /&gt;
## mod&lt;br /&gt;
# Erste Zahl&lt;br /&gt;
# Zweite Zahl&lt;br /&gt;
# optional beim Operator +: weitere Summanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$ICALC(mod,17,5)&lt;br /&gt;
&lt;br /&gt;
==$INC()==&lt;br /&gt;
&lt;br /&gt;
Erhöht die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die erhöht werden soll.&lt;br /&gt;
# optional: Zahl, um die erhöht werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$INC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$INTLEN()==&lt;br /&gt;
&lt;br /&gt;
Ist der String im Parameter eine ganz Zahl, dann wird deren Länge in Zeichen zurückgegeben, andernfalls -1; ein leerer String im ersten Parameter ergibt 0.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, deren Länge ermittelt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTLEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Länge eines Strings in Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Länge ermittelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEVENSHTEIN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Levenshtein-Distanz (https://de.wikipedia.org/wiki/Levenshtein-Distanz) der beiden übergebenen Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# erster String&lt;br /&gt;
# zweiter String&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $LEVENSHTEIN(alpha,beta)&lt;br /&gt;
&lt;br /&gt;
==$POS()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Position des Substrings in einem String. Das Funktionsergebnis ist die Position, das erste Zeichen ist 1. 0 wird zurück gegeben, wenn der Substring im String nicht vorkommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Substring (nach dem gesucht wird)&lt;br /&gt;
# String (in dem gesucht wird)&lt;br /&gt;
# optional: Wenn ic (ignore case), dann wird bei der Suche die Groß- und Kleinschreibung nicht beachtet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $POS($EDT(edt1),$VAR(1),ic) &amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert zwischen der oberen und unteren Grenze&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ&lt;br /&gt;
## int - zufällige Ganzzahl &lt;br /&gt;
## date - zufälliges Datum &lt;br /&gt;
## curr - zufällige Zahl mit zwei Nachkommastellen&lt;br /&gt;
## curr4 - zufällige Zahl mit vier Nachkommastellen&lt;br /&gt;
## text1, text2, text3... - zufällige Zeile aus dem jeweiligen Text; text ist text1; untere und obere Grenze bleiben unberücksichtigt&lt;br /&gt;
## ld - zufälliger Schlüssel-Wert aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ldv - zufälliger Text aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ls - zufälliger Schlüssel-Wert aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## lsv - zufälliger Text aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
# untere Grenze&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $RANDOM(int,1,6)&lt;br /&gt;
&lt;br /&gt;
=Datumsfunktionen=&lt;br /&gt;
&lt;br /&gt;
==$INCDATE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktione  $INCDATE() verändert das Datum im ersten Parameter um die Anzahl Tage im zweiten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das verändert werden soll&lt;br /&gt;
# optional: Die Tage, um die verändert werden soll; wenn leer, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCDATE($NOW(),-3)   clr=Y&lt;br /&gt;
&lt;br /&gt;
==$INT2TIME()==&lt;br /&gt;
&lt;br /&gt;
Macht aus z.B. 1130 die Zeit 11:30&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zeit im Integer-Format&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_time=$INT2TIME($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$NOW()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit im Format dd.mm.yyyy hh:mm:ss zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #execsql   k_datechg=$NOW()&lt;br /&gt;
&lt;br /&gt;
==$NOWFMT()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und/oder die aktuelle Uhrzeit im angegebenen Format zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Formatierungsstring (Syntax wie FormatDateTime in Delphi)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$NOWFMT(yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$NOWMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit ohne Sekunden (also dd.mm.yyyy hh:mm) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$NOWMIN()&lt;br /&gt;
&lt;br /&gt;
==$TODAY()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum im Format dd.mm.yyyy zurück.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Wenn das Datum in einem anderen Format benötigt wird, ist $NOWFMT() das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$TODAY()&lt;br /&gt;
&lt;br /&gt;
==$DFMT()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;date formated&amp;quot;) Formatiert das übergebene Datum. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, ggf. mit Uhrzeit, das formatiert werden soll.&lt;br /&gt;
# Formatierungsstring wie in Delphi&lt;br /&gt;
# optional: Wenn hn (&amp;quot;hide null&amp;quot;), dann wird ein leerer String zurück gegeben, wenn das Datum kleiner/gleich 1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$DFMT($NOW(),yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Bool'sche Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
==$BFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert einen bool'schen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'scher Wert&lt;br /&gt;
# optional: Ergebnis, wenn Wert Y ('y', 'J', 'j', '1') ist, default Y&lt;br /&gt;
# optional: Ergebnis, wenn Wert N (also nicht 'Y', 'y', 'J', 'j', '1') ist, default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cout   c=$BFMT($VAR(test),x,)&lt;br /&gt;
&lt;br /&gt;
==$BOOL()==&lt;br /&gt;
&lt;br /&gt;
Wertet das bool'sche Statement im Parameter aus.&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
* = gleich&lt;br /&gt;
* == gleich ohne Berücksichtigung der Groß- und Kleinschreibung&lt;br /&gt;
* &amp;lt;&amp;gt; ungleich&lt;br /&gt;
* != ungleich&lt;br /&gt;
* &amp;gt; größer&lt;br /&gt;
* &amp;gt;= größer gleich&lt;br /&gt;
* &amp;lt; kleiner&lt;br /&gt;
* &amp;lt;= kleiner gleich &lt;br /&gt;
* and Und-Verknüpfung&lt;br /&gt;
* or ODER-Verknüpfung&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Statements werden von links nach rechts ausgewertet, and und or sind gleichwetig, gegebenenfalls müssen Klammern eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'sches Statement, das ausgewertet wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL((17 &amp;gt; 22) or (5 &amp;gt; 3))&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL(17 &amp;gt; 22 or 5 &amp;gt; 3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATECOMP()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn Datum 2 Operator Datum 1 zutreffend ist. Ansonsten wird N zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Wird kein Operator angegeben, dann wird die Anzahl der Tage Datum 2 - Datum 1 als Zahl zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum 1&lt;br /&gt;
# Datum 2&lt;br /&gt;
# Operator&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024,&amp;lt;)&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATEMINREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMINREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEMAXREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMAXREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in ein Datum wandeln lassen, werden zu 0 (30.12.1899) konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter diesem Datum entspricht. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;Test $DATEBETWEEN($TODAY(),1.1.2020,2.2.2022)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$EMPTY()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Parameter ein leerer String ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTY($DATE(n,grpname))&lt;br /&gt;
&lt;br /&gt;
==$EMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable ein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTYVAR(buchungsnr)&lt;br /&gt;
&lt;br /&gt;
==$IN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INIC() beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die erste Anweisung gibt Y und die zweite N zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INIC()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $IN() nicht beachtet beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen geben Y zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich die Variable, deren Namen im ersten Parameter steht, in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INICVAR() beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable, die geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die erste Anweisung gibt Y und die zweite N zurück&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=beta&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INICVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich die Variable, deren Namen im ersten Parameter steht, in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INVAR() nicht beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable, die geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen geben Y zurück&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=beta&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$ISCURR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen Currency-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISCURR($DATA(n,rechnungssumme))&lt;br /&gt;
&lt;br /&gt;
==$ISDATE()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in ein Datums- oder DatumsZeit-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Prüfoperation, default ist date&lt;br /&gt;
## date - prüft, ob in ein Datum gewandelt werden kann&lt;br /&gt;
## datetime - prüft, ob in ein Datums-Zeit-Wert gewandelt werden kann&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISDATE($DATA(n,beginn))&lt;br /&gt;
&lt;br /&gt;
==$ISINT()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen ganzzahligen Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISINT($DATA(n,tage))&lt;br /&gt;
&lt;br /&gt;
==$INTMAX()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMAX($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$INTMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMIN($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$NEMPTY()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;not empty&amp;quot;) Gibt Y zurück, wenn der Parameter nicht leer ist. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalt geprüft wird. Leerzeichen gelten als leerer String.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 &lt;br /&gt;
 ~ $NEMPTY($EDT(edt1))&lt;br /&gt;
&lt;br /&gt;
==$NEMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable kein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $NEMPTYVAR(kundennr)&lt;br /&gt;
&lt;br /&gt;
==$NOT==&lt;br /&gt;
&lt;br /&gt;
Invertiert einen bool'schen Wert. Aus Y (y, J, j, 1) wird N und aus N wird Y.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der invertiert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $NOT(2)&lt;br /&gt;
&lt;br /&gt;
==$NUMBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in eine Zahl wandeln lassen, werden zu 0 konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter dieser Zahl entspricht. Siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56,)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die beiden Beispiele unterscheiden sich auf den ersten Blick kaum. Bei der ersten Zeile muss jedoch eine Schuhgröße eingegeben werden. Bleibt das Feld im VL-Segment leer, so wird dieser fehlende Wert nach 0 konvertiert und liegt nicht zwischen 28 und 56.&lt;br /&gt;
&lt;br /&gt;
Anders bei der zweiten Zeile: Das Komma vor der schließenden Klammer sorgt für einen vierten Parameter, der ebenfalls leer ist und damit nach 0 gewandelt wird. Auf diese Weise werden die leere Eingaben (und die Eingabe von 0) gültig.&lt;br /&gt;
&lt;br /&gt;
==$REGEX()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $REGEX() (&amp;quot;regular expressions&amp;quot;) prüft, ob der String in Parameter 1 den Anforderungen von Parameter 2 entspricht (Ergebnis Y) oder nicht (Ergebnis N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft werden soll&lt;br /&gt;
# Regulärer Ausdruck, mit dem der String in Parameter 2 geprüft wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $REGEX($VAR(med),^[A-Z]{3}$)&lt;br /&gt;
&lt;br /&gt;
==$TEXT_HASLINE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $TEXT_HASLINE() prüft, ob die als Parameter 2 übergebene Textzeile in einem Text vorkommt. Es wird nur auf komplette Textzeilen geprüft. Wird zum Beispiel verwendet, um eine Liste von Kundennummern zu erstellen, und dann auf einzelne Nummern zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# Textzeile, deren Vorkommen geprüft wird&lt;br /&gt;
# Ergebnis, wenn die Textzeile vorkommt; default Y&lt;br /&gt;
# Ergebnis, wenn die Textzeile nicht vorkommt; default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $TEXT_HASLINE(1,990000018,1,0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$VIBAN()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VIBAN() (&amp;quot;validate IBAN&amp;quot;) prüft eine IBAN anhand der Prüfziffern (3. und 4. Stelle).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# IBAN, die geprüft werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VIBAN(DE12345)&lt;br /&gt;
&lt;br /&gt;
=Currency-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==$CCALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit Festkommawerten durch&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
** + - Addition&lt;br /&gt;
** - - Subtraktion&lt;br /&gt;
** * - Multiplikation&lt;br /&gt;
** / - Division&lt;br /&gt;
** % - Division und Multiplikation des Ergebnisses mit 100&lt;br /&gt;
** +4 - Addition und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** -4 - Subtraktion und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** *4 - Multiplikation und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** /4 - Division und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** %4 - Division, Multiplikation des Ergebnisses mit 100 und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
** B, b, B4, b4 - Bruttobetrag, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** E, e, E4, e4 - Enthaltene MWSt, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** M, m, M4, m4 - MWSt, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** N, n, N4, n4 - Nettobetrag, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator&lt;br /&gt;
# und weitere: Operanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 10&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(+,1,2,3,4)&amp;quot;&lt;br /&gt;
 -- Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #val_set   n=1   z=1038,87&lt;br /&gt;
 #coutl $CCALC(N,$VAL(1),19)  -  $CCALC(E,$VAL(1),19)  -&lt;br /&gt;
&lt;br /&gt;
==$CURR()==&lt;br /&gt;
&lt;br /&gt;
Currency-Werte müssen in Funktionen mit einem Punkt als Dezimaltrennzeichen eingegeben werden, da das Komma die Parameter trennt. Sofern Konstanten verwendet werden, lässt sich das einfach so eingeben, sobald aber die Werte aus anderen Funktionen kommen (zum Beispiel $DATA()), müssen sie dann mit $CURR() in dieses Format umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Vorkommastellen&lt;br /&gt;
# Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 43,48&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,$CURR(2,3))&amp;quot;&lt;br /&gt;
 -- zum Vergleich; Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert Curreny-Werte&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert&lt;br /&gt;
# optional: Formatierungsstring, default 0.00&lt;br /&gt;
# optional: wenn hn (&amp;quot;hide null&amp;quot;), dann werden leere Strings als Wert auch als leerer String ausgegeben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=###,###,###,##0.00&lt;br /&gt;
 #val_set   n=2   z=1337,42&lt;br /&gt;
 #cout   c=$CFMT($VAL(2),$VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ONLYNUM()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass in einem String nur Zahlen (ggf. auch Kommas oder Punkte) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl&lt;br /&gt;
# Art der Operation; default numkomma&lt;br /&gt;
## flnnc (&amp;quot;from last not numeric character&amp;quot;) - Ab dem letzten Zeichen, das keine Ziffer ist&lt;br /&gt;
## num - Nur Ziffern, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numkomma - Nur Ziffern und Kommata, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numpoint - Nur Ziffern und Punkte, alle anderen Zeichen werden entfernt&lt;br /&gt;
## ufnnc (&amp;quot;until first not numeric character&amp;quot;) - vom Anfang bis zum ersten Zeichen, das keine Ziffer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 -- Ergebnis 123456&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,num)&lt;br /&gt;
 -- Ergebnis 123&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,ufnnc)&lt;br /&gt;
 -- Ergebnis 456 &lt;br /&gt;
 #coutl   $ONLYNUM(123-456,flnnc)&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22563</id>
		<title>Modul VAR neu</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22563"/>
		<updated>2026-05-06T09:12:14Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #file_op */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das Modul Var sammelt neben den Variablen auch die grundlegenden Prozeduren und Funktionen.&lt;br /&gt;
&lt;br /&gt;
=Variable=&lt;br /&gt;
&lt;br /&gt;
==#var_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#setvar setzt den Wert einer Variablen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis: Variable sind global, auf sie kann auch in Sub-Kommandos zugegriffen werden. Values sind dagegen lokal.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*rf (replace functions) - Wenn Y, dann werden nach der Zuweisung auf die Variable nochmals die Funktionen ersetzt. Wird zum Beispiel benötigt, wenn Code mit Funktionen mittels $DATA() aus der Datenbank geladen wird; Funktionen werden ersetzt, default N; siehe Beispiel&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_set   n=test2  z=$GUID()&lt;br /&gt;
 #var_set   n=edt    z=$EDT(edt1)   ie=42&lt;br /&gt;
 #var_set   n=_page_kunde_adressänderung_ro   z=N   zn=Y   zr=Y   r=kundenservice&lt;br /&gt;
&lt;br /&gt;
Zum Parameter rf: $NOW() in die Zwischenablage kopieren und dann ausführen:&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=N&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=Y&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_setempty==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_setempty setzt den Wert einer Variablen, sofern sie (noch) leer ist.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Besteht der Variableninhalt aus Leerzeichen, gilt die Variable auch als leer.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_setempty   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_setempty   n=test2  z=$GUID()&lt;br /&gt;
 #var_setempty   n=edt    z=$EDT(edt1)    ie=42&lt;br /&gt;
&lt;br /&gt;
==#var_add==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_add fügt einer Variablen einen Wert hinzu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. &lt;br /&gt;
* y -Typ der Operation; default ''text''&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** month - Es wird dem Datum eine Anzahl von Monaten hinzugefügt&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
*z - Wert, welcher der Variablen hinzugefügt wird, Funktionen werden ersetzt, default ist ein leerer String oder eine 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$NOW()&lt;br /&gt;
 #var_add   n=test   z=1   y=datetime&lt;br /&gt;
 #cout   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_log==&lt;br /&gt;
&lt;br /&gt;
Schreibt den Inhalt aller Variablen in das Debug-Log.&lt;br /&gt;
&lt;br /&gt;
Wird nur zur Fehlersuche verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_log&lt;br /&gt;
&lt;br /&gt;
==$VAR()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $VAR() wird auf den Inhalt der Variable zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
# optional: Der Wert wird vor oder nach der Rückgabe als Funktionsergebnis verändert; nur für ganzzahlige Werte&lt;br /&gt;
## ib (&amp;quot;increment before&amp;quot;) - Der Wert wird vor der Rückgabe um eins erhöht&lt;br /&gt;
## db (&amp;quot;decrement before&amp;quot;) - Der Wert wird vor der Rückgabe um eins verringert&lt;br /&gt;
## ia (&amp;quot;increment after&amp;quot;) - Der Wert wird nach der Rückgabe um eins erhöht&lt;br /&gt;
## da (&amp;quot;decrement after&amp;quot;) - Der Wert wird nach der Rückgabe um eins verringert&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #message  c=$VAR(test)&lt;br /&gt;
 #var_set  n=neuer_wert   z=$VAR(wert)   ie=$VAR(alternativwert)&lt;br /&gt;
 #execsql   k_lfdnr=$VAR(lfdnr,ib)&lt;br /&gt;
&lt;br /&gt;
=Kommandos=&lt;br /&gt;
&lt;br /&gt;
(Primär- und Sub) Kommandos sind üblicherweise benannt und werden im Code-Dialog eingegeben.&lt;br /&gt;
&lt;br /&gt;
Es besteht jedoch auch die Möglichkeit, lokale Kommandos innerhalb eines anderen Kommandos zu definieren. Diese Kommandos haben statt eines Kommando-Namens dann dann eine Kommando-Nummer.&lt;br /&gt;
&lt;br /&gt;
Lokale Kommandos werden üblicherweise für folgende Zwecke verwendet:&lt;br /&gt;
&lt;br /&gt;
* Bei der Verwendung von xlive werden bisweilen Prozeduren eingesetzt, die ihrerseits ein Kommando aufrufen (z.B. #sql_open). Wenn dieses Kommando nichts bereits existiert, kann es nur als lokales Kommando erstellt werden.&lt;br /&gt;
&lt;br /&gt;
* Wenn das auszuführende Kommando auf derselben Seite stehen soll wie die aufrufende Prozedur.&lt;br /&gt;
&lt;br /&gt;
Siehe als Beispiel: [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd fügt dem Kommando eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd fügt dem ersten Kommando eine Zeile hinzu, #cmd2 fügt dem zweiten Kommando eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd hat keine benannten Parameter. Die ganze Zeile nach dem #cmd und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd3 #text $DATA(n,login);$DATA(n,shortname);$DATA(n,firstname);$DATA(n,lastname);$DATA(n,userid);&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clear löscht ein Kommando&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd_clear löscht das erste Kommando, #cmd_clear2 löscht das zweite Kommando, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #cmd_clear Zeichen, so werden die dem gerade gelöschten Kommando hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear3&lt;br /&gt;
 #cmd_clear #grd_add   i=grid   f_logtext=&amp;quot;Kunde angerufen und nicht erreicht.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#cmd_clearall==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clearall löscht alle Kommandos&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clearall&lt;br /&gt;
&lt;br /&gt;
=CSV=&lt;br /&gt;
&lt;br /&gt;
Die CSV-Routinen werden verwendet, um CSV-Dateien einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==#csv_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_open öffnet eine CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_open öffnet die erste CSV-Datei, #csv_open2 öffnet die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*ber - wenn Y, werden die Zeilenumbrüche innerhalb von Feldern durch Leerzeichen ersetzt. Die Felder müssen dabei in doppelten Anführungszeichen eingeschlossen sein.&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - (&amp;quot;Filename&amp;quot;) Dateiname der CSV-Datei&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich. Muss bereits hier gesetzt werden, wenn mit $CSV_LINE auf den Header zugegriffen werden soll, bevor #csv_line ausgeführt wird.&lt;br /&gt;
*txt (&amp;quot;Text&amp;quot;) - alternativ zum Dateinamen fn die Nummer eines Textes, der als CSV-Datei verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open  fn=c:\temp\text.csv&lt;br /&gt;
&lt;br /&gt;
==#csv_line==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_line geht zeilenweise durch die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_line geht durch die erste CSV-Datei, #csv_line2 geht durch die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;database&amp;quot;) - Die Datenbank, für welche die Transaktion ausgeführt wird, wenn ert=Y gesetzt ist. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
*er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
*ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt, Funktionen werden ersetzt&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich.&lt;br /&gt;
*m (&amp;quot;maximum&amp;quot;) - Maximale Anzahl der Zeilen, die verarbeitet wird. Wird gerne bei der Entwicklung verwendet, um die Bearbeitungsgeschwindigkeit zu erhöhen. Funktionen werden ersetzt&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird im Falle einer Exception die Bearbeitung nicht abgebrochen, sondern lediglich Warnungen geloggt; Default N, Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Semikolon, Funktionen werden ersetzt&lt;br /&gt;
*trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_line  er=test_csv_line   hhr=Y   m=3&lt;br /&gt;
&lt;br /&gt;
==#csv_check==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_check prüft die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnt (&amp;quot;count&amp;quot;) - Anzahl der Header-Einträge, die geprüft wird; Funktionen werden ersetzt&lt;br /&gt;
*h1, h2... (&amp;quot;header&amp;quot;) - Eintrag im Header, der auf existenz geprüft wird; Groß und Kleinschreibung ist unerheblich, Funktionen werden ersetzt.&lt;br /&gt;
*n (&amp;quot;name&amp;quot; / &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in die/den das Ergebnis (Y oder N) geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*res (&amp;quot;result&amp;quot;) - Name der Variable oder Nummer des Values, in die/den der Ergebnistext geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwischen den einzelnen Spalten; Funktionen werden ersetzt&lt;br /&gt;
*y - Typ der Prüfung; Funktionen werden ersetzt, default header&lt;br /&gt;
** header - Prüft die Existenz von Spaltennamen im Header. Die zu prüfenden Spaltennamen werden als h1, h2... übergeben, cnt ist entsprechend zu setzen. Wenn alle geprüften Spaltennamen vorhanden sind, wird Y zurück gegeben, ansonsten N. Die fehlenden Spaltennamen werden als Ergebnistext zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open   fn=C:\temp\mad\done\MTF3108_ET2607_selektion.CSV&lt;br /&gt;
 #csv_check   n=1   res=2   cnt=3   h1=eins   h2=zwei   h3=drei&lt;br /&gt;
 #coutl $VAL(1) - $VAL(2)&lt;br /&gt;
&lt;br /&gt;
==#csv_paste==&lt;br /&gt;
&lt;br /&gt;
Übernimmt eine CSV-Datei aus der Zwischenablage. Auf die Werte kann mit $SEPLINE() zugegriffen werden, siehe [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
'''Multi-Row'''&lt;br /&gt;
&lt;br /&gt;
Mit dem Multi-Row-Modus können Daten eingelesen werden, die in einer Zeile mehrere gleichartige Werte haben.&lt;br /&gt;
&lt;br /&gt;
Daten, die im Single-Row-Modus wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465&lt;br /&gt;
 01.01.2020     8574&lt;br /&gt;
 01.01.2020     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     3456&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     4457&lt;br /&gt;
 03.01.2020     7658&lt;br /&gt;
&lt;br /&gt;
Würden im Multi-Row-Modus wie folgt aussehen (und könnten auch so eingelesen werden):&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465     8574     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436     6578     3456     6578     4457     7658&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Wenn dieser Parameter einen Wert hat, dann muss die kopierte CSV-Datei in der ersten Zeile auch diesen Wert haben, oder die Aktion wird abgebrochen; Funktionen werden ersetzt&lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden.&lt;br /&gt;
* mrs (&amp;quot;multi row start&amp;quot;) - Erste Spalte für den Multi-Row-Bereich&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Tabulatorzeichen&lt;br /&gt;
* trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ; default s&lt;br /&gt;
** m - multi; siehe Abschnitt Multi-Row&lt;br /&gt;
** s - single; die CSV-Datei wird Zeile für Zeile eingelesen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
* [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
 #csv_paste   er=imp_line   hhr=Y&lt;br /&gt;
 #csv_paste   er=imp_line   y=m   mrs=1&lt;br /&gt;
&lt;br /&gt;
==$CSV()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV() greift auf einen Feldinhalt der aktuellen CSV-Zeile zu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Spalte oder 0-relative Spaltennummer. Name der Spalte setzt voraus, dass bei #csv_line der Parameter hhr gleich Y ist.&lt;br /&gt;
# optional: Stelle der Zeichens, ab dem der Inhalt des CSV-Feldes zurück gegeben wird&lt;br /&gt;
# optional: Anzahl der Zeichen, die maximal zurück gegeben werden; wird meist dafür verwendet, damit die maximale Länge von Datenbankfeldern nicht überschritten wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0)&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird in der ersten CSV-Datei (#csv_open) auf die erste Spalte (0, da 0-relativ) zugegriffen.&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0,1,30)&lt;br /&gt;
&lt;br /&gt;
Wie oben, nur werden nur die ersten 30 Zeichen zurück gegeben&lt;br /&gt;
&lt;br /&gt;
==$CSV_LINE()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV_LINE() Gibt eine ganze Zeile einer CSV-Datei zurück&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Zeile: header gibt die Header-Zeile zurück, current die aktuelle Zeile in #csv_line&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CSV_LINE wird insbesondere dafür verwendet, um CSV-Dateien mit Daten zu ergänzen. Hier im Beispiel wird jede Zeile mit einer GUID ergänzt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #text $CSV_LINE(1,current)$GUID();&lt;br /&gt;
 &lt;br /&gt;
 #csv_open   fn=c:\temp\ex.csv   hhr=Y&lt;br /&gt;
 #text_clear $CSV_LINE(1,header)guid;&lt;br /&gt;
 #csv_line   er=1   hhr=Y&lt;br /&gt;
 &lt;br /&gt;
 #text_save   fn=c:\temp\ex2.csv&lt;br /&gt;
&lt;br /&gt;
Nach dem Öffnen der bestehenden CSV-Datei (es muss hier bereits hhr gesetzt werden) wird zunächst der Header in Text 1 eingefügt, ergänzt um die Spalte ''guid'' und das abschließende Semikolon. Danach gehen wir mit #csv_line durch alle Zeile, fügen diese komplett in Text 1 ein und hängen eine GUID hinten dran. Danach wird die Datei gespeichert.&lt;br /&gt;
&lt;br /&gt;
=Text=&lt;br /&gt;
&lt;br /&gt;
==#text==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text fügt dem Text eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text fügt dem ersten Text eine Zeile hinzu, #text2 fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Und jetzt noch eine GUID: $GUID()&lt;br /&gt;
 #text Der folgende Text kommt in Großbuchstaben: $UPP(hello world)&lt;br /&gt;
&lt;br /&gt;
==#textn==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#textn fügt dem Text eine Zeile hinzu. Im Unterschied zu #text werden dabei keine Funktionen ersetzt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #textn fügt dem ersten Text eine Zeile hinzu, #text2n fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #textn und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden dabei '''nicht''' ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #textn Zeile 1&lt;br /&gt;
 #textn Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_clear löscht einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_clear löscht den ersten Text, #text_clear2 löscht den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #text_clear Zeichen, so werden die dem gerade gelöschten Text hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear7&lt;br /&gt;
 #text7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
Das vorangestellt #text_clear stellt sicher, dass Text7 leer ist. Alternativ könnte man formulieren:&lt;br /&gt;
&lt;br /&gt;
 #text_clear7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_save==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_save speichert einen Text in einer Datei.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_save speichert den ersten Text, #text_save2 speichert den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* bom (&amp;quot;Byte order mark&amp;quot;) - Wenn Y, dann wird die Datei mit BOM geschrieben; default Y&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu speichernden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname, unter dem die Datei gespeichert wird. Bestehende Dateien werden überschrieben, sofern das Betriebssystem das nicht verhindert (z.B, weil die Datei gerade geöffnet ist)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Öffnet die gespeicherte Datei gleich anschließend.&lt;br /&gt;
*sort - Wenn Y, dann wird die Datei vor dem Speichern sortiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Hello world&lt;br /&gt;
 #text_save  fn=$DIR(userroot)hello_world.txt&lt;br /&gt;
 #text_save  fn=c:\temp\export_vert_export.prepared_.csv   e=utf8   bom=N&lt;br /&gt;
&lt;br /&gt;
==#text_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_open öffnet einen Text aus einer Datei, der bisherige Inhalt der Datei wird überschrieben.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_open öffnet den ersten Text, #text_open2 öffnet den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname der Datei, die geöffnet wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_open  fn=$DIR(userroot)test.txt&lt;br /&gt;
 #text Eine weitere Zeile, $GUID()&lt;br /&gt;
 #text_save  fn=$DIR(userroot)test.txt&lt;br /&gt;
&lt;br /&gt;
==#text_props==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_props stellt Eigenschaften des Textes ein.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_props bezieht sich auf den ersten Text, #text_props2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* dub (&amp;quot;duplicates&amp;quot;) - Verhalten einer sortierten Liste bezüglich Dubletten&lt;br /&gt;
** acc (&amp;quot;accept&amp;quot;) - Dubletten werden akzeptiert&lt;br /&gt;
** err (&amp;quot;error&amp;quot;) - Dubletten führen zu Fehlern&lt;br /&gt;
** ign (&amp;quot;ignore) - Dubletten werden ignoriert&lt;br /&gt;
* srt (&amp;quot;sorted&amp;quot;) - Wenn ja, dann ist die Liste sortiert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_props   srt=Y   dup=ign&lt;br /&gt;
&lt;br /&gt;
==#text_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_set setzt eine bestimmte Zeile eines Textes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_set bezieht sich auf den ersten Text, #text_set2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;index&amp;quot;) - 0-relativer Index der Zeile, die geschrieben werden soll. Mit ''last'' kann die letzte Zeile geschrieben werden, mit ''all'' werden alle Zeilen ersetzt, das wird dann gebraucht, wenn mehrzeiliger Text zugewiesen werden soll; Funktionen werden ersetzt&lt;br /&gt;
* z - Text, der geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text_set   i=2   z=&amp;quot;dritte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=last   z=&amp;quot;letzte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=all   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
==#text_sort==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_sort sortiert einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_sort bezieht sich auf den ersten Text, #text_sort2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* y - Typ, default alpha, Funktionen werden ersetzt&lt;br /&gt;
** alpha - sortiert alphanumerisch&lt;br /&gt;
** inv - invertiert die gegebene Reihenfolge&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=&amp;quot;,OU=2nd_Level_T1,OU=Kundenservice,OU=Benutzer,OU=Testtours,OU=Travel&amp;quot;&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text_dissect   z=$VAL(1)   sep=&amp;quot;,OU=&amp;quot;&lt;br /&gt;
 #coutl  $TEXT(1)&lt;br /&gt;
 #text_sort   y=inv&lt;br /&gt;
 #text_compose   n=1   sep=.&lt;br /&gt;
 #val_set   n=1   z=tt.$VAL(1)&lt;br /&gt;
 #coutl $VAL(1)&lt;br /&gt;
&lt;br /&gt;
 Ergebnis ist:&lt;br /&gt;
 2nd_Level_T1&lt;br /&gt;
 Kundenservice&lt;br /&gt;
 Benutzer&lt;br /&gt;
 Testtours&lt;br /&gt;
 tt.Testtours.Benutzer.Kundenservice.2nd_Level_T1.&lt;br /&gt;
&lt;br /&gt;
==#text_dissect==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_dissect zerteilt einen String anhand einer vorgegebenen Trennzeichenfolge und fügt das Ergebnis dem betreffenden Text hinzu. Gegebenenfalls muss der Text vorher mit #text_clear geleert werden.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_dissect bezieht sich auf den ersten Text, #text_dissect bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - wenn Y, wird die sep-Zeichenfolge noch mal dem String angehängt; default N, Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, anhand der String zerteilt wird; Funktionen werden ersetzt&lt;br /&gt;
* z - String, der zerlegt wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_compose==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_compose setzt einen Text mithilfe eines Trennzeichens zu einem String zusammen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_compose bezieht sich auf den ersten Text, #text_compose bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - Wenn Y, wird die Trennzeichenfolge auch noch mal am Ende des Strings eingefügt; default N, Funktionen werden ersetzt&lt;br /&gt;
* n - Nummer des Values oder Name der Variable, in welche der String geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichenfolge, die beim Zusammenfügen des Textes verwendet wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_act==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_act bearbeitet einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_act bezieht sich auf den ersten Text, #text_act2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text der Zeile, die bei insert eingefügt werden soll; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* cu (&amp;quot;current&amp;quot;) - 0-relative Zeilennummer der Operation; default 0, Funktionen werden ersetzt&lt;br /&gt;
* ne (&amp;quot;new&amp;quot;) - 0-relative Zeilennummer als Ziel bei move; default 0, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt&lt;br /&gt;
** delete - Löscht die Zeile an Position cu (&amp;quot;current&amp;quot;)&lt;br /&gt;
** insert - Fügt den Text c an der Position cu (&amp;quot;current&amp;quot;) ein&lt;br /&gt;
** move - verschiebt die Zeile cu (&amp;quot;current&amp;quot;) nach Zeile ne (&amp;quot;new&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #text_act   y=move   cu=0&lt;br /&gt;
&lt;br /&gt;
==#text_loop==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_loop geht durch die Zeilen eines Textes und ruft für jede Zeile ''er'' auf&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_loop  bezieht sich auf den ersten Text, #text_loop2  bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich ert bezieht&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m - (&amp;quot;maximum&amp;quot;) Es wird maximal für die Anzahl der angegebenen Zeilen das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* n - Name der Variable, in welche die 0-relative Schleifenvariable geschrieben wird. (Es würde auch in einen Value geschrieben, wenn es sich um eine Nummer handelt, das ergibt in der Praxis aber meist nicht viel Sinn) Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear eins&lt;br /&gt;
 #text zwei&lt;br /&gt;
 #text drei&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear #coutl - $TEXT(1,$VAR(eins))&lt;br /&gt;
 #text_loop   er=1   n=eins&lt;br /&gt;
&lt;br /&gt;
==#tvl_add==&lt;br /&gt;
&lt;br /&gt;
Addiert dem Wert in einer Text-Valueliste einen Wert hinzu. Es handelt sich dabei um eine nummerierte Prozedur: #tvl_add arbeitet mit Text 1, #tvl_add2 mit Text 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Zeile, der ein Wert hinzugefügt wird; Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Operation, Funktionen werden ersetzt, default text&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
* z - Der Wert, der hinzugefügt wird&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text eins=1&lt;br /&gt;
 #text zwei=2&lt;br /&gt;
 #text drei=3&lt;br /&gt;
 #tvl_add   y=int   n=zwei   z=1&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==$TEXT()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $TEXT() wird auf den Inhalt des Textes zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# optional Zeile des Textes (0-relativ). Wenn es keinen zweiten Parameter gibt, wird der komplette Text zurück gegeben. Alternativ als zweiter Parameter eine Sonderfunktion:&lt;br /&gt;
## cnt / count - Gibt die Anzahl der Zeilen zurück&lt;br /&gt;
## last - Gibt die letzte Zeile zurück&lt;br /&gt;
## ix - Gibt die Position des Textes im dritten Parameter zurück&lt;br /&gt;
## as_line - Gibt den Text als eine Zeile zurück, Zeilenumbrüche werden durch den dritten Parameter ersetzt&lt;br /&gt;
# optional in abhängigkeit vom zweiten Paremeter&lt;br /&gt;
## wenn zweiter Parameter ix: Textzeile, nach der mit ix gesucht wird&lt;br /&gt;
## wenn zweiter Parameter as_line: Zeichenfolge, mit der die Zeilenumbrüche ersetzt werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Zeile 3&lt;br /&gt;
 #message  c=$TEXT(1)&lt;br /&gt;
&lt;br /&gt;
 #code url=$TEXT(1,as_line,&amp;amp;)&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich gilt in BAL: Eine Prozedur - eine Zeile.&lt;br /&gt;
&lt;br /&gt;
Bei vielen und/oder langen Parametern führt das zu recht langen Code-Zeilen und zu Unübersichtlichkeit. Hier können nun Teile der Parameter mit #code in weitere Zeile ausgelagert werden, deren Inhalt dann mit $CODE$ oder $CODE$ der eigentlichen Code-Zeile hinzugefügt wird.&lt;br /&gt;
&lt;br /&gt;
==#code==&lt;br /&gt;
&lt;br /&gt;
Fügt Text dem Code-Speicher hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#code hat keine benannten Parameter. Die ganze Zeile nach dem #code und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=G:\pics\pic5d68865cdaba62_62767562.jpg&lt;br /&gt;
 #code fn2=G:\pics\pic5d913c48682128_67979256.jpg&lt;br /&gt;
 #email_send   from=test@****.de   to=info@*****************.de   bcc=info@*****.de   subject=Testmail   text=$TEXT(1)   $CODE$&lt;br /&gt;
&lt;br /&gt;
==$CODE$ / $CODEN$==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CODE$ und $CODEN$ sind keine Funktionen, auch wenn sie auf den ersten Blick ähnlich aussehen. Sie haben keine Parameter und auch keine Klammern, dafür ein abschließendes $.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen fügen den Code-Speicher der jeweiligen Zeile hinzu. $CODE$ löscht danach den Code-Speicher, $CODEN$ tut das nicht, so dass dieselben Parameter wiederholt eingefügt werden können (beim letzten Einfügen sollte dann $CODE$ verwendet werden).&lt;br /&gt;
&lt;br /&gt;
=Separierte Zeile=&lt;br /&gt;
&lt;br /&gt;
Eine separierte Zeile ist eine Textzeile, die mehrere gleichartige Werte enthält, die durch Trennzeichen getrennt sind.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 3244,4465,7763,4536,4356,7777&lt;br /&gt;
&lt;br /&gt;
Solche Zeilen können mit #sepline aufgetrennt werden.&lt;br /&gt;
&lt;br /&gt;
==#sepline==&lt;br /&gt;
&lt;br /&gt;
Trennt eine separierte Zeile auf und führt für jeden Wert das mit er angegebene Kommando aus.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur (#sepline, #sepline2...)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y; Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, für welche die Transaktion gestartet wird, wenn ert=Y. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern (&amp;quot;each row no&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Wenn Y, wird für jeden Wert der separierten Zeile eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Es wird maximal für die Anzahl der angegebenen Werte das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten; Funktionen werden ersetzt.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N; Funktionen werden ersetzt.&lt;br /&gt;
* nn (&amp;quot;not null&amp;quot;) - Wenn Y, dann wird er nur für Werte der separierten Zeile aufgerufen, die nicht leer sind. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Das oder die Trennzeichen; default ist das Semikolon, Funktionen werden ersetzt.&lt;br /&gt;
* z - Der Inhalt der separierten Zeile; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(1)&lt;br /&gt;
 #sepline z=3244,4465,7763,4536,4356,7777   sep=,   er=1&lt;br /&gt;
&lt;br /&gt;
==$SEPLINE()==&lt;br /&gt;
&lt;br /&gt;
Greift auf den einzelnen Wert einer mit #sepline getrennten Zeile zu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der separierten Zeile&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(3)&lt;br /&gt;
 #sepline3 z=3244;4465;7763;4536;4356;7777     er=1&lt;br /&gt;
&lt;br /&gt;
=User und Rechte=&lt;br /&gt;
&lt;br /&gt;
Aus Gründen der Übersichtlichkeit ist die Rechtevergabe zweistufig:&lt;br /&gt;
&lt;br /&gt;
# Es werden (meist am Anfang eines Primär-Kommandos) Rechte-Definitionen erstellt, die einer oder mehreren Benutzergruppen Rechte (lesen oder lesen und schreiben) zuweisen. Die Rechte werden dabei implizit auch allen Untergruppen der angegebenen Benutzergruppe erteilt (Zum Beispiel: Rechte der Gruppe ''user'' hat auch implizit die Gruppe ''user.admin'').&lt;br /&gt;
# Dem Parameter r verschiedener Prozeduren kann dann eine Rechte-Definition zugewiesen werden.&lt;br /&gt;
&lt;br /&gt;
Den Parameter r als Rechte-Definition berücksichtigen die folgenden Prozeduren:&lt;br /&gt;
&lt;br /&gt;
* #frm&lt;br /&gt;
* Buttons (#btn, #btns_btn)&lt;br /&gt;
* Alle Segmente (#text_seg, #memo_seg, #btns_seg, vl_seg, #grd_seg, #xgrd_seg)&lt;br /&gt;
* Tree (#tree_add, #tree_fill, #tree_fillsql, Lese-Recht reicht)&lt;br /&gt;
* Grid-Spalten (#grd_col, #xgrd_col)&lt;br /&gt;
* #vl_line (für die komplette Zeile (r) und die einzelne Zelle (r1, r2, r3...))&lt;br /&gt;
&lt;br /&gt;
Wo der Parameter r nicht gesetzt ist, wird die Rechte-Definition der Formulars verwendet.&lt;br /&gt;
&lt;br /&gt;
==#rights==&lt;br /&gt;
&lt;br /&gt;
Setzt eine Rechte-Definition im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Rechte-Definition; default ist ''frm'', also dsa Default-Recht für das Formular.&lt;br /&gt;
* r_ (&amp;quot;right&amp;quot;) - Prefix für die Benutzergruppe. Für die Rechte-Definition sind die folgenden Werte zulässig&lt;br /&gt;
** n (&amp;quot;no&amp;quot;) - kein Recht&lt;br /&gt;
** r (&amp;quot;read&amp;quot;) - nur lesen&lt;br /&gt;
** w (&amp;quot;write&amp;quot;) - lesen und schreiben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights  n=frm   r_user=r   r_user.admin=w&lt;br /&gt;
&lt;br /&gt;
Setzt für alle User das Lese-Recht und für Administratoren das Lese- und Schreibrecht.&lt;br /&gt;
&lt;br /&gt;
==#rights_clear==&lt;br /&gt;
&lt;br /&gt;
Löscht alle Rechte-Definitionen im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
(Wird in der Praxis selten benötigt, weil Kommandos mit leerer Rechte-Definition starten.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights_clear&lt;br /&gt;
&lt;br /&gt;
==$USERID()==&lt;br /&gt;
&lt;br /&gt;
Die ID des angemeldeten Users&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kusr=$USERID()&lt;br /&gt;
&lt;br /&gt;
==$RIGHTUSERID()==&lt;br /&gt;
&lt;br /&gt;
Administratoren können andere User einstellen (Userliste links unten im BAF-Client), vor allem um deren Rechte zu prüfen. Die UserID dieses ausgewählten Users kann mit der Funktion $RIGHTUSERID() ermittelt werden.&lt;br /&gt;
&lt;br /&gt;
In fast allen Fällen gilt der folgende Grundsatz: Lesende Operationen mit $RIGHTUSERID(), schreibende Operationen mit $USERID().&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_open   kusr=$RIGHTUSERID()&lt;br /&gt;
&lt;br /&gt;
==$ADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der angemeldete User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $ADM()&lt;br /&gt;
&lt;br /&gt;
==$RADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der ausgewählte User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $RADM()&lt;br /&gt;
&lt;br /&gt;
=Ausführen=&lt;br /&gt;
&lt;br /&gt;
==#exec==&lt;br /&gt;
&lt;br /&gt;
Führt ein anderes Kommando aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Names des (Primär- oder Sub-) Kommandos, das ausgeführt werden soll.&lt;br /&gt;
* ex (&amp;quot;exception&amp;quot;) - Name oder Nummer des Kommandos, das ausgeführt wird, wenn bei der Ausführung von cmd eine Exception auftritt; siehe Beispiele&lt;br /&gt;
* fin (&amp;quot;finally&amp;quot;) - Name oder Nummer des Kommandos, das nach der Ausführung von cmd ausgeführt wird - egal ob eine Exception aufgetreten ist oder nicht. Wird nur berücksichtigt, wenn der Parameter ex nicht gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel löst das Problem, dass ein neues PDF unter demselben Dateinamen nicht erstellt werden kann, wenn beim vorherigen Versuche der Erstellung eine Exception aufgetreten ist. In einem solchen Fall wurde ein #pdf_start, aber kein #pdf_stop ausgeführt, und die geöffnete Datei sperrt diesen Dateiname, bis der BAF-Client geschlossen wird. Lösung dieses Problems ist es, im Parameter ex ein #pdf stop auszuführen; auf das Öffnen der Datei kann in einem solchen Fall verzichtet werden. Mit der Funktion $DATA() wird hier im Beispiel gezielt eine Exception ausgelöst.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test_pdf&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #pdf_text  c=&amp;quot;Hello World&amp;quot;&lt;br /&gt;
 -- #cmd #pdf_text  c=&amp;quot;Hello World $DATA(dat,test)&amp;quot;&lt;br /&gt;
 #cmd #pdf_stop   o=Y&lt;br /&gt;
 &lt;br /&gt;
 #pdf_start  fn=$DIR(doc)\test.pdf&lt;br /&gt;
 #exec   cmd=1   ex=&amp;quot;#pdf_stop   o=N&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test_pdf executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#exec_async==&lt;br /&gt;
&lt;br /&gt;
Führt ein anderes Kommando aus, allerdings asynchron (über einen Timer). Das wird beispielsweise dann benötigt, wenn mit einem chg-Parameter eines Grid oder eine VL-Segmentes die Seite neu aufgebaut wird. Würde hier mit #exec gearbeitet, würde nach dem Aufbau der Seite die Ausführung die diesem Segment zurückkehren, das es aber zu diesem Zeitpunkt gar nicht mehr gibt. Mit #exec_async tritt dieses Problem nicht auf.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter sind dieselben wie bei #exec&lt;br /&gt;
&lt;br /&gt;
==#batchexec==&lt;br /&gt;
&lt;br /&gt;
Speichert den Text n in der Datei batch.bat und führt diese aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clr (&amp;quot;clear&amp;quot;) - Wenn Y, wird der Text nach Ausführung des Batch-Datei gelöscht; Default Y; Funktionen werden ersetzt;&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes; der mit #text gespeicherte Text hat die Nummer 1 &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #batchexec   n=1&lt;br /&gt;
&lt;br /&gt;
==#file_open==&lt;br /&gt;
&lt;br /&gt;
Öffnet eine Datei (oder auch eine Webseite)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder die URL der Webseite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_open  fn=c:\temp\test.csv&lt;br /&gt;
 #file_open  fn=https://www.google.de&lt;br /&gt;
&lt;br /&gt;
==#loop==&lt;br /&gt;
&lt;br /&gt;
BAL kennt keine Schleifen als Sprachelement. Um Schleifen mit einer fest Schleifenzahl auszuführen, wird die Prozedur #loop verwendet. lf muss nicht kleiner als lt sein, #loop kann auch von oben nach unten zählen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* lf (&amp;quot;loop from&amp;quot;) - Anfangswert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* lt (&amp;quot;loop to&amp;quot;) - Endwert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in der die Schleifenvariable gespeichert wird (damit sie an anderer Stelle gelesen werden kann); Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #loop   lf=42   lt=1337   er=test_line&lt;br /&gt;
&lt;br /&gt;
==#exit==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #exit bricht die Ausführung auf der jeweiligen Code-Ebene (Kommando bzw. Sub-Kommando) ab&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 ~ $EMPTY($PVAL(vl,id))   and   $PVAL(vl,status) &amp;gt; 20&lt;br /&gt;
 #sql select nextval('ausza_id') as id&lt;br /&gt;
 #sql_openval   f_id=1&lt;br /&gt;
 #page_val   i=vl   f=id   z=$VAL(1)&lt;br /&gt;
 #save&lt;br /&gt;
 #exit&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Der Beispiel-Code befindet sich auf der Seite xausza_page_ausza und baut die entsprechende Seite auf. Er prüft, ob bereits eine ID-Gesetzt ist - wenn nicht, wird über eine Datenbank-Sequenz die nächste ID abgefragt, in das VL-Segment geschrieben und die Seite gespeichert. Beim Speichern der Seite wird sie jedoch neu aufgerufen, also komplett neu aufgebaut, was erst einmal kein Problem ist. Danach würde aber die Ausführung auf der Code-Ebene, auf der sich #save befindet, fortgeführt, was zur Folge hat, dass die dann folgenden Segmente doppelt erscheinen (zunächst die aus dem Neu-Aufbau der Seite, dann die, die von der Fortsetzung des Codes her stammen).&lt;br /&gt;
&lt;br /&gt;
Um dies zu vermeiden muss die Ausführung des Codes nach #save abgebrochen werden.&lt;br /&gt;
&lt;br /&gt;
==$EXEC==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando. Im ausgeführten Kommando kann eine Variable gesetzt werden, die dann als Funktionsergebnis von $EXEC zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll&lt;br /&gt;
# optional: Der Name der Variablen, in der das Ergebnis steht; default ist ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;test_funkexec&amp;quot;   y=console&lt;br /&gt;
 #cout   c=$EXEC(test_funkexec_line)&lt;br /&gt;
&lt;br /&gt;
 -- test_funkexec_line&lt;br /&gt;
 #var_set   n=result   z=42&lt;br /&gt;
&lt;br /&gt;
=Dateien und Verzeichnisse=&lt;br /&gt;
&lt;br /&gt;
==#file_op==&lt;br /&gt;
&lt;br /&gt;
Führt eine Operation mit einer Datei oder einem Verzeichnis aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder des Verzeichnisses&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in die/den das Ergebnis der Operation (Y oder N) geschrieben wird.&lt;br /&gt;
* on (&amp;quot;old name) - der bisherige Dateiname bei RenameFile&lt;br /&gt;
* y - Typ der Operation&lt;br /&gt;
** cd / createdir - Erzeugt ein Verzeichnis&lt;br /&gt;
** cf / copyfile - Kopiert eine Datei (von on zu fn)&lt;br /&gt;
** dac / deleteaftercopy _ wenn sowohl die mit fn als auch die mit on spezifizierte Datei existiert, wird die mit on spezifizierte Datei gelöscht und das Kommando gibt Y zurück.&lt;br /&gt;
** df / deletefile - Löscht eine Datei&lt;br /&gt;
** fd / forcedirectories - Stellt sicher, dass ein Pfad vorhanden ist&lt;br /&gt;
** rd / removedir - Entfernt ein Verzeichnis&lt;br /&gt;
** rf / renamefile - Benennt eine Datei um, kann auch dazu verwendet werden, eine Datei zu verschieben&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #file_op   y=renamefile   on=c:\temp\debug.txt   fn=c:\temp\test\debug.txt   n=1&lt;br /&gt;
 #cout   c=$VAL(1)&lt;br /&gt;
 &lt;br /&gt;
 #file_op   y=fd   fn=c:\eins\zwei\drei\vier&lt;br /&gt;
&lt;br /&gt;
==#file_search==&lt;br /&gt;
&lt;br /&gt;
Sucht Dateien und schreibt die Ergebnisliste in einen Text.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* clr - (&amp;quot;clear&amp;quot;) wenn Y, wird der Text vor der Suche geleert. Default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, in den die Ergebnisliste geschrieben wird; default 1, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_search   fn=c:\*.ini   n=1   y=0   all_=Y&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==#file_wait==&lt;br /&gt;
&lt;br /&gt;
Wartet, bis zumindest eine Datei vorhanden ist, die den Kriterien entspricht, und führt dann cmd aus. Wird nach der in to eingestellten Zeit keine Datei gefunden, dann wird mit dem in cmdto eingestellten Kommando abgebrochen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* cmd - Kommando, das ausgeführt wird, sobald eine Datei gefunden wird; Funktionen werden ersetzt&lt;br /&gt;
* cmdto - Kommando, das ausgeführt wird, sobald die Prozedur wegen eines TimeOuts abgebrochen wird; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* sleep - Zeit in ms zwischen den einzelnen Suchen nach einer Datei, die den Kriterien entspricht; Default 1000, Funktionen werden ersetzt&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in ms, nach der die Ausführung abgebrochen wird; Default 15000, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #cout c=&amp;quot;Gefunden&amp;quot;&lt;br /&gt;
 #cmd_clear2 #cout c=&amp;quot;TimeOut&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #file_wait   fn=C:\temp\test\*.txt   cmd=1   cmdto=2&lt;br /&gt;
&lt;br /&gt;
==#dir_force==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass es den spezifizierten Verzeichnispfad gibt, indem erforderlichenfalls Verzeichnisse angelegt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Names des Pfads&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_force   n=c:\temp\pdf&lt;br /&gt;
&lt;br /&gt;
==#dir_proc==&lt;br /&gt;
&lt;br /&gt;
Durchsucht ein Verzeichnis nach Dateien, die den angegebenen Kriterien entsprechen, und führt für jede gefundene Datei ''cmd'' aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das für jede gefundene Datei ausgeführt wird&lt;br /&gt;
* dn (&amp;quot;DirectoryName&amp;quot;) - Pfad des Verzeichnisses, in dem die Dateien gesucht werden; Funktionen werden ersetzt.&lt;br /&gt;
* done - Verzeichnis, in das die Dateien nach Abarbeitung verschoben werden (sofern der Parameter nicht leer ist). Funktionen werden ersetzt.&lt;br /&gt;
* error- Verzeichnis, in das die Dateien nach Abarbeitung verschoben werden (sofern der Parameter nicht leer ist), wenn der Inhalte der unter ndone angegebenen Variablen E ist. Funktionen werden ersetzt.&lt;br /&gt;
* fn (&amp;quot;filename&amp;quot;) - Suchkriterium für den Dateinamen; Funktionen werden ersetzt; Default *&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in welcher der Dateiname der aktuell zu bearbeitenden Datei inklusive Pfad gespeichert wird; Funktionen werden ersetzt; Default dir_proc&lt;br /&gt;
* ndone(&amp;quot;name done&amp;quot;) - Name der Variablen, die bestimmt, ob eine Datei in das Done-Verzeichnis verschoben wird. Vor jedem Aufruf von cmd wird diese Variable auf 'Y' gesetzt. Sie kann während der Bearbeitung auf N gesetzt werden - damit wird verhindert, dass die Datei in das Done-Verzeichnis verschoben wird. Wir die Variable auf E gesetzt, wird die Datei ins Error-Verzeichnis verschoben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_proc   dn=c:\temp\in   done=c:\temp\done   fn=*.csv   cmd=importcsv_line&lt;br /&gt;
&lt;br /&gt;
==$FILEINFO()==&lt;br /&gt;
&lt;br /&gt;
Liefert Infos über eine Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Dateiname&lt;br /&gt;
# Typ der Information, es stehen dabei folgende Optionen zur Verfügung&lt;br /&gt;
#* size - Dateigröße in Byte&lt;br /&gt;
#* size_point - Dateigröße in Byte, Punkte alle drei Zeichen von rechts&lt;br /&gt;
#* size_auto - Dateigröße in Byte, kB, MB oder GB, je nach Größe; mit Einheit&lt;br /&gt;
#* size_kb - Dateigröße in kB (analog Windows-Explorer)&lt;br /&gt;
#* date - Datum im Format dd.mm.yyyy&lt;br /&gt;
#* date_yyyy - Datum im Format yyyymmdd&lt;br /&gt;
#* datetime - Datum und Uhrzeit im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
#* datetime_yyyy - Datum im Format yyyymmddhhmmss&lt;br /&gt;
#* exists - Y, wenn die Datei existiert, sonst N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=fn   z=&amp;quot;T:\Tools Gruppenrechte\BC3 light\BafClientFM.exe&amp;quot;&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_point)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_auto)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_kb)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),exists)&lt;br /&gt;
&lt;br /&gt;
Ergebnis&lt;br /&gt;
&lt;br /&gt;
 27668480&lt;br /&gt;
 27.668.480&lt;br /&gt;
 26,39 MB&lt;br /&gt;
 27.020 kB&lt;br /&gt;
 02.05.2023&lt;br /&gt;
 20230502&lt;br /&gt;
 02.05.2023 12:20:09&lt;br /&gt;
 20230502122009&lt;br /&gt;
 Y&lt;br /&gt;
&lt;br /&gt;
==$DIR()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Verzeichnisnamen. Trailing Path Delimiter (\ bei Windows) wird immer angehängt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bezeichnung des Verzeichnisses&lt;br /&gt;
## appdata - Verzeichnis für Anwendungsdaten des Users&lt;br /&gt;
## cappdata - gemeinsames Verzeichnis für Anwendungsdaten aller User&lt;br /&gt;
## cdoc - gemeinsames Dokumentenverzeichnis  aller User&lt;br /&gt;
## cfav / cfavorites - gemeinsames Favoritenverzeichnis aller User&lt;br /&gt;
## cmusic - gemeinsames Musikverzeichnis aller User&lt;br /&gt;
## cpic / cpictures - gemeinsames Bilderverzeichnis aller User&lt;br /&gt;
## cvideo - gemeinsames Videoverzeichnis aller User&lt;br /&gt;
## desktop - Desktopverzeichnis des Rechners&lt;br /&gt;
## '''doc''' / docdir - Dokumentenverzeichnis des Users&lt;br /&gt;
## downloads - Downloadsverzeichnis des Users&lt;br /&gt;
## fav / favorites - Favoritenverzeichnis des Users&lt;br /&gt;
## fonts - Fontsverzeichnis des Rechners&lt;br /&gt;
## music - Musikverzeichnis des Users&lt;br /&gt;
## pic / pictures - Bilderverzeichnis des Users&lt;br /&gt;
## prog / program - Programmverzeichnis des Rechners&lt;br /&gt;
## prog86 / program86 - Programm86-Verzeichnis des Rechners&lt;br /&gt;
## '''root''' - Root-Verzeichnis des BAF-Clients bzw. des BAF-Servers&lt;br /&gt;
## '''userroot''' / usrroot - User-Verzeichnis des BAF-Clients&lt;br /&gt;
## video - Videoverzeichnis des Users&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=$DIR(doc)test.txt&lt;br /&gt;
&lt;br /&gt;
==$FILEDIALOG()==&lt;br /&gt;
&lt;br /&gt;
Führt einen Dateiauswahl-Dialog aus und gibt den gewählten Dateinamen zurück. Im Falle des Abbruchs wird ''abort'' zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wenn der erste Parameter ''save'' lautet, wird ein Speichern-Dialog, sonst ein Öffnen-Dialog aufgerufen.&lt;br /&gt;
# Filter-Statement, immer Kombinationen aus Text (Text-Dateien *.txt) und Filter-Statement(*.txt), getrennt durch Pipes.&lt;br /&gt;
# Standard-Dateierweiterung&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=&amp;quot;$FILEDIALOG(save,Text-Dateien *.txt|*.txt|Alle Dateien *.*|*.*,txt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Bitte beachten: Wegen der Leerzeichen im Filter-Statement muss der ganze Parameter in doppelte Anführungszeichen gesetzt werden.)&lt;br /&gt;
&lt;br /&gt;
=ZIP=&lt;br /&gt;
&lt;br /&gt;
==#zip_create==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine ZIP-Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Dateien, die der ZIP-Datei hinzugefügt werden; Funktionen werden ersetzt&lt;br /&gt;
* dir (&amp;quot;directory&amp;quot;) - Verzeichnis, wenn das nicht bei allen fn1, fn2... angegeben werden soll&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Der Dateiname, unter dem die ZIP-Datei gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* fn1, fn2,... (&amp;quot;FileName&amp;quot;) - Die Dateien, die in der ZIP-Datei gespeichert werden; die Anzahl wird mit dem Parameter cnt bestimmt; Funktionen werden ersetzt&lt;br /&gt;
* list - Nummer eines Textes (#text, #text2...), in dem die Dateien gelistet sind, die der ZIP-Datei hinzugefügt werden sollen. Wenn list ein Wert größer 0 hat, werden cnt und fn1, fn2... ignoriert. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* pw (&amp;quot;PassWord&amp;quot;) - Password der erzeugten ZIP-Datei; Funktionen werden ersetzt.&lt;br /&gt;
* pwc (&amp;quot;PassWordCrypted&amp;quot;) - Wenn Y, dann ist das Passwort mit der Verschlüsselungsfunktion auf der Seite Tools des Code-Dialogs verschlüsselt. Hinweis: Mit dieser Verschlüsselung verhindert man lediglich, dass das Passwort direkt aus dem Code ausgelesen werden kann. Wird der BAF-Client mit dem Delphi-Debugger ausgeführt, lässt sich leicht an die betreffende Stelle ein Breakpoint setzen und das Passwort dann im Klartext auslesen (dieselbe Unit uBafCrypt vorausgesetzt).&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #zip_create   fn=$VAR(root).zip   list=1&lt;br /&gt;
 &lt;br /&gt;
 #var_set   n=fn_zip   z=tt_mail_$VAR(reise)-$VAR(reisename)_$PAD($VAR(lfdnr),4,L,0)_$NOWFMT(yyyymmdd).zip&lt;br /&gt;
 #file_op   y=df   fn=$VAR(path)\$VAR(fn_zip)&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=$VAR(filename).txt&lt;br /&gt;
 #code fn2=$VAR(filename).sab&lt;br /&gt;
 #zip_create   dir=$VAR(path)   fn=$VAR(path)\$VAR(fn_zip)    pw=$VAR(pw)   $CODE$&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #zip_create ersetzt nicht vorherige Dateien. Von daher im Zweifelsfall wie im zweiten Beispiel vorher eine Datei dieses Namens löschen.&lt;br /&gt;
&lt;br /&gt;
=Ini-Dateien=&lt;br /&gt;
&lt;br /&gt;
Der BAF-Client verwendet eine Ini-Datei im Root-Verzeichnis (vor allem für die Datenbankverbindungen) und eine Ini-Datei ''BafClientFM.ini'' im User-Anwendungsverzeichnis (vor allem für die Formularpositionen). Es können aber auch weitere Ini-Dateien verwendet werden.&lt;br /&gt;
&lt;br /&gt;
==#ini_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Ini-Datei. #ini_val ist eine nummerierte Prozedur: #ini_val schreibt in die erste Ini-Datei, #ini_val2 in die zweite Ini-Datei und so weiter. Diese Ini-Dateien werden zunächst nur im Speicher gehalten und müssen explizit aus einer Datei geladen oder in eine Datei gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;item&amp;quot; / &amp;quot;ident&amp;quot;) - Name des Eintrags in der Ini-Datei; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Wenn der Parameter n den Wert ''usr'' oder ''user'' hat, dann bleibt die Nummer der Ini-Datei unberücksichtigt und der Wert wird in die Datei ''BafClientFM.ini'' im im User-Anwendungsverzeichnis geschrieben.&lt;br /&gt;
* sec (&amp;quot;section&amp;quot;) - Abschnitt in der Ini-Datei; Funktionen werden ersetzt; default ''values''&lt;br /&gt;
* z - Wert, der in die Ini-Datei geschrieben wird; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_val  i=date_last   z=$NOW()&lt;br /&gt;
&lt;br /&gt;
==#ini_load==&lt;br /&gt;
&lt;br /&gt;
Lädt eine Ini-Datei aus einer Datei. Es handelt sich um eine nummerierte Prozedur: #ini_load lädt die Ini-Datei 1, #ini_load2 lädt die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, die geladen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_load   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==#ini_save==&lt;br /&gt;
&lt;br /&gt;
Speichert eine Ini-Datei ineine Datei. Es handelt sich um eine nummerierte Prozedur: #ini_save speichert die Ini-Datei 1, #ini_save2 speichert die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, in die gespeichert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_save   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==$INI()==&lt;br /&gt;
&lt;br /&gt;
Liest einen Wert aus einer Ini-Datei.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
# Item (Ident)&lt;br /&gt;
# optional: Sektion; wenn nicht vorhanden, dann ''values''. Wenn ''db!'', dann wird als Sektion die aktuell gewählte Datenbankverbindung verwendet (in diesem Fall sollte als erster Parameter ''root'' verwendet werden).&lt;br /&gt;
# optional: Default-Wert; wenn nicht vorhanden, dann ein leerer String&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum)&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum,bearbeitung,$TODAY())&lt;br /&gt;
&lt;br /&gt;
==$INITEXT()==&lt;br /&gt;
&lt;br /&gt;
Gibt die komplette Ini-Datei zurück. Wird vor allem beim Debugging verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $INITEXT(usr)&lt;br /&gt;
&lt;br /&gt;
=Zwischenablage=&lt;br /&gt;
&lt;br /&gt;
Das BAF-Framework unterstützt die Zwischenablage nur für Text.&lt;br /&gt;
&lt;br /&gt;
==#clipboard==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Text in die Zwischenablage&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* z - Wert, der in der Zwischenablage gespeichert werden soll; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #clipboard   z=$TEXT()&lt;br /&gt;
 #clipboard   z=$CHR(dquote)$PVAL(test,zahl,allsel,$CHR(crlf))$CHR(dquote)&lt;br /&gt;
&lt;br /&gt;
==$CLIPBOARD()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Text aus der Zwischenablage zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setvar   n=clp   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
=String-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben einen String zurück.&lt;br /&gt;
&lt;br /&gt;
==$BASE64()==&lt;br /&gt;
&lt;br /&gt;
En- oder Decodiert einen Text im Base64-Code&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Encoding oder Decoding:&lt;br /&gt;
## e - Encoding&lt;br /&gt;
## d - Decoding&lt;br /&gt;
# Text, der en-oder decodet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $BASE64(e,Dies ist ein Test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$CHR()==&lt;br /&gt;
&lt;br /&gt;
Gibt ein Zeichen (ggf zwei Zeichen) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Ansi-Zeichennummer oder eine der folgenden Bezeichnungen:&lt;br /&gt;
## crlf - Zeilenumbruch #13#10&lt;br /&gt;
## cr - Zeichen #13&lt;br /&gt;
## lf - Zeichen #10&lt;br /&gt;
## tab - Tabulator&lt;br /&gt;
## quote - ' (einfache Anführungszeichen)&lt;br /&gt;
## dquote - &amp;quot; (doppelte Anführungszeichen)&lt;br /&gt;
## space / leer - Leerzeichen&lt;br /&gt;
## comma / komma - , (Komma)&lt;br /&gt;
## questionmark / qmark / frage / fragezeichen - ?&lt;br /&gt;
## bro / bracket_open - (&lt;br /&gt;
## brc / bracket_close - )&lt;br /&gt;
## dollar - $&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CONVERT()==&lt;br /&gt;
&lt;br /&gt;
Konvertiert einen String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Konvertierungsfunktion&lt;br /&gt;
## isodate&lt;br /&gt;
## isodatetime&lt;br /&gt;
## truefalse&lt;br /&gt;
## pointfloat&lt;br /&gt;
## urlcode&lt;br /&gt;
## utf8&lt;br /&gt;
# String, der konvertiert werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $CONVERT(isodate,2025-03-12)&lt;br /&gt;
 #coutl $CONVERT(isodatetime,2025-03-12 12:03:17)&lt;br /&gt;
 #coutl $CONVERT(truefalse,true)&lt;br /&gt;
 #coutl $CONVERT(pointfloat,12.3)&lt;br /&gt;
 #coutl $CONVERT(urlcode,Für schönen Ärger)&lt;br /&gt;
 #coutl $CONVERT(utf8,Für schönen Ärger)&lt;br /&gt;
&lt;br /&gt;
(Ergebnis)&lt;br /&gt;
 12.03.2025&lt;br /&gt;
 12.03.2025 12:03:17&lt;br /&gt;
 Y&lt;br /&gt;
 12,3&lt;br /&gt;
 F%C3%BCr%20sch%C3%B6nen%20%C3%84rger&lt;br /&gt;
 Für schönen Ärger&lt;br /&gt;
&lt;br /&gt;
==$COPY()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$COPY($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$EXEC()==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando aus und gibt ein Funktionsergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll.&lt;br /&gt;
# optional: Name der Variable, die als Funktionsergebnis zurück gegeben werden soll; default ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=test   z=$EXEC(testkommando)&lt;br /&gt;
&lt;br /&gt;
==$GUID()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine GUID und gibt sie zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# optional: Name einer Variablen, in welcher die GUID zusätzlich gespeichert wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kid=$GUID()&lt;br /&gt;
&lt;br /&gt;
==$HASH()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt einen Hash-Wert vom String im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, von welchem der Hash gebildet werden soll.&lt;br /&gt;
# zu verwendender Hash-Algorithmus:&lt;br /&gt;
## sha512&lt;br /&gt;
## sha512_256&lt;br /&gt;
## sha512_224&lt;br /&gt;
## sha384&lt;br /&gt;
## sha256&lt;br /&gt;
## sha224&lt;br /&gt;
## sha1&lt;br /&gt;
## md5 (Hinweis: MD5 gilt seit Längerem als nicht mehr sicher. Verwenden Sie ihn nur, wenn dies aus Gründen der Abwärts-Kompatbilität zwingend ist.)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$HASH($PVAL(vl,1,2),sha512)&lt;br /&gt;
&lt;br /&gt;
==$INCLUDE()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass der als dritter Parameter übergebene Text am Anfang oder am Ende steht, gegebenenfalls wird er dort eingefügt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## lead(oder leading) - Text muss am Anfang stehen&lt;br /&gt;
## leadci(oder leadingci oder leadingcaseinsensitive) - Text muss am Anfang stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
## trail(oder trailing) - Text muss am Ende stehen&lt;br /&gt;
## trailci(oder trailci oder trailingcaseinsensitive) - Text muss am Ende stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
# Text, in den gegebenenfalls eingefügt wird&lt;br /&gt;
# Text, der gegebenenfalls eingefügt wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCLUDE(trailci,test.PDF,.pdf)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$INVLOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Key aus einer Nachschlageliste bei Übergabe des Values.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Value des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$INVLOOKUP(general_status,aktiv,Wert nicht vorhanden)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus einer Nachschlageliste.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Key des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$LOOKUP(general_status,1,Status nicht gesetzt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOW()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Kleinbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Kleinbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LOW($EDT(edt1)) = bus&lt;br /&gt;
&lt;br /&gt;
==$LOWNOSPACE()==&lt;br /&gt;
&lt;br /&gt;
Wandelt einen String in Kleinbuchstaben und ersetzt alle Leerzeichen durch Unterstriche.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der gewandelt werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$LOWNOSPACE($PVAL(vl,1,2))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$NOCRLF()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Zeilenumbrüche&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem die Zeilenumbrüche entfernt werden sollen&lt;br /&gt;
# optional: Zeichenfolge, die an Stelle der Zeilenumbrüche eingefügt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=2   z=$NOCRLF($VAL(1),;)&lt;br /&gt;
&lt;br /&gt;
==$NVL()==&lt;br /&gt;
&lt;br /&gt;
Liefert einen Ersatzwert, wenn der Wert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird, wenn der erste Parameter leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   where ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0)&lt;br /&gt;
&lt;br /&gt;
Liefert $PVAL einen leeren Wert zurück (z.B., weil die Gridzeile neu angelegt wurde und daher noch keine Nummer eingetragen ist), so wird statt dessen 0 verwendet, damit die WHERE-Klausel syntaktisch korrekt ist.&lt;br /&gt;
&lt;br /&gt;
==$ONLYCHAR()==&lt;br /&gt;
&lt;br /&gt;
Entfernt unerwünschte Zeichen aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# optional: Typ der Funktion&lt;br /&gt;
## (leer) - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z', 'ä', 'ö', 'ü', 'Ä','Ö', 'Ü', 'ß']) sind&lt;br /&gt;
## charnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind&lt;br /&gt;
## low - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## upp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## charnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## charnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## uml - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z') sind, Umlaute werden konvertiert (ä -&amp;gt; ae, ö -&amp;gt; oe, ü -&amp;gt; ue, Ä -&amp;gt; Ae, Ö -&amp;gt; Oe, Ü -&amp;gt; Ue, ß -&amp;gt; ss)&lt;br /&gt;
## umlcharnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Umlaute werden konvertiert&lt;br /&gt;
## umllow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## no191 / not191 - Es werden alle Zeichen mit der ANSI-Nummer 191 (¿) entfernt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg)&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg,umllow)&lt;br /&gt;
&lt;br /&gt;
==$PAD()==&lt;br /&gt;
&lt;br /&gt;
Füllt links oder rechts bis zur vorgegebenen Länge mit Zeichen auf.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# Soll-Länge. Ist der ursprüngliche String bereits länger, wird er nicht gekürzt, es werden aber auch keine weiteren Zeichen hinzugefügt&lt;br /&gt;
# Wenn L, werden die Zeichen vorne hinzugefügt, andernfalls hinten&lt;br /&gt;
# Zeichen, die soweit und so oft hinzugefügt werden, bis die Soll-Länge erreicht ist. Umfasst der Parameter mehrere Zeichen, werden diese ggf. nicht alle hinzugefügt.&lt;br /&gt;
# optional: Länge, auf die der ursprüngliche String vor der weiteren Verarbeitung gekürzt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   text1 = '$PAD($VAR(text1),70,R, )'&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ des Ergebnisses&lt;br /&gt;
## curr - Zahl mit zwei Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## curr4 - Zahl mit vier Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## date - Datum in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## int - ganze Zahl  in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## ld - Key einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ldv - Value einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ls - Key eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## lsv - Value eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## text, text2, text3... - Zeile eines Textes&lt;br /&gt;
# untere Grenze bzw. Name der Nachschlageliste oder des Specials&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $RANDOM(date,01.01.2022,31.12.2022)&lt;br /&gt;
 #coutl $RANDOM(text2)&lt;br /&gt;
&lt;br /&gt;
==$SUBSTR()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Selbe Funktionalität wie $COPY())&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$SUBSTR($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$STREP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string replace&amp;quot;) Ersetzt Zeichen im String durch andere Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, in welchen Zeichen ersetzt werden sollen.&lt;br /&gt;
# Zeichen, die ersetzt werden sollen&lt;br /&gt;
# Zeichen, die an deren Stelle treten sollen&lt;br /&gt;
# optional: Optionen (kombinierbar)&lt;br /&gt;
## i - Groß- und Kleinschreibung ignorieren &lt;br /&gt;
## a - Alle Vorkommen ersetzen (andernfalls wird nur das erste Vorkommen ersetzt)&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=&amp;quot;$STREP($PVAL(vl,1,2), ,_,a)&amp;quot;&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$STREP($PVAL(vl,1,2),$CHR(space),_,a)&lt;br /&gt;
&lt;br /&gt;
Hinweis: Beide Beispiele haben exakt dieselbe Funktion. Im oberen Beispiel steht das Leerzeichen direkt im Text, dafür muss der komplette Parameter in doppelte Anführungszeichen, im unteren Beispiel wird das Leerzeichen durch $CHR(space) eingefügt, dafür können die Leerzeichen unterbleiben.&lt;br /&gt;
&lt;br /&gt;
==$STROP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string operation&amp;quot;) Sammelsurium von String-Operationen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## trim - entfernt führende und folgende Leerzeichen&lt;br /&gt;
## trimleft - entfernt führende Leerzeichen&lt;br /&gt;
## trimright - entferne folgende Leerzeichen&lt;br /&gt;
## quote - setzt den String in einfache Anführungszeichen&lt;br /&gt;
## unquote - entfernt einschließende einfache Anführungszeichen&lt;br /&gt;
## dquote - setzt den String in doppelte Anführungszeichen&lt;br /&gt;
## unqduote - entfernt einschließende doppelte Anführungszeichen&lt;br /&gt;
## ex_filepath - entspricht der Delphi-Funktion ExtractFilePath&lt;br /&gt;
## ex_filedir - entspricht der Delphi-Funktion ExtractFileDir&lt;br /&gt;
## ex_filedrive - entspricht der Delphi-Funktion ExtractFileDrive&lt;br /&gt;
## ex_filename - entspricht der Delphi-Funktion ExtractFileName&lt;br /&gt;
## ex_fileext - entspricht der Delphi-Funktion ExtractFileExt&lt;br /&gt;
# String, der bearbeitet werden soll&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$STROP(quote,Test)&lt;br /&gt;
&lt;br /&gt;
==$STREXTR()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string extract&amp;quot;) Extrahiert einen Teil aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem extrahiert werden soll&lt;br /&gt;
# Extraktionstyp&lt;br /&gt;
## ffe (&amp;quot;from first exclude&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## ffi (&amp;quot;from first include&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tfe (&amp;quot;to first exclude&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tfi (&amp;quot;to first include&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## fle (&amp;quot;from last exclude&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## fli (&amp;quot;from last include&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tle (&amp;quot;to last  exclude&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tli (&amp;quot;to last include&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Trennzeichen&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffe,;)&amp;quot;    -- Ergebnis: test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffi,;)&amp;quot;    -- Ergebnis: ;test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfe,;)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfi,;)&amp;quot;    -- Ergebnis: test;&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;!§§test2,tfe,;!§§)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
&lt;br /&gt;
==$TRIM()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Leerzeichen und Zeilenumbrüche am Rand des Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der getrimmt werden soll&lt;br /&gt;
# optional&lt;br /&gt;
## L - trimmt nur auf der linken Seite&lt;br /&gt;
## R - trimmt nur auf der rechten Seite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$TRIM($VAL(1),R)&lt;br /&gt;
&lt;br /&gt;
==$UPP()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Großbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Großbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $UPP($EDT(edt1)) = BUS&lt;br /&gt;
&lt;br /&gt;
==$VT()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VT (&amp;quot;Value Translate&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Vergleichswert 1&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 1 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 2&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 2 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 3&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 3 dem ersten Parameter entspricht &lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VT(Frau,1,Herr,2,Frau,3)&lt;br /&gt;
 -- Frau -&amp;gt; 3&lt;br /&gt;
 -- Herr -&amp;gt; 2&lt;br /&gt;
 -- Test -&amp;gt; 1&lt;br /&gt;
 -- Firma -&amp;gt; 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$VTRDB()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VTRDB (&amp;quot;Value Translate Root Database&amp;quot;) gibt eine String zurück, der von einem Wert im Datenbank-Segment der Root-Ini abhängt. Diese Ini-Datei (BafClientFM.ini im selben Verzeichnis wie die BafClientFM.exe) enthält die Datenbank-Zugangsdaten. Diese könnte den folgenden Block (Auszug) enthalten:&lt;br /&gt;
&lt;br /&gt;
 [DB_PGPROD]&lt;br /&gt;
 prefix=prod&lt;br /&gt;
 Name=Postgres PROD&lt;br /&gt;
 DriverName=Postgres&lt;br /&gt;
 Database=postgres&lt;br /&gt;
 User=ttbaf3prodadmin&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Der Wert in ''prefix'' spezifiziert, ob es sich um das Produktiv- oder das Test-System handelt. In Abhängigkeit davon gibt diese Funktion dann unterschiedliche Werte zurück. Es wird immer die Sektion der gerade ausgewählten Datenbank verwendet. &lt;br /&gt;
&lt;br /&gt;
Der Hauptanwendungsfall dieser Funktion, die Notwendigkeit einer Änderung des Codes bei der Migration vom Test- in das Produktiv-System oder umgekehrt zu vermeiden. Statt dessen ermittelt die Funktion, ob sie gerade im Test- oder Produktiv-System ausgeführt wird und gibt den passenden Wert (Verzeichnis-Name, URL, ...) zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Item (Ident) in der Root-Ini (die Sektion ist immer die der aktuell ausgewählten Datenbank)&lt;br /&gt;
# Vergleichswert 1&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 1 dem Wert in der Ini-Datei entspricht&lt;br /&gt;
# Vergleichswert 2&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 2 dem Wert in der Ini-Datei entspricht&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$VTRDB(prefix,test,Test-System,prod,Produktiv-System)&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$VTRDB(prefix,test,C:\temp\export\busdaten,prod,T:\files\export\busdaten)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$VTVL()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VTVL (&amp;quot;Value Translate ValueList&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu $VT werden die zu prüfenden Werte und deren Entsprechungen nicht über Parameter übergeben, sondern aus einer Werte-Liste geholt, die in einem Text gespeichert sein muss.&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich wie folgt aufbauen&lt;br /&gt;
&lt;br /&gt;
 key1=value1&lt;br /&gt;
 key2=value2&lt;br /&gt;
 key3=value3&lt;br /&gt;
 key4=value4&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich auch mit #sql_opentvl erzeugen, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Nummer des Textes, in dem sich die Werteliste befindet.&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select userid as ckey, shortname as cvalue from user_user&lt;br /&gt;
 #sql_opentvl n=1&lt;br /&gt;
 #coutl $VTVL(591,(nicht gefunden),1)&lt;br /&gt;
&lt;br /&gt;
==$XR()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $XR (&amp;quot;XmlReplace&amp;quot;) ersetzt in XML nicht zulässige Zeichen:&lt;br /&gt;
* aus &amp;amp; wird $amp ;&lt;br /&gt;
* aus &amp;lt; wird &amp;amp;lt ;&lt;br /&gt;
* aus &amp;gt; wird &amp;amp;gt ;&lt;br /&gt;
* aus &amp;quot; wird &amp;amp;quot ;&lt;br /&gt;
* aus ' wird &amp;amp;apos ;&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Das Leerzeichen vor dem Semikolon soll verhindern, dass die Zeichen hier in der Darstellung ersetzt werden und wird nicht eingefügt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text &amp;lt;firmenname&amp;gt;$XR($DATA(dat,firmenname))&amp;lt;/firmenname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==$XRR()==&lt;br /&gt;
&lt;br /&gt;
Umkehrfunktion von $XR()&lt;br /&gt;
* aus $amp ; wird &amp;amp;&lt;br /&gt;
* aus &amp;amp;lt ; wird &amp;lt;&lt;br /&gt;
* aus &amp;amp;gt ; wird &amp;gt;&lt;br /&gt;
* aus &amp;amp;quot ; wird &amp;quot;&lt;br /&gt;
* aus &amp;amp;apos ; wird '&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
=Integer-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben eine ganze Zahl zurück&lt;br /&gt;
&lt;br /&gt;
==$DEC()==&lt;br /&gt;
&lt;br /&gt;
Verringert die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die verringert werden soll.&lt;br /&gt;
# optional: Zahl, um die verringert werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$DEC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ICALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit ganzzahligen Werten durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator, es stehen zur Verfügung&lt;br /&gt;
## +&lt;br /&gt;
## -&lt;br /&gt;
## *&lt;br /&gt;
## div&lt;br /&gt;
## mod&lt;br /&gt;
# Erste Zahl&lt;br /&gt;
# Zweite Zahl&lt;br /&gt;
# optional beim Operator +: weitere Summanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$ICALC(mod,17,5)&lt;br /&gt;
&lt;br /&gt;
==$INC()==&lt;br /&gt;
&lt;br /&gt;
Erhöht die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die erhöht werden soll.&lt;br /&gt;
# optional: Zahl, um die erhöht werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$INC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$INTLEN()==&lt;br /&gt;
&lt;br /&gt;
Ist der String im Parameter eine ganz Zahl, dann wird deren Länge in Zeichen zurückgegeben, andernfalls -1; ein leerer String im ersten Parameter ergibt 0.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, deren Länge ermittelt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTLEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Länge eines Strings in Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Länge ermittelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEVENSHTEIN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Levenshtein-Distanz (https://de.wikipedia.org/wiki/Levenshtein-Distanz) der beiden übergebenen Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# erster String&lt;br /&gt;
# zweiter String&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $LEVENSHTEIN(alpha,beta)&lt;br /&gt;
&lt;br /&gt;
==$POS()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Position des Substrings in einem String. Das Funktionsergebnis ist die Position, das erste Zeichen ist 1. 0 wird zurück gegeben, wenn der Substring im String nicht vorkommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Substring (nach dem gesucht wird)&lt;br /&gt;
# String (in dem gesucht wird)&lt;br /&gt;
# optional: Wenn ic (ignore case), dann wird bei der Suche die Groß- und Kleinschreibung nicht beachtet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $POS($EDT(edt1),$VAR(1),ic) &amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert zwischen der oberen und unteren Grenze&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ&lt;br /&gt;
## int - zufällige Ganzzahl &lt;br /&gt;
## date - zufälliges Datum &lt;br /&gt;
## curr - zufällige Zahl mit zwei Nachkommastellen&lt;br /&gt;
## curr4 - zufällige Zahl mit vier Nachkommastellen&lt;br /&gt;
## text1, text2, text3... - zufällige Zeile aus dem jeweiligen Text; text ist text1; untere und obere Grenze bleiben unberücksichtigt&lt;br /&gt;
## ld - zufälliger Schlüssel-Wert aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ldv - zufälliger Text aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ls - zufälliger Schlüssel-Wert aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## lsv - zufälliger Text aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
# untere Grenze&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $RANDOM(int,1,6)&lt;br /&gt;
&lt;br /&gt;
=Datumsfunktionen=&lt;br /&gt;
&lt;br /&gt;
==$INCDATE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktione  $INCDATE() verändert das Datum im ersten Parameter um die Anzahl Tage im zweiten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das verändert werden soll&lt;br /&gt;
# optional: Die Tage, um die verändert werden soll; wenn leer, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCDATE($NOW(),-3)   clr=Y&lt;br /&gt;
&lt;br /&gt;
==$INT2TIME()==&lt;br /&gt;
&lt;br /&gt;
Macht aus z.B. 1130 die Zeit 11:30&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zeit im Integer-Format&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_time=$INT2TIME($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$NOW()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit im Format dd.mm.yyyy hh:mm:ss zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #execsql   k_datechg=$NOW()&lt;br /&gt;
&lt;br /&gt;
==$NOWFMT()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und/oder die aktuelle Uhrzeit im angegebenen Format zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Formatierungsstring (Syntax wie FormatDateTime in Delphi)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$NOWFMT(yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$NOWMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit ohne Sekunden (also dd.mm.yyyy hh:mm) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$NOWMIN()&lt;br /&gt;
&lt;br /&gt;
==$TODAY()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum im Format dd.mm.yyyy zurück.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Wenn das Datum in einem anderen Format benötigt wird, ist $NOWFMT() das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$TODAY()&lt;br /&gt;
&lt;br /&gt;
==$DFMT()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;date formated&amp;quot;) Formatiert das übergebene Datum. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, ggf. mit Uhrzeit, das formatiert werden soll.&lt;br /&gt;
# Formatierungsstring wie in Delphi&lt;br /&gt;
# optional: Wenn hn (&amp;quot;hide null&amp;quot;), dann wird ein leerer String zurück gegeben, wenn das Datum kleiner/gleich 1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$DFMT($NOW(),yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Bool'sche Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
==$BFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert einen bool'schen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'scher Wert&lt;br /&gt;
# optional: Ergebnis, wenn Wert Y ('y', 'J', 'j', '1') ist, default Y&lt;br /&gt;
# optional: Ergebnis, wenn Wert N (also nicht 'Y', 'y', 'J', 'j', '1') ist, default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cout   c=$BFMT($VAR(test),x,)&lt;br /&gt;
&lt;br /&gt;
==$BOOL()==&lt;br /&gt;
&lt;br /&gt;
Wertet das bool'sche Statement im Parameter aus.&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
* = gleich&lt;br /&gt;
* == gleich ohne Berücksichtigung der Groß- und Kleinschreibung&lt;br /&gt;
* &amp;lt;&amp;gt; ungleich&lt;br /&gt;
* != ungleich&lt;br /&gt;
* &amp;gt; größer&lt;br /&gt;
* &amp;gt;= größer gleich&lt;br /&gt;
* &amp;lt; kleiner&lt;br /&gt;
* &amp;lt;= kleiner gleich &lt;br /&gt;
* and Und-Verknüpfung&lt;br /&gt;
* or ODER-Verknüpfung&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Statements werden von links nach rechts ausgewertet, and und or sind gleichwetig, gegebenenfalls müssen Klammern eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'sches Statement, das ausgewertet wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL((17 &amp;gt; 22) or (5 &amp;gt; 3))&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL(17 &amp;gt; 22 or 5 &amp;gt; 3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATECOMP()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn Datum 2 Operator Datum 1 zutreffend ist. Ansonsten wird N zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Wird kein Operator angegeben, dann wird die Anzahl der Tage Datum 2 - Datum 1 als Zahl zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum 1&lt;br /&gt;
# Datum 2&lt;br /&gt;
# Operator&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024,&amp;lt;)&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATEMINREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMINREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEMAXREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMAXREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in ein Datum wandeln lassen, werden zu 0 (30.12.1899) konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter diesem Datum entspricht. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;Test $DATEBETWEEN($TODAY(),1.1.2020,2.2.2022)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$EMPTY()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Parameter ein leerer String ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTY($DATE(n,grpname))&lt;br /&gt;
&lt;br /&gt;
==$EMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable ein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTYVAR(buchungsnr)&lt;br /&gt;
&lt;br /&gt;
==$IN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INIC() beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die erste Anweisung gibt Y und die zweite N zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INIC()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $IN() nicht beachtet beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen geben Y zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich die Variable, deren Namen im ersten Parameter steht, in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INICVAR() beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable, die geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die erste Anweisung gibt Y und die zweite N zurück&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=beta&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INICVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich die Variable, deren Namen im ersten Parameter steht, in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INVAR() nicht beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable, die geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen geben Y zurück&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=beta&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$ISCURR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen Currency-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISCURR($DATA(n,rechnungssumme))&lt;br /&gt;
&lt;br /&gt;
==$ISDATE()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in ein Datums- oder DatumsZeit-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Prüfoperation, default ist date&lt;br /&gt;
## date - prüft, ob in ein Datum gewandelt werden kann&lt;br /&gt;
## datetime - prüft, ob in ein Datums-Zeit-Wert gewandelt werden kann&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISDATE($DATA(n,beginn))&lt;br /&gt;
&lt;br /&gt;
==$ISINT()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen ganzzahligen Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISINT($DATA(n,tage))&lt;br /&gt;
&lt;br /&gt;
==$INTMAX()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMAX($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$INTMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMIN($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$NEMPTY()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;not empty&amp;quot;) Gibt Y zurück, wenn der Parameter nicht leer ist. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalt geprüft wird. Leerzeichen gelten als leerer String.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 &lt;br /&gt;
 ~ $NEMPTY($EDT(edt1))&lt;br /&gt;
&lt;br /&gt;
==$NEMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable kein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $NEMPTYVAR(kundennr)&lt;br /&gt;
&lt;br /&gt;
==$NOT==&lt;br /&gt;
&lt;br /&gt;
Invertiert einen bool'schen Wert. Aus Y (y, J, j, 1) wird N und aus N wird Y.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der invertiert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $NOT(2)&lt;br /&gt;
&lt;br /&gt;
==$NUMBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in eine Zahl wandeln lassen, werden zu 0 konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter dieser Zahl entspricht. Siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56,)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die beiden Beispiele unterscheiden sich auf den ersten Blick kaum. Bei der ersten Zeile muss jedoch eine Schuhgröße eingegeben werden. Bleibt das Feld im VL-Segment leer, so wird dieser fehlende Wert nach 0 konvertiert und liegt nicht zwischen 28 und 56.&lt;br /&gt;
&lt;br /&gt;
Anders bei der zweiten Zeile: Das Komma vor der schließenden Klammer sorgt für einen vierten Parameter, der ebenfalls leer ist und damit nach 0 gewandelt wird. Auf diese Weise werden die leere Eingaben (und die Eingabe von 0) gültig.&lt;br /&gt;
&lt;br /&gt;
==$REGEX()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $REGEX() (&amp;quot;regular expressions&amp;quot;) prüft, ob der String in Parameter 1 den Anforderungen von Parameter 2 entspricht (Ergebnis Y) oder nicht (Ergebnis N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft werden soll&lt;br /&gt;
# Regulärer Ausdruck, mit dem der String in Parameter 2 geprüft wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $REGEX($VAR(med),^[A-Z]{3}$)&lt;br /&gt;
&lt;br /&gt;
==$TEXT_HASLINE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $TEXT_HASLINE() prüft, ob die als Parameter 2 übergebene Textzeile in einem Text vorkommt. Es wird nur auf komplette Textzeilen geprüft. Wird zum Beispiel verwendet, um eine Liste von Kundennummern zu erstellen, und dann auf einzelne Nummern zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# Textzeile, deren Vorkommen geprüft wird&lt;br /&gt;
# Ergebnis, wenn die Textzeile vorkommt; default Y&lt;br /&gt;
# Ergebnis, wenn die Textzeile nicht vorkommt; default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $TEXT_HASLINE(1,990000018,1,0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$VIBAN()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VIBAN() (&amp;quot;validate IBAN&amp;quot;) prüft eine IBAN anhand der Prüfziffern (3. und 4. Stelle).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# IBAN, die geprüft werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VIBAN(DE12345)&lt;br /&gt;
&lt;br /&gt;
=Currency-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==$CCALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit Festkommawerten durch&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
** + - Addition&lt;br /&gt;
** - - Subtraktion&lt;br /&gt;
** * - Multiplikation&lt;br /&gt;
** / - Division&lt;br /&gt;
** % - Division und Multiplikation des Ergebnisses mit 100&lt;br /&gt;
** +4 - Addition und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** -4 - Subtraktion und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** *4 - Multiplikation und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** /4 - Division und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** %4 - Division, Multiplikation des Ergebnisses mit 100 und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
** B, b, B4, b4 - Bruttobetrag, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** E, e, E4, e4 - Enthaltene MWSt, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** M, m, M4, m4 - MWSt, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** N, n, N4, n4 - Nettobetrag, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator&lt;br /&gt;
# und weitere: Operanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 10&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(+,1,2,3,4)&amp;quot;&lt;br /&gt;
 -- Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #val_set   n=1   z=1038,87&lt;br /&gt;
 #coutl $CCALC(N,$VAL(1),19)  -  $CCALC(E,$VAL(1),19)  -&lt;br /&gt;
&lt;br /&gt;
==$CURR()==&lt;br /&gt;
&lt;br /&gt;
Currency-Werte müssen in Funktionen mit einem Punkt als Dezimaltrennzeichen eingegeben werden, da das Komma die Parameter trennt. Sofern Konstanten verwendet werden, lässt sich das einfach so eingeben, sobald aber die Werte aus anderen Funktionen kommen (zum Beispiel $DATA()), müssen sie dann mit $CURR() in dieses Format umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Vorkommastellen&lt;br /&gt;
# Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 43,48&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,$CURR(2,3))&amp;quot;&lt;br /&gt;
 -- zum Vergleich; Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert Curreny-Werte&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert&lt;br /&gt;
# optional: Formatierungsstring, default 0.00&lt;br /&gt;
# optional: wenn hn (&amp;quot;hide null&amp;quot;), dann werden leere Strings als Wert auch als leerer String ausgegeben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=###,###,###,##0.00&lt;br /&gt;
 #val_set   n=2   z=1337,42&lt;br /&gt;
 #cout   c=$CFMT($VAL(2),$VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ONLYNUM()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass in einem String nur Zahlen (ggf. auch Kommas oder Punkte) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl&lt;br /&gt;
# Art der Operation; default numkomma&lt;br /&gt;
## flnnc (&amp;quot;from last not numeric character&amp;quot;) - Ab dem letzten Zeichen, das keine Ziffer ist&lt;br /&gt;
## num - Nur Ziffern, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numkomma - Nur Ziffern und Kommata, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numpoint - Nur Ziffern und Punkte, alle anderen Zeichen werden entfernt&lt;br /&gt;
## ufnnc (&amp;quot;until first not numeric character&amp;quot;) - vom Anfang bis zum ersten Zeichen, das keine Ziffer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 -- Ergebnis 123456&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,num)&lt;br /&gt;
 -- Ergebnis 123&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,ufnnc)&lt;br /&gt;
 -- Ergebnis 456 &lt;br /&gt;
 #coutl   $ONLYNUM(123-456,flnnc)&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Interpreter&amp;diff=22562</id>
		<title>Interpreter</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Interpreter&amp;diff=22562"/>
		<updated>2026-05-06T09:09:00Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #tab_new */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Im Interpreter sind nur wenige Prozeduren und Funktionen direkt implementiert. Die meisten Routinen finden sich in den Modulen.&lt;br /&gt;
&lt;br /&gt;
=Values=&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Variablen ist der Gültigkeitsbereich von Values auf das jeweilige (Primär- oder Sub-) Kommando beschränkt. Values haben Nummern, während Variable Namen haben.&lt;br /&gt;
&lt;br /&gt;
==#val_set==&lt;br /&gt;
&lt;br /&gt;
Setzt der Wert für einen Value.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Der Value wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie (if empty) - Wenn der Wert von z leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei Oracle; Funktionen werden ersetzt&lt;br /&gt;
*n - Nummer des Values&lt;br /&gt;
*r (rights) - Der Value wird nur dann gesetzt, wenn das Recht vorliegt; default ist ''frm''&lt;br /&gt;
*rf (replace functions) - Wenn Y, dann werden nach der Zuweisung auf den Value nochmals die Funktionen ersetzt. Wird zum Beispiel benötigt, wenn Code mit Funktionen mittels $DATA() aus der Datenbank geladen wird; Funktionen werden ersetzt, default N; siehe Beispiel&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=7   z=$GUID()&lt;br /&gt;
 #val_set   n=1   z=$GUID()   r=admin&lt;br /&gt;
&lt;br /&gt;
 -- Zum Parameter rf: $NOW() in die Zwischenablage kopieren und dann ausführen&lt;br /&gt;
 #val_set   n=1  z=$CLIPBOARD()   rf=N&lt;br /&gt;
 #message   c=$VAL(1)&lt;br /&gt;
 #val_set   n=1  z=$CLIPBOARD()   rf=Y&lt;br /&gt;
 #message   c=$VAL(1)&lt;br /&gt;
&lt;br /&gt;
==#val_add==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#val_add fügt einem Value einen Wert hinzu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Der Value wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*n - Nummer des Values; zwingend erforderlich&lt;br /&gt;
*r (rights) - Der Value wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. &lt;br /&gt;
* y -Typ der Operation; default ''text''&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
*z - Wert, welcher dem Value hinzugefügt wird, Funktionen werden ersetzt, default ist ein leerer String oder eine 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=$NOW()&lt;br /&gt;
 #val_add   n=1   z=1   y=datetime&lt;br /&gt;
 #cout   c=$VAL(1)&lt;br /&gt;
&lt;br /&gt;
==#val_clearall==&lt;br /&gt;
&lt;br /&gt;
Löscht alle Values. Wird selten benötigt, da die Values mit Ende des (Primär- oder Sub-) Kommandos ohnehin ihre Gültigkeit verlieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_clearall&lt;br /&gt;
&lt;br /&gt;
==$VAL()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Inhalt eines Values zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Values&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout c=$VAL(3)&lt;br /&gt;
&lt;br /&gt;
==$EMPTYVAL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Value ein leerer String ist, dessen Nummer im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Values&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTYVAL(1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$NEMPTYVAL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Value kein leerer String ist, dessen Nummer im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Values&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $NEMPTYVAL(2)&lt;br /&gt;
&lt;br /&gt;
=Log=&lt;br /&gt;
&lt;br /&gt;
==#exception_info==&lt;br /&gt;
&lt;br /&gt;
Tritt eine Exception auf, dann wird die entsprechende Fehlermeldung in das Log geschrieben. Mit #exception_info kann eine Information ergänzt werden, die vor diese Fehlermeldung gesetzt wird. Üblicherweise wird das dazu verwendet, um eine ID zu schreiben, damit der fehlerhafte Datensatz gefunden wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* z - Wert, welcher vor die Fehlermeldung geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #exception_info   z=$DATA(dat,knd_nr)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==#log==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Text in das Log.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der in das Log geschrieben wird; Funktionen werden ersetzt; default ist ''#log, Parameter c nicht gesetzt''&lt;br /&gt;
* y - Typ des Log-Eintrags; default I. Vorgesehen sind die folgenden Typen:&lt;br /&gt;
** E - Error&lt;br /&gt;
** I - Info&lt;br /&gt;
** W - Warning&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #log   y=W   c=&amp;quot;Ermittelte Summe untypisch gering&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#logi==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Text als Info in das Log.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #logi hat keine benannten Parameter. Der komplette Text nach dem #logi und dem folgenden Leerzeichen wird in das Log geschrieben; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #logi   Berechnung beendet&lt;br /&gt;
&lt;br /&gt;
=Kommandos=&lt;br /&gt;
&lt;br /&gt;
==#tab_new==&lt;br /&gt;
&lt;br /&gt;
Öffnet einen neuen Tab im BAF-Client und führt dort ein Kommando aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des neuen Tabs; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das im neuen Tab ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* debug - Wenn Y, wird für den neuen Tab das Debug-Log aktiviert; Default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tab_new   c=xuser   cmd=xuser($PAGE(link))&lt;br /&gt;
&lt;br /&gt;
==#code_open==&lt;br /&gt;
&lt;br /&gt;
Öffnet den Code-Dialog und geht zum entsprechenden Kommando&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das im Code-Dialog selektiert wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_btn   c=&amp;quot;Direkt zum Code&amp;quot;   w=130   cmd=&amp;quot;#code_open   cmd=$PVAL(vl,cmd)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;command parameter&amp;quot;) - Greift auf einen Parameter des Kommandos zu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Parameters. 0-relativ, der erste Parameter hat somit die Nummer 0.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_fill  d=$CP(1)&lt;br /&gt;
&lt;br /&gt;
==$ICP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;is command parameter&amp;quot;) - Vergleicht den Parameter des Kommandos mit dem im zweiten oder weiteren Parameter angegebenen Wert; Unterschiede in Groß- und Kleinschreibung werden dabei nicht berücksichtigt. Gibt Y zurück, wenn der Parameter mit einem der Vergleichswerte übereinstimmt.&lt;br /&gt;
&lt;br /&gt;
Wird fast immer in Verbindung mit Verzweigungsbedingungen verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Parameters. 0-relativ, der erste Parameter hat somit die Nummer 0.&lt;br /&gt;
# und Folgende: Vergleichswerte&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $ICP(0,ex)&lt;br /&gt;
 ~ $ICP(0,ex,im,new)&lt;br /&gt;
&lt;br /&gt;
==$INCP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;is not command parameter&amp;quot;) - Vergleicht den Parameter des Kommandos mit dem im zweiten oder weiteren Parameter angegebenen Wert; Unterschiede in Groß- und Kleinschreibung werden dabei nicht berücksichtigt. Gibt Y zurück, wenn der Parameter mit keinem der Vergleichswerte übereinstimmt.&lt;br /&gt;
&lt;br /&gt;
Wird fast immer in Verbindung mit Verzweigungsbedingungen verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Parameters. 0-relativ, der erste Parameter hat somit die Nummer 0.&lt;br /&gt;
# und Folgende: Vergleichswerte&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INCP(0,ex)&lt;br /&gt;
 ~ $INCP(0,ex,im,new)&lt;br /&gt;
&lt;br /&gt;
=Internes=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen werden für interne Zwecke verwendet:&lt;br /&gt;
&lt;br /&gt;
* $INTER() - Name des Interpreters&lt;br /&gt;
* $HISTSQL() - SQL-Statement für den History-Dialog&lt;br /&gt;
* $HISTTABLE() - Tabellenname der History-Tabelle&lt;br /&gt;
* $HISTMEMOFIELD() - Feldname des Memo-Feldes für den History-Dialog&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Archiv&amp;diff=22561</id>
		<title>Archiv</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Archiv&amp;diff=22561"/>
		<updated>2026-01-11T12:09:07Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* 31.12.2023 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===30.06.2024===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 1.01]]&lt;br /&gt;
&lt;br /&gt;
===31.12.2023===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 1.00]]&lt;br /&gt;
* Youtube-Video: [https://www.youtube.com/watch?v=tCAL7MmKO6c| Version 1.00 (19:24)]&lt;br /&gt;
&lt;br /&gt;
===23.7.2023===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.99]]&lt;br /&gt;
&lt;br /&gt;
===26.03.2023===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.98]]&lt;br /&gt;
&lt;br /&gt;
===26.02.2023===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.97]]&lt;br /&gt;
* [https://www.youtube.com/watch?v=HKDW09g7ikc| Video Version 0.97 (5:51)]&lt;br /&gt;
&lt;br /&gt;
===29.01.2023===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.96]]&lt;br /&gt;
&lt;br /&gt;
===31.12.2022===&lt;br /&gt;
*[[beispiele_rest_json|Neues Beispiel: Daten von einem REST-Server holen, anzeigen und bearbeiten (längeres Tutorial)]]&lt;br /&gt;
&lt;br /&gt;
===24.12.2022===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.95]]&lt;br /&gt;
&lt;br /&gt;
===03.12.2022===&lt;br /&gt;
&lt;br /&gt;
* Video [https://youtu.be/gdUh9S_KEAQ| BIC ergänzen (10:11)]&lt;br /&gt;
* Video [https://youtu.be/XenPgo0OTn8| Version 0.91 (4:45)]&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.91]]&lt;br /&gt;
&lt;br /&gt;
===27.11.2022===&lt;br /&gt;
&lt;br /&gt;
* Video [https://www.youtube.com/watch?v=95NUxGX6R1k| BAF-Server einrichten (13:01)]&lt;br /&gt;
* [[Versionen_Server| Erste Version: BAF-Server 0.1 / SerProc 0.9]]&lt;br /&gt;
&lt;br /&gt;
===26.11.2022===&lt;br /&gt;
&lt;br /&gt;
* Video [https://www.youtube.com/watch?v=iarhXOJJVuA| Version 0.9 (7:28)]&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.9]]&lt;br /&gt;
&lt;br /&gt;
===25.11.2022===&lt;br /&gt;
&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=6_Ngk-EJmuY| Threads (8:53)]&lt;br /&gt;
&lt;br /&gt;
===19.11.2022===&lt;br /&gt;
&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=u7JVPvnB0es| Dialoge erstellen (15:53)]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=5yXkC2B0jQM| Länderkürzel anlegen (11:32)]&lt;br /&gt;
&lt;br /&gt;
===19.11.2022===&lt;br /&gt;
&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=tUtmq1l11ls| Version 0.8 (13:54)]&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.8]]&lt;br /&gt;
&lt;br /&gt;
===13.11.2022===&lt;br /&gt;
&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=iJxdU6A9NrE| User und Rechte (21:49)]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=c1NYgMhP1F8| User importieren (28:11)]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=PrENFgNIwpY| Testdaten und $RANDOM (16:14)]&lt;br /&gt;
&lt;br /&gt;
===12.11.2022===&lt;br /&gt;
&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=P8aK_vkmlcI| Text (10:51)]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=cWvvcC8QVZo| INI verwenden (4:11)]&lt;br /&gt;
&lt;br /&gt;
===29.10.2022===&lt;br /&gt;
&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=_HGqS9_R_Xc| xsql - ein simples SQL-Tool (21:29)]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=83sqJmoC068| Zusaätzliche Datenbank einbinden (5:35)]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=u-71YXZlcRk| Variable und Values (9.30)]&lt;br /&gt;
&lt;br /&gt;
===23.10.2022===&lt;br /&gt;
&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.7]]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=St3fj1WB098| Die Sprache BAL (7:20)]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=R2ceP0UYgoY| PDFs erstellen (8:11)]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=RDJBGeG1xsA| BAF-Client 0.7 (3:21)]&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Hauptseite&amp;diff=22560</id>
		<title>Hauptseite</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Hauptseite&amp;diff=22560"/>
		<updated>2026-01-11T12:08:55Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* Aktuelles */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=BAF/BAL=&lt;br /&gt;
&lt;br /&gt;
BAF steht für ''Business Applications Framework''&lt;br /&gt;
&lt;br /&gt;
BAL steht für ''Business Applications Language''&lt;br /&gt;
&lt;br /&gt;
==Aktuelles==&lt;br /&gt;
&lt;br /&gt;
===11.01.2026===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 1.04]]&lt;br /&gt;
&lt;br /&gt;
===13.07.2025===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 1.03]]&lt;br /&gt;
&lt;br /&gt;
===25.12.2024===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 1.02]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Archiv]]&lt;br /&gt;
&lt;br /&gt;
==Was ?==&lt;br /&gt;
&lt;br /&gt;
BAF ist eine Framework zur schnellen Entwicklung von Datenbankanwendungen im Business-Umfeld.&lt;br /&gt;
&lt;br /&gt;
==Warum?==&lt;br /&gt;
&lt;br /&gt;
Kurzfassung: Für schnelle Entwicklung&lt;br /&gt;
&lt;br /&gt;
[[Gruende|Langfassung: Gründe für die Entwiklung von BAF/BAL]]&lt;br /&gt;
&lt;br /&gt;
==Wo ?==&lt;br /&gt;
&lt;br /&gt;
[[Versionen|BAF-Client Download-Seite]]&lt;br /&gt;
&lt;br /&gt;
[[Videos|Videos]]&lt;br /&gt;
&lt;br /&gt;
==Lizenz==&lt;br /&gt;
&lt;br /&gt;
Das Framework steht unter der [[bful|BAF fair use license]], einer unkomplizierten OpenSource-Lizenz.&lt;br /&gt;
&lt;br /&gt;
==BAF Client==&lt;br /&gt;
&lt;br /&gt;
Der BAF-Client ist sowohl IDE als auch Benutzeroberfläche für den Endanwender.&lt;br /&gt;
&lt;br /&gt;
*[[BC_Login|Der Login-Dialog]]&lt;br /&gt;
*[[BC_Programmfenster|Programmfenster]]&lt;br /&gt;
*[[BC_Typisch|typisches Formular]]&lt;br /&gt;
*[[BC_Code_|Code]]&lt;br /&gt;
*[[BC_SGWizard|Code - Simple Grid Wizard]]&lt;br /&gt;
*[[BC_SqlOpen|Code - SQL Open / SQL Open 2]]&lt;br /&gt;
*[[BC_SqlExec|Code - SQL Exec]]&lt;br /&gt;
*[[BC_Tools|Code - Tools]]&lt;br /&gt;
*[[BC_Lists|Code - Lists]]&lt;br /&gt;
*[[BC_Debug|Debug]]&lt;br /&gt;
*[[BC_Migration|Migration]]&lt;br /&gt;
&lt;br /&gt;
==BAF Server==&lt;br /&gt;
&lt;br /&gt;
[[Versionen_Server|BAF-Server Download-Seite]]&lt;br /&gt;
&lt;br /&gt;
[[Videos|Videos]]&lt;br /&gt;
&lt;br /&gt;
==Datenbanken==&lt;br /&gt;
&lt;br /&gt;
*[[BafClientFmIni|Datenbanken einbinden mit der BafClientFM.ini]]&lt;br /&gt;
*[[DbBesonderheiten|Besonderheiten der unterstützten Datenbanksysteme]]&lt;br /&gt;
&lt;br /&gt;
==Sprache und Bibliotheken==&lt;br /&gt;
&lt;br /&gt;
*[[BAL|Die Sprache BAL]]&lt;br /&gt;
*[[Interpreter|Interpreter]]&lt;br /&gt;
*[[Modul VAR neu|Modul VAR]]&lt;br /&gt;
*[[Modul DB|Modul DB]]&lt;br /&gt;
*[[Modul Form|Modul Form]]&lt;br /&gt;
*[[Modul Translation|Modul Translation]]&lt;br /&gt;
*[[Modul Web|Modul Web]]&lt;br /&gt;
*[[Modul XML|Modul XML]]&lt;br /&gt;
*[[Modul JSON|Modul JSON]]&lt;br /&gt;
*[[Modul PDF|Modul PDF]]&lt;br /&gt;
*[[Modul XLS|Modul XLS]]&lt;br /&gt;
*[[beispiele|Beispiele]]&lt;br /&gt;
&lt;br /&gt;
==Die Standard-Module==&lt;br /&gt;
&lt;br /&gt;
Mit den Standard-Modulen werden die Standard-Aufgaben in einer Datenbankanwendung abgedeckt.&lt;br /&gt;
&lt;br /&gt;
*[[xuser|xuser - Benutzerverwaltung]]&lt;br /&gt;
*[[xlookup|xlookup - Nachschlagelisten]]&lt;br /&gt;
*[[xspecial|xspecial - Nachschlagelisten aus SQL-Abfragen]]&lt;br /&gt;
*[[xdevtext|xdevtext - Entwicklertexte]]&lt;br /&gt;
*[[xmenu|xmenu - Das Menü]]&lt;br /&gt;
*[[xtranslation|xtranslation - Übersetzung]]&lt;br /&gt;
*[[xsettings|xsettings - Benutzereinstellungen]]&lt;br /&gt;
*[[xtodo|xtodo - Aufgabenliste]]&lt;br /&gt;
&lt;br /&gt;
==[[Impressum|Impressum]]==&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Versionen_Server&amp;diff=22559</id>
		<title>Versionen Server</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Versionen_Server&amp;diff=22559"/>
		<updated>2026-01-11T12:08:19Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* BAF-Server 0.1 mit SrvProc 1.03 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=BAF-Server Download=&lt;br /&gt;
&lt;br /&gt;
* Einfach die ZIP-Datei entpacken &lt;br /&gt;
* Datenbank in der Ini passend zum Client einrichten&lt;br /&gt;
* Tabellen und xserver im BAF-Client ergänzen&lt;br /&gt;
* Den BAF-Server einfach mit der Datei pBafServer.exe starten&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Video [https://www.youtube.com/watch?v=95NUxGX6R1k| BAF-Server einrichten (13:01)]&lt;br /&gt;
&lt;br /&gt;
==BAF-Server 0.1 mit SrvProc 1.04==&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_04.zip, 26.427 KB)[[https://bafbal.de/downloads/bs_v1_04.zip]]&lt;br /&gt;
&lt;br /&gt;
==BAF-Server 0.1 mit SrvProc 1.03==&lt;br /&gt;
&lt;br /&gt;
Download (bs_v1_03.zip, 26.420 KB)[[https://bafbal.de/downloads/bs_v1_03.zip]]&lt;br /&gt;
&lt;br /&gt;
==BAF-Server 0.1 mit SrvProc 1.02==&lt;br /&gt;
&lt;br /&gt;
Download (bs_v1_02.zip, 25.071 KB)[[https://bafbal.de/downloads/bs_v1_02.zip]]&lt;br /&gt;
&lt;br /&gt;
==BAF-Server 0.1 mit SrvProc 0.98==&lt;br /&gt;
&lt;br /&gt;
Download (bs_v0_98.zip, 24.577 KB)[[https://bafbal.de/downloads/bs_v0_98.zip]]&lt;br /&gt;
&lt;br /&gt;
==BAF-Server 0.1 mit SrvProc 0.97==&lt;br /&gt;
&lt;br /&gt;
Download (bs_v0_97.zip, 24.572 KB)[[https://bafbal.de/downloads/bs_v0_97.zip]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==BAF-Server 0.1 mit SrvProc 0.96==&lt;br /&gt;
&lt;br /&gt;
Download (bs_v0_96.zip, 24.569 KB)[[https://bafbal.de/downloads/bs_v0_96.zip]]&lt;br /&gt;
&lt;br /&gt;
==BAF-Server 0.1 mit SrvProc 0.95==&lt;br /&gt;
&lt;br /&gt;
Download (bs_v0_95.zip, 24.518 KB)[[https://bafbal.de/downloads/bs_v0_95.zip]]&lt;br /&gt;
&lt;br /&gt;
==BAF-Server 0.1 mit SrvProc 0.9==&lt;br /&gt;
&lt;br /&gt;
Download (bs_v0_9.zip, 24,5 MB)[[https://bafbal.de/downloads/bs_v0_9.zip]]&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Versionen&amp;diff=22558</id>
		<title>Versionen</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Versionen&amp;diff=22558"/>
		<updated>2026-01-11T12:07:30Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* Version 1.04 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=BAF-Client Download=&lt;br /&gt;
&lt;br /&gt;
* Einfach die ZIP-Datei entpacken und dann erst mal die beiliegenden Fonts installieren (recht Maustaste, &amp;quot;Installieren&amp;quot;)&lt;br /&gt;
* Den BAF-Client einfach mit der Datei BafCLientFM.exe starten&lt;br /&gt;
* Username und Passwort (admin/admin) kommen aus der Ini-Datei. Vor dem Produktivbetrieb das Passwort dort löschen und in der Userverwaltung abändern.&lt;br /&gt;
&lt;br /&gt;
==Version 1.04==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren sowie wesentliche Parameterergänzungen. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Var: #exec_async, $VTRDB()&lt;br /&gt;
* DB: #sql_openkvl&lt;br /&gt;
* Form: #grd_lookupliveclear&lt;br /&gt;
* XML: $XML_VALEX()&lt;br /&gt;
* XLS: #xls_delete_sheet&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_04.zip, 25.971 KB)[[https://bafbal.de/downloads/bc3_v1_04.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_04.zip, 26.427 KB)[[https://bafbal.de/downloads/bs_v1_04.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.03==&lt;br /&gt;
 		 	&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren sowie wesentliche Parameterergänzungen. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
 		 	&lt;br /&gt;
* Die Suche kann nun auf die Kommandos in den Favoriten beschränkt werden.&lt;br /&gt;
* Int: $EMPTYVAL(), $NEMPTYVAL()&lt;br /&gt;
* Var: $CONVERT(), $DATECOMP(), $EMPTYVAR(), $NEMPTYVAR()&lt;br /&gt;
* DB: #sql_openval hat nun die Parameter af und de&lt;br /&gt;
* Form: #tree_node hat nun den Parameter iek, $GRD_REGEX(), S-Grid (#sgrd_seg, #sgrd_node, #sgrd_hf, #sgrd_data), #grd_data kennt nun auch q=text&lt;br /&gt;
* Web: #email_init hat nun den Parameter sasl, #email_send hat nun den Parameter fn_list&lt;br /&gt;
* JSON: $JSON_ARRAY_VALUE(), $JSON_LFR()&lt;br /&gt;
* PDF: #pdf_text hat nun den Parameter d&lt;br /&gt;
 &lt;br /&gt;
Download Client (bc3_v1_03.zip, 25.880 KB)[[https://bafbal.de/downloads/bc3_v1_03.zip]]&lt;br /&gt;
 &lt;br /&gt;
Download Server (bs_v1_03.zip, 26.420 KB)[[https://bafbal.de/downloads/bs_v1_03.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.02==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Var: #file_wait, $BFMT(), $CFMT()&lt;br /&gt;
* Form: #dlg, #dlg_close&lt;br /&gt;
* XML: $XML_VALEX()&lt;br /&gt;
* Code-Dialog: Es wurde die Seite ''Fav'' und die entsprechende Checkbox auf der Seite ''Code'' hinzugefügt. Um dies nutzen zu können, muss die folgende Tabelle existieren:&lt;br /&gt;
&lt;br /&gt;
 create table sys_userfav(&lt;br /&gt;
   name varchar(80) not null,&lt;br /&gt;
   user_user_id varchar(40) not null&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_02.zip, 23.627 KB)[[https://bafbal.de/downloads/bc3_v1_02.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_02.zip, 25.071 KB)[[https://bafbal.de/downloads/bs_v1_02.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.01==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Interpreter: Funktion $INCP() ergänzt (if not command parameter)&lt;br /&gt;
* DB: #sql_upsert2 (gibt es den Datensatz noch nicht, wird er angelegt, haben sich die Daten geändert, werden sie geschrieben)&lt;br /&gt;
* Form: $DLG_YESNO() (Dialog mit Yes/No)&lt;br /&gt;
* Form: #tree_clearnode (Entfernt einen Zweig, damit er neu aufgebaut werden kann)&lt;br /&gt;
* Form: #grd_dub (ermittelt Dubletten in einem Grid)&lt;br /&gt;
* XML: $XML_DATATEXT (ermittelt ein XML in einer Schleife)&lt;br /&gt;
* XML: $XML_LFR (loop first regex)&lt;br /&gt;
* XLS: #xls_load (öffnet eine XLS-Datei)&lt;br /&gt;
* XLS: #xls_looprows (loop über die Zeilen einer XLS-Datei)&lt;br /&gt;
* XLS: $XLS_COUNT() (ermittelt die Anzahl von Sheets, Zeilen oder Zellen)&lt;br /&gt;
* XLS: $XLS_CELL() (Gibt der Wert einer Zelle aus)&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_01.zip, 23.620 KB)[[https://bafbal.de/downloads/bc3_v1_01.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_01.zip, 25.067 KB)[[https://bafbal.de/downloads/bs_v1_01.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.00==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Im Code-Dialog wurde die Seite ''Open SQL'' überarbeitet und auf drei solche Seiten erweitert&lt;br /&gt;
*[[Modul_VAR_neu#.23csv_check|#csv_check]] Prüft eine CSV-Datei&lt;br /&gt;
*[[Modul_VAR_neu#.24CSV_LINE.28.29|$CSV_LINE()]] Gibt eine ganze Zeile einer CSV-Datei zurück &lt;br /&gt;
*[[Modul_VAR_neu#.23tvl_add|#tvl_add]] Addiert einem Wert in einer Text-Value-Liste einen Wert hinzu &lt;br /&gt;
*[[Modul_VAR_neu#.23exit|#exit]] Bricht die Ausführung eines (Sub-)Kommandos ab&lt;br /&gt;
*[[Modul_VAR_neu#.24STROP.28.29|$STROP()]] Verschiedene String-Bearbeitungen wie Trim, Quote oder Unquote&lt;br /&gt;
*[[Modul_Form#.24CCI.28.29|$CCI()]] Ermittelt die zu setzende Zellen-Farbe&lt;br /&gt;
*[[Modul_Form#.23grd_sort|#grd_sort]] Sortiert ein Grid&lt;br /&gt;
*[[Modul_Form#.23grd_pos|#grd_pos]] Ermittelt das erste Vorkommen einer Zeile, deren Zelleninhalte den Kriterien entsprechen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_00.zip, 23.476 KB)[[https://bafbal.de/downloads/bc3_v1_00.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_00.zip, 25.040 KB)[[https://bafbal.de/downloads/bs_v1_00.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.99==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Vereinzelt wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier meist nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
*[[Modul_VAR_neu#.23text_act|#text_act]] Bearbeitet einen Text&lt;br /&gt;
*[[Modul_VAR_neu#.24FILEINFO.28.29|$FILEINFO()]] Liefert Infos zu einer Datei&lt;br /&gt;
*[[Modul_VAR_neu#.23zip_create|#zip_create]] Erzeugt eine ZIP-Datei&lt;br /&gt;
*[[Modul_VAR_neu#.24LEVENSHTEIN.28.29|$LEVENSHTEIN()]] Ermittelt die Levensthein-Distanz (Größe bei einem String-Vergleich)&lt;br /&gt;
*[[Modul_VAR_neu#.24RANDOM.28.29_2|$RANDOM()]] Erzeugt eine Zufalls-Zahl&lt;br /&gt;
* Bei Konsolen-Programmen kann nun auf den Bestätigungsdialog verzichtet werden, siehe [[Modul_Form#.23frm|#frm]]&lt;br /&gt;
* Bei [[Modul_Form#.23tree_sel|#tree_sel]] können nun auch Unterknoten durchsucht werden.&lt;br /&gt;
*[[Modul_Form#.23tree_fillthread|#tree_fillthread]] - Ergänzt den Baum in einem Thread (meist, um Daten aus einer Datenbank zu ergänzen)&lt;br /&gt;
*[[Modul_Form#.23vl_thread|#vl_thread]] Ergänzt die Daten in einem VL-Segment (meist, um Daten aus einer Datenbank zu ergänzen)&lt;br /&gt;
*[[Modul_Form#.23xgrd_calc|#xgrd_calc]] Berechnet einen Wert in einem XGrid-Segment&lt;br /&gt;
*[[Modul_Form#.24XGRD_CALC|$XGRD_CALC()]] Berechnet einen Wert in einem XGrid-Segment, aber als Funktion&lt;br /&gt;
*[[Modul_Form#XXGrid-Segmente|XX-Grid-Segmente]] (mehrere Prozeduren)&lt;br /&gt;
*[[Modul_XML#.23xml_gav|#xml_gav]] Holt die Array-Werte aus einem XML&lt;br /&gt;
* In [[Modul_JSON#.24JSON_DATA|$JSON_DATA()]] können nun auch Namen ausgelesen werden&lt;br /&gt;
* In [[Modul_XLS#.23xls_cell|#xls_cell]] kann nun auch die vertikale Ausrichtung in einer Zelle spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_99.zip, 23.345 KB)[[https://bafbal.de/downloads/bc3_v0_99.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_99.zip, 24.935 KB)[[https://bafbal.de/downloads/bs_v0_99.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.98==&lt;br /&gt;
&lt;br /&gt;
* Im GridWizard funktioniert nun der Hint der Spaltenüberschriften&lt;br /&gt;
* Links funktionieren nun im VL-Segment&lt;br /&gt;
* #tree_sel erweitert&lt;br /&gt;
* #sql_opentvl&lt;br /&gt;
* #sql_line &lt;br /&gt;
* Lookups, Specials und Kommandos cachen nun&lt;br /&gt;
* XGrid und XXGrid stretchen nun&lt;br /&gt;
* grd_thread y=gridlist&lt;br /&gt;
* #grd_seg und #vl_seg - whs&lt;br /&gt;
* Werte werden nun nur vom Grid in den Baum zurück geschrieben, wenn sie tatsächlich geändert wurden&lt;br /&gt;
* #tree_fillthread&lt;br /&gt;
* Prozessabbruch beim Fortschrittsdialog wird nun resettet&lt;br /&gt;
* cmd no_crlf&lt;br /&gt;
* Verbesserung von dateMin und dateSek&lt;br /&gt;
* $INCP&lt;br /&gt;
* Pos1 und End im Grid&lt;br /&gt;
* Wizzard für csv und xlsx&lt;br /&gt;
* Beim Debug-Fenster Select werden nun nicht mehr die Selects angezeigt, die Commands holen&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_98.zip, 20.246 KB)[[https://bafbal.de/downloads/bc3_v0_98.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_98.zip, 24.577 KB)[[https://bafbal.de/downloads/bs_v0_98.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.97==&lt;br /&gt;
&lt;br /&gt;
* #grd_ac ergänzt&lt;br /&gt;
* $INCLUDE() ergänzt&lt;br /&gt;
* $ONLYNUM() ergänzt&lt;br /&gt;
* Fehler beim Parsen von XML behoben&lt;br /&gt;
* UserIni wird nun beim ServerProzess beim Ende gespeichert&lt;br /&gt;
* Cursor beim Login-Dialog&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_97.zip, 20.236 KB)[[https://bafbal.de/downloads/bc3_v0_97.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_97.zip, 24.572 KB)[[https://bafbal.de/downloads/bs_v0_97.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.96==&lt;br /&gt;
&lt;br /&gt;
* TBafTree Scrollbar bei langen Listen gleich&lt;br /&gt;
* #ftp_connect Parameter isc&lt;br /&gt;
* #email_init Parameter port, isc und to&lt;br /&gt;
* Menu scrollt nun richtig&lt;br /&gt;
* PDF Grid (#pdf_gdef, #pdf_grow, #pdf_gend)&lt;br /&gt;
* #upsert, y=c und n&lt;br /&gt;
* Performance Log&lt;br /&gt;
* Debug, Request and Response&lt;br /&gt;
* History Statement bei anderen DB&lt;br /&gt;
* PG, AlterTable, AlterHistory, Leerzeilen in CREATE TABLE kein Problem mehr bei Funktionen&lt;br /&gt;
* Vorbelegung Username aus INI beim Login-Dialog&lt;br /&gt;
* Baum kann mit Tasten gesteuert werden&lt;br /&gt;
* Page, kleinere Bugs behoben, TAB nun auch bei VL-Segment&lt;br /&gt;
* $ISDATE ergänzt&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_96.zip, 20.232 KB)[[https://bafbal.de/downloads/bc3_v0_96.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_96.zip, 24.569 KB)[[https://bafbal.de/downloads/bs_v0_96.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.95==&lt;br /&gt;
&lt;br /&gt;
* REST und JSON&lt;br /&gt;
* Bilder&lt;br /&gt;
* ein wenig XML&lt;br /&gt;
* tvl bei Nachschlagelisten&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_95.zip, 24.541 KB)[[https://bafbal.de/downloads/bc3_v0_95.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_95.zip, 24.518 KB)[[https://bafbal.de/downloads/bs_v0_95.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.91==&lt;br /&gt;
&lt;br /&gt;
* TBafTree&lt;br /&gt;
* uServer und uServer2&lt;br /&gt;
* Parameter isc bei #http_request&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_91.zip, 19,7 MB)[[https://bafbal.de/downloads/bc3_v0_91.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.9==&lt;br /&gt;
&lt;br /&gt;
* Werden Texte in Nachschlagelisten geladen, werden nun Funktionen (z.B. Übersetzungen) ersetzt&lt;br /&gt;
* Werden nach einer Änderung im Tree Werte in den Baum zurückgeschrieben, wird nicht nur - wie bisher - c1 und c2 geschrieben, sondern auch k. Zudem werden nun Funktionen ersetzt&lt;br /&gt;
* Wurde bei VL-Wizard nachgebessert&lt;br /&gt;
* lookuptext&lt;br /&gt;
* Die Listen im Code-Dialog wurden erweitert&lt;br /&gt;
* Funktion $BASE64&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_9.zip, 19,7 MB)[[https://bafbal.de/downloads/bc3_v0_9.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.8==&lt;br /&gt;
&lt;br /&gt;
* Grid- und VL-Wizard&lt;br /&gt;
* SQL-Creator&lt;br /&gt;
* Dialoge&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_8.zip, 19,87 MB)[[https://bafbal.de/downloads/bc3_v0_8.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.7==&lt;br /&gt;
&lt;br /&gt;
Download nicht mehr verfügbar&lt;br /&gt;
&lt;br /&gt;
==Version 0.3 &amp;quot;Public Preview&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Hinweise:&lt;br /&gt;
&lt;br /&gt;
Download (copy_303.zip, 9,39 MB)[[https://bafbal.de/downloads/copy_303.zip]]&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Versionen&amp;diff=22557</id>
		<title>Versionen</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Versionen&amp;diff=22557"/>
		<updated>2026-01-11T12:07:12Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* Version 1.04 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=BAF-Client Download=&lt;br /&gt;
&lt;br /&gt;
* Einfach die ZIP-Datei entpacken und dann erst mal die beiliegenden Fonts installieren (recht Maustaste, &amp;quot;Installieren&amp;quot;)&lt;br /&gt;
* Den BAF-Client einfach mit der Datei BafCLientFM.exe starten&lt;br /&gt;
* Username und Passwort (admin/admin) kommen aus der Ini-Datei. Vor dem Produktivbetrieb das Passwort dort löschen und in der Userverwaltung abändern.&lt;br /&gt;
&lt;br /&gt;
==Version 1.04==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren sowie wesentliche Parameterergänzungen. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
Var: #exec_async, $VTRDB()&lt;br /&gt;
DB: #sql_openkvl&lt;br /&gt;
Form: #grd_lookupliveclear&lt;br /&gt;
XML: $XML_VALEX()&lt;br /&gt;
XLS: #xls_delete_sheet&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_04.zip, 25.971 KB)[[https://bafbal.de/downloads/bc3_v1_04.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_04.zip, 26.427 KB)[[https://bafbal.de/downloads/bs_v1_04.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.03==&lt;br /&gt;
 		 	&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren sowie wesentliche Parameterergänzungen. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
 		 	&lt;br /&gt;
* Die Suche kann nun auf die Kommandos in den Favoriten beschränkt werden.&lt;br /&gt;
* Int: $EMPTYVAL(), $NEMPTYVAL()&lt;br /&gt;
* Var: $CONVERT(), $DATECOMP(), $EMPTYVAR(), $NEMPTYVAR()&lt;br /&gt;
* DB: #sql_openval hat nun die Parameter af und de&lt;br /&gt;
* Form: #tree_node hat nun den Parameter iek, $GRD_REGEX(), S-Grid (#sgrd_seg, #sgrd_node, #sgrd_hf, #sgrd_data), #grd_data kennt nun auch q=text&lt;br /&gt;
* Web: #email_init hat nun den Parameter sasl, #email_send hat nun den Parameter fn_list&lt;br /&gt;
* JSON: $JSON_ARRAY_VALUE(), $JSON_LFR()&lt;br /&gt;
* PDF: #pdf_text hat nun den Parameter d&lt;br /&gt;
 &lt;br /&gt;
Download Client (bc3_v1_03.zip, 25.880 KB)[[https://bafbal.de/downloads/bc3_v1_03.zip]]&lt;br /&gt;
 &lt;br /&gt;
Download Server (bs_v1_03.zip, 26.420 KB)[[https://bafbal.de/downloads/bs_v1_03.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.02==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Var: #file_wait, $BFMT(), $CFMT()&lt;br /&gt;
* Form: #dlg, #dlg_close&lt;br /&gt;
* XML: $XML_VALEX()&lt;br /&gt;
* Code-Dialog: Es wurde die Seite ''Fav'' und die entsprechende Checkbox auf der Seite ''Code'' hinzugefügt. Um dies nutzen zu können, muss die folgende Tabelle existieren:&lt;br /&gt;
&lt;br /&gt;
 create table sys_userfav(&lt;br /&gt;
   name varchar(80) not null,&lt;br /&gt;
   user_user_id varchar(40) not null&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_02.zip, 23.627 KB)[[https://bafbal.de/downloads/bc3_v1_02.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_02.zip, 25.071 KB)[[https://bafbal.de/downloads/bs_v1_02.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.01==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Interpreter: Funktion $INCP() ergänzt (if not command parameter)&lt;br /&gt;
* DB: #sql_upsert2 (gibt es den Datensatz noch nicht, wird er angelegt, haben sich die Daten geändert, werden sie geschrieben)&lt;br /&gt;
* Form: $DLG_YESNO() (Dialog mit Yes/No)&lt;br /&gt;
* Form: #tree_clearnode (Entfernt einen Zweig, damit er neu aufgebaut werden kann)&lt;br /&gt;
* Form: #grd_dub (ermittelt Dubletten in einem Grid)&lt;br /&gt;
* XML: $XML_DATATEXT (ermittelt ein XML in einer Schleife)&lt;br /&gt;
* XML: $XML_LFR (loop first regex)&lt;br /&gt;
* XLS: #xls_load (öffnet eine XLS-Datei)&lt;br /&gt;
* XLS: #xls_looprows (loop über die Zeilen einer XLS-Datei)&lt;br /&gt;
* XLS: $XLS_COUNT() (ermittelt die Anzahl von Sheets, Zeilen oder Zellen)&lt;br /&gt;
* XLS: $XLS_CELL() (Gibt der Wert einer Zelle aus)&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_01.zip, 23.620 KB)[[https://bafbal.de/downloads/bc3_v1_01.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_01.zip, 25.067 KB)[[https://bafbal.de/downloads/bs_v1_01.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.00==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Im Code-Dialog wurde die Seite ''Open SQL'' überarbeitet und auf drei solche Seiten erweitert&lt;br /&gt;
*[[Modul_VAR_neu#.23csv_check|#csv_check]] Prüft eine CSV-Datei&lt;br /&gt;
*[[Modul_VAR_neu#.24CSV_LINE.28.29|$CSV_LINE()]] Gibt eine ganze Zeile einer CSV-Datei zurück &lt;br /&gt;
*[[Modul_VAR_neu#.23tvl_add|#tvl_add]] Addiert einem Wert in einer Text-Value-Liste einen Wert hinzu &lt;br /&gt;
*[[Modul_VAR_neu#.23exit|#exit]] Bricht die Ausführung eines (Sub-)Kommandos ab&lt;br /&gt;
*[[Modul_VAR_neu#.24STROP.28.29|$STROP()]] Verschiedene String-Bearbeitungen wie Trim, Quote oder Unquote&lt;br /&gt;
*[[Modul_Form#.24CCI.28.29|$CCI()]] Ermittelt die zu setzende Zellen-Farbe&lt;br /&gt;
*[[Modul_Form#.23grd_sort|#grd_sort]] Sortiert ein Grid&lt;br /&gt;
*[[Modul_Form#.23grd_pos|#grd_pos]] Ermittelt das erste Vorkommen einer Zeile, deren Zelleninhalte den Kriterien entsprechen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_00.zip, 23.476 KB)[[https://bafbal.de/downloads/bc3_v1_00.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_00.zip, 25.040 KB)[[https://bafbal.de/downloads/bs_v1_00.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.99==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Vereinzelt wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier meist nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
*[[Modul_VAR_neu#.23text_act|#text_act]] Bearbeitet einen Text&lt;br /&gt;
*[[Modul_VAR_neu#.24FILEINFO.28.29|$FILEINFO()]] Liefert Infos zu einer Datei&lt;br /&gt;
*[[Modul_VAR_neu#.23zip_create|#zip_create]] Erzeugt eine ZIP-Datei&lt;br /&gt;
*[[Modul_VAR_neu#.24LEVENSHTEIN.28.29|$LEVENSHTEIN()]] Ermittelt die Levensthein-Distanz (Größe bei einem String-Vergleich)&lt;br /&gt;
*[[Modul_VAR_neu#.24RANDOM.28.29_2|$RANDOM()]] Erzeugt eine Zufalls-Zahl&lt;br /&gt;
* Bei Konsolen-Programmen kann nun auf den Bestätigungsdialog verzichtet werden, siehe [[Modul_Form#.23frm|#frm]]&lt;br /&gt;
* Bei [[Modul_Form#.23tree_sel|#tree_sel]] können nun auch Unterknoten durchsucht werden.&lt;br /&gt;
*[[Modul_Form#.23tree_fillthread|#tree_fillthread]] - Ergänzt den Baum in einem Thread (meist, um Daten aus einer Datenbank zu ergänzen)&lt;br /&gt;
*[[Modul_Form#.23vl_thread|#vl_thread]] Ergänzt die Daten in einem VL-Segment (meist, um Daten aus einer Datenbank zu ergänzen)&lt;br /&gt;
*[[Modul_Form#.23xgrd_calc|#xgrd_calc]] Berechnet einen Wert in einem XGrid-Segment&lt;br /&gt;
*[[Modul_Form#.24XGRD_CALC|$XGRD_CALC()]] Berechnet einen Wert in einem XGrid-Segment, aber als Funktion&lt;br /&gt;
*[[Modul_Form#XXGrid-Segmente|XX-Grid-Segmente]] (mehrere Prozeduren)&lt;br /&gt;
*[[Modul_XML#.23xml_gav|#xml_gav]] Holt die Array-Werte aus einem XML&lt;br /&gt;
* In [[Modul_JSON#.24JSON_DATA|$JSON_DATA()]] können nun auch Namen ausgelesen werden&lt;br /&gt;
* In [[Modul_XLS#.23xls_cell|#xls_cell]] kann nun auch die vertikale Ausrichtung in einer Zelle spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_99.zip, 23.345 KB)[[https://bafbal.de/downloads/bc3_v0_99.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_99.zip, 24.935 KB)[[https://bafbal.de/downloads/bs_v0_99.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.98==&lt;br /&gt;
&lt;br /&gt;
* Im GridWizard funktioniert nun der Hint der Spaltenüberschriften&lt;br /&gt;
* Links funktionieren nun im VL-Segment&lt;br /&gt;
* #tree_sel erweitert&lt;br /&gt;
* #sql_opentvl&lt;br /&gt;
* #sql_line &lt;br /&gt;
* Lookups, Specials und Kommandos cachen nun&lt;br /&gt;
* XGrid und XXGrid stretchen nun&lt;br /&gt;
* grd_thread y=gridlist&lt;br /&gt;
* #grd_seg und #vl_seg - whs&lt;br /&gt;
* Werte werden nun nur vom Grid in den Baum zurück geschrieben, wenn sie tatsächlich geändert wurden&lt;br /&gt;
* #tree_fillthread&lt;br /&gt;
* Prozessabbruch beim Fortschrittsdialog wird nun resettet&lt;br /&gt;
* cmd no_crlf&lt;br /&gt;
* Verbesserung von dateMin und dateSek&lt;br /&gt;
* $INCP&lt;br /&gt;
* Pos1 und End im Grid&lt;br /&gt;
* Wizzard für csv und xlsx&lt;br /&gt;
* Beim Debug-Fenster Select werden nun nicht mehr die Selects angezeigt, die Commands holen&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_98.zip, 20.246 KB)[[https://bafbal.de/downloads/bc3_v0_98.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_98.zip, 24.577 KB)[[https://bafbal.de/downloads/bs_v0_98.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.97==&lt;br /&gt;
&lt;br /&gt;
* #grd_ac ergänzt&lt;br /&gt;
* $INCLUDE() ergänzt&lt;br /&gt;
* $ONLYNUM() ergänzt&lt;br /&gt;
* Fehler beim Parsen von XML behoben&lt;br /&gt;
* UserIni wird nun beim ServerProzess beim Ende gespeichert&lt;br /&gt;
* Cursor beim Login-Dialog&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_97.zip, 20.236 KB)[[https://bafbal.de/downloads/bc3_v0_97.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_97.zip, 24.572 KB)[[https://bafbal.de/downloads/bs_v0_97.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.96==&lt;br /&gt;
&lt;br /&gt;
* TBafTree Scrollbar bei langen Listen gleich&lt;br /&gt;
* #ftp_connect Parameter isc&lt;br /&gt;
* #email_init Parameter port, isc und to&lt;br /&gt;
* Menu scrollt nun richtig&lt;br /&gt;
* PDF Grid (#pdf_gdef, #pdf_grow, #pdf_gend)&lt;br /&gt;
* #upsert, y=c und n&lt;br /&gt;
* Performance Log&lt;br /&gt;
* Debug, Request and Response&lt;br /&gt;
* History Statement bei anderen DB&lt;br /&gt;
* PG, AlterTable, AlterHistory, Leerzeilen in CREATE TABLE kein Problem mehr bei Funktionen&lt;br /&gt;
* Vorbelegung Username aus INI beim Login-Dialog&lt;br /&gt;
* Baum kann mit Tasten gesteuert werden&lt;br /&gt;
* Page, kleinere Bugs behoben, TAB nun auch bei VL-Segment&lt;br /&gt;
* $ISDATE ergänzt&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_96.zip, 20.232 KB)[[https://bafbal.de/downloads/bc3_v0_96.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_96.zip, 24.569 KB)[[https://bafbal.de/downloads/bs_v0_96.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.95==&lt;br /&gt;
&lt;br /&gt;
* REST und JSON&lt;br /&gt;
* Bilder&lt;br /&gt;
* ein wenig XML&lt;br /&gt;
* tvl bei Nachschlagelisten&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_95.zip, 24.541 KB)[[https://bafbal.de/downloads/bc3_v0_95.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_95.zip, 24.518 KB)[[https://bafbal.de/downloads/bs_v0_95.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.91==&lt;br /&gt;
&lt;br /&gt;
* TBafTree&lt;br /&gt;
* uServer und uServer2&lt;br /&gt;
* Parameter isc bei #http_request&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_91.zip, 19,7 MB)[[https://bafbal.de/downloads/bc3_v0_91.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.9==&lt;br /&gt;
&lt;br /&gt;
* Werden Texte in Nachschlagelisten geladen, werden nun Funktionen (z.B. Übersetzungen) ersetzt&lt;br /&gt;
* Werden nach einer Änderung im Tree Werte in den Baum zurückgeschrieben, wird nicht nur - wie bisher - c1 und c2 geschrieben, sondern auch k. Zudem werden nun Funktionen ersetzt&lt;br /&gt;
* Wurde bei VL-Wizard nachgebessert&lt;br /&gt;
* lookuptext&lt;br /&gt;
* Die Listen im Code-Dialog wurden erweitert&lt;br /&gt;
* Funktion $BASE64&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_9.zip, 19,7 MB)[[https://bafbal.de/downloads/bc3_v0_9.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.8==&lt;br /&gt;
&lt;br /&gt;
* Grid- und VL-Wizard&lt;br /&gt;
* SQL-Creator&lt;br /&gt;
* Dialoge&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_8.zip, 19,87 MB)[[https://bafbal.de/downloads/bc3_v0_8.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.7==&lt;br /&gt;
&lt;br /&gt;
Download nicht mehr verfügbar&lt;br /&gt;
&lt;br /&gt;
==Version 0.3 &amp;quot;Public Preview&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Hinweise:&lt;br /&gt;
&lt;br /&gt;
Download (copy_303.zip, 9,39 MB)[[https://bafbal.de/downloads/copy_303.zip]]&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Versionen&amp;diff=22556</id>
		<title>Versionen</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Versionen&amp;diff=22556"/>
		<updated>2026-01-11T12:00:30Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* Version 1.04 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=BAF-Client Download=&lt;br /&gt;
&lt;br /&gt;
* Einfach die ZIP-Datei entpacken und dann erst mal die beiliegenden Fonts installieren (recht Maustaste, &amp;quot;Installieren&amp;quot;)&lt;br /&gt;
* Den BAF-Client einfach mit der Datei BafCLientFM.exe starten&lt;br /&gt;
* Username und Passwort (admin/admin) kommen aus der Ini-Datei. Vor dem Produktivbetrieb das Passwort dort löschen und in der Userverwaltung abändern.&lt;br /&gt;
&lt;br /&gt;
==Version 1.04==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren sowie wesentliche Parameterergänzungen. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_04.zip, 25.971 KB)[[https://bafbal.de/downloads/bc3_v1_04.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_04.zip, 26.427 KB)[[https://bafbal.de/downloads/bs_v1_04.zip]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Version 1.03==&lt;br /&gt;
 		 	&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren sowie wesentliche Parameterergänzungen. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
 		 	&lt;br /&gt;
* Die Suche kann nun auf die Kommandos in den Favoriten beschränkt werden.&lt;br /&gt;
* Int: $EMPTYVAL(), $NEMPTYVAL()&lt;br /&gt;
* Var: $CONVERT(), $DATECOMP(), $EMPTYVAR(), $NEMPTYVAR()&lt;br /&gt;
* DB: #sql_openval hat nun die Parameter af und de&lt;br /&gt;
* Form: #tree_node hat nun den Parameter iek, $GRD_REGEX(), S-Grid (#sgrd_seg, #sgrd_node, #sgrd_hf, #sgrd_data), #grd_data kennt nun auch q=text&lt;br /&gt;
* Web: #email_init hat nun den Parameter sasl, #email_send hat nun den Parameter fn_list&lt;br /&gt;
* JSON: $JSON_ARRAY_VALUE(), $JSON_LFR()&lt;br /&gt;
* PDF: #pdf_text hat nun den Parameter d&lt;br /&gt;
 &lt;br /&gt;
Download Client (bc3_v1_03.zip, 25.880 KB)[[https://bafbal.de/downloads/bc3_v1_03.zip]]&lt;br /&gt;
 &lt;br /&gt;
Download Server (bs_v1_03.zip, 26.420 KB)[[https://bafbal.de/downloads/bs_v1_03.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.02==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Var: #file_wait, $BFMT(), $CFMT()&lt;br /&gt;
* Form: #dlg, #dlg_close&lt;br /&gt;
* XML: $XML_VALEX()&lt;br /&gt;
* Code-Dialog: Es wurde die Seite ''Fav'' und die entsprechende Checkbox auf der Seite ''Code'' hinzugefügt. Um dies nutzen zu können, muss die folgende Tabelle existieren:&lt;br /&gt;
&lt;br /&gt;
 create table sys_userfav(&lt;br /&gt;
   name varchar(80) not null,&lt;br /&gt;
   user_user_id varchar(40) not null&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_02.zip, 23.627 KB)[[https://bafbal.de/downloads/bc3_v1_02.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_02.zip, 25.071 KB)[[https://bafbal.de/downloads/bs_v1_02.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.01==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Interpreter: Funktion $INCP() ergänzt (if not command parameter)&lt;br /&gt;
* DB: #sql_upsert2 (gibt es den Datensatz noch nicht, wird er angelegt, haben sich die Daten geändert, werden sie geschrieben)&lt;br /&gt;
* Form: $DLG_YESNO() (Dialog mit Yes/No)&lt;br /&gt;
* Form: #tree_clearnode (Entfernt einen Zweig, damit er neu aufgebaut werden kann)&lt;br /&gt;
* Form: #grd_dub (ermittelt Dubletten in einem Grid)&lt;br /&gt;
* XML: $XML_DATATEXT (ermittelt ein XML in einer Schleife)&lt;br /&gt;
* XML: $XML_LFR (loop first regex)&lt;br /&gt;
* XLS: #xls_load (öffnet eine XLS-Datei)&lt;br /&gt;
* XLS: #xls_looprows (loop über die Zeilen einer XLS-Datei)&lt;br /&gt;
* XLS: $XLS_COUNT() (ermittelt die Anzahl von Sheets, Zeilen oder Zellen)&lt;br /&gt;
* XLS: $XLS_CELL() (Gibt der Wert einer Zelle aus)&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_01.zip, 23.620 KB)[[https://bafbal.de/downloads/bc3_v1_01.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_01.zip, 25.067 KB)[[https://bafbal.de/downloads/bs_v1_01.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.00==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Im Code-Dialog wurde die Seite ''Open SQL'' überarbeitet und auf drei solche Seiten erweitert&lt;br /&gt;
*[[Modul_VAR_neu#.23csv_check|#csv_check]] Prüft eine CSV-Datei&lt;br /&gt;
*[[Modul_VAR_neu#.24CSV_LINE.28.29|$CSV_LINE()]] Gibt eine ganze Zeile einer CSV-Datei zurück &lt;br /&gt;
*[[Modul_VAR_neu#.23tvl_add|#tvl_add]] Addiert einem Wert in einer Text-Value-Liste einen Wert hinzu &lt;br /&gt;
*[[Modul_VAR_neu#.23exit|#exit]] Bricht die Ausführung eines (Sub-)Kommandos ab&lt;br /&gt;
*[[Modul_VAR_neu#.24STROP.28.29|$STROP()]] Verschiedene String-Bearbeitungen wie Trim, Quote oder Unquote&lt;br /&gt;
*[[Modul_Form#.24CCI.28.29|$CCI()]] Ermittelt die zu setzende Zellen-Farbe&lt;br /&gt;
*[[Modul_Form#.23grd_sort|#grd_sort]] Sortiert ein Grid&lt;br /&gt;
*[[Modul_Form#.23grd_pos|#grd_pos]] Ermittelt das erste Vorkommen einer Zeile, deren Zelleninhalte den Kriterien entsprechen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_00.zip, 23.476 KB)[[https://bafbal.de/downloads/bc3_v1_00.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_00.zip, 25.040 KB)[[https://bafbal.de/downloads/bs_v1_00.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.99==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Vereinzelt wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier meist nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
*[[Modul_VAR_neu#.23text_act|#text_act]] Bearbeitet einen Text&lt;br /&gt;
*[[Modul_VAR_neu#.24FILEINFO.28.29|$FILEINFO()]] Liefert Infos zu einer Datei&lt;br /&gt;
*[[Modul_VAR_neu#.23zip_create|#zip_create]] Erzeugt eine ZIP-Datei&lt;br /&gt;
*[[Modul_VAR_neu#.24LEVENSHTEIN.28.29|$LEVENSHTEIN()]] Ermittelt die Levensthein-Distanz (Größe bei einem String-Vergleich)&lt;br /&gt;
*[[Modul_VAR_neu#.24RANDOM.28.29_2|$RANDOM()]] Erzeugt eine Zufalls-Zahl&lt;br /&gt;
* Bei Konsolen-Programmen kann nun auf den Bestätigungsdialog verzichtet werden, siehe [[Modul_Form#.23frm|#frm]]&lt;br /&gt;
* Bei [[Modul_Form#.23tree_sel|#tree_sel]] können nun auch Unterknoten durchsucht werden.&lt;br /&gt;
*[[Modul_Form#.23tree_fillthread|#tree_fillthread]] - Ergänzt den Baum in einem Thread (meist, um Daten aus einer Datenbank zu ergänzen)&lt;br /&gt;
*[[Modul_Form#.23vl_thread|#vl_thread]] Ergänzt die Daten in einem VL-Segment (meist, um Daten aus einer Datenbank zu ergänzen)&lt;br /&gt;
*[[Modul_Form#.23xgrd_calc|#xgrd_calc]] Berechnet einen Wert in einem XGrid-Segment&lt;br /&gt;
*[[Modul_Form#.24XGRD_CALC|$XGRD_CALC()]] Berechnet einen Wert in einem XGrid-Segment, aber als Funktion&lt;br /&gt;
*[[Modul_Form#XXGrid-Segmente|XX-Grid-Segmente]] (mehrere Prozeduren)&lt;br /&gt;
*[[Modul_XML#.23xml_gav|#xml_gav]] Holt die Array-Werte aus einem XML&lt;br /&gt;
* In [[Modul_JSON#.24JSON_DATA|$JSON_DATA()]] können nun auch Namen ausgelesen werden&lt;br /&gt;
* In [[Modul_XLS#.23xls_cell|#xls_cell]] kann nun auch die vertikale Ausrichtung in einer Zelle spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_99.zip, 23.345 KB)[[https://bafbal.de/downloads/bc3_v0_99.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_99.zip, 24.935 KB)[[https://bafbal.de/downloads/bs_v0_99.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.98==&lt;br /&gt;
&lt;br /&gt;
* Im GridWizard funktioniert nun der Hint der Spaltenüberschriften&lt;br /&gt;
* Links funktionieren nun im VL-Segment&lt;br /&gt;
* #tree_sel erweitert&lt;br /&gt;
* #sql_opentvl&lt;br /&gt;
* #sql_line &lt;br /&gt;
* Lookups, Specials und Kommandos cachen nun&lt;br /&gt;
* XGrid und XXGrid stretchen nun&lt;br /&gt;
* grd_thread y=gridlist&lt;br /&gt;
* #grd_seg und #vl_seg - whs&lt;br /&gt;
* Werte werden nun nur vom Grid in den Baum zurück geschrieben, wenn sie tatsächlich geändert wurden&lt;br /&gt;
* #tree_fillthread&lt;br /&gt;
* Prozessabbruch beim Fortschrittsdialog wird nun resettet&lt;br /&gt;
* cmd no_crlf&lt;br /&gt;
* Verbesserung von dateMin und dateSek&lt;br /&gt;
* $INCP&lt;br /&gt;
* Pos1 und End im Grid&lt;br /&gt;
* Wizzard für csv und xlsx&lt;br /&gt;
* Beim Debug-Fenster Select werden nun nicht mehr die Selects angezeigt, die Commands holen&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_98.zip, 20.246 KB)[[https://bafbal.de/downloads/bc3_v0_98.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_98.zip, 24.577 KB)[[https://bafbal.de/downloads/bs_v0_98.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.97==&lt;br /&gt;
&lt;br /&gt;
* #grd_ac ergänzt&lt;br /&gt;
* $INCLUDE() ergänzt&lt;br /&gt;
* $ONLYNUM() ergänzt&lt;br /&gt;
* Fehler beim Parsen von XML behoben&lt;br /&gt;
* UserIni wird nun beim ServerProzess beim Ende gespeichert&lt;br /&gt;
* Cursor beim Login-Dialog&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_97.zip, 20.236 KB)[[https://bafbal.de/downloads/bc3_v0_97.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_97.zip, 24.572 KB)[[https://bafbal.de/downloads/bs_v0_97.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.96==&lt;br /&gt;
&lt;br /&gt;
* TBafTree Scrollbar bei langen Listen gleich&lt;br /&gt;
* #ftp_connect Parameter isc&lt;br /&gt;
* #email_init Parameter port, isc und to&lt;br /&gt;
* Menu scrollt nun richtig&lt;br /&gt;
* PDF Grid (#pdf_gdef, #pdf_grow, #pdf_gend)&lt;br /&gt;
* #upsert, y=c und n&lt;br /&gt;
* Performance Log&lt;br /&gt;
* Debug, Request and Response&lt;br /&gt;
* History Statement bei anderen DB&lt;br /&gt;
* PG, AlterTable, AlterHistory, Leerzeilen in CREATE TABLE kein Problem mehr bei Funktionen&lt;br /&gt;
* Vorbelegung Username aus INI beim Login-Dialog&lt;br /&gt;
* Baum kann mit Tasten gesteuert werden&lt;br /&gt;
* Page, kleinere Bugs behoben, TAB nun auch bei VL-Segment&lt;br /&gt;
* $ISDATE ergänzt&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_96.zip, 20.232 KB)[[https://bafbal.de/downloads/bc3_v0_96.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_96.zip, 24.569 KB)[[https://bafbal.de/downloads/bs_v0_96.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.95==&lt;br /&gt;
&lt;br /&gt;
* REST und JSON&lt;br /&gt;
* Bilder&lt;br /&gt;
* ein wenig XML&lt;br /&gt;
* tvl bei Nachschlagelisten&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_95.zip, 24.541 KB)[[https://bafbal.de/downloads/bc3_v0_95.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_95.zip, 24.518 KB)[[https://bafbal.de/downloads/bs_v0_95.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.91==&lt;br /&gt;
&lt;br /&gt;
* TBafTree&lt;br /&gt;
* uServer und uServer2&lt;br /&gt;
* Parameter isc bei #http_request&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_91.zip, 19,7 MB)[[https://bafbal.de/downloads/bc3_v0_91.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.9==&lt;br /&gt;
&lt;br /&gt;
* Werden Texte in Nachschlagelisten geladen, werden nun Funktionen (z.B. Übersetzungen) ersetzt&lt;br /&gt;
* Werden nach einer Änderung im Tree Werte in den Baum zurückgeschrieben, wird nicht nur - wie bisher - c1 und c2 geschrieben, sondern auch k. Zudem werden nun Funktionen ersetzt&lt;br /&gt;
* Wurde bei VL-Wizard nachgebessert&lt;br /&gt;
* lookuptext&lt;br /&gt;
* Die Listen im Code-Dialog wurden erweitert&lt;br /&gt;
* Funktion $BASE64&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_9.zip, 19,7 MB)[[https://bafbal.de/downloads/bc3_v0_9.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.8==&lt;br /&gt;
&lt;br /&gt;
* Grid- und VL-Wizard&lt;br /&gt;
* SQL-Creator&lt;br /&gt;
* Dialoge&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_8.zip, 19,87 MB)[[https://bafbal.de/downloads/bc3_v0_8.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.7==&lt;br /&gt;
&lt;br /&gt;
Download nicht mehr verfügbar&lt;br /&gt;
&lt;br /&gt;
==Version 0.3 &amp;quot;Public Preview&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Hinweise:&lt;br /&gt;
&lt;br /&gt;
Download (copy_303.zip, 9,39 MB)[[https://bafbal.de/downloads/copy_303.zip]]&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Versionen&amp;diff=22555</id>
		<title>Versionen</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Versionen&amp;diff=22555"/>
		<updated>2026-01-11T11:58:36Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* Version 1.03 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=BAF-Client Download=&lt;br /&gt;
&lt;br /&gt;
* Einfach die ZIP-Datei entpacken und dann erst mal die beiliegenden Fonts installieren (recht Maustaste, &amp;quot;Installieren&amp;quot;)&lt;br /&gt;
* Den BAF-Client einfach mit der Datei BafCLientFM.exe starten&lt;br /&gt;
* Username und Passwort (admin/admin) kommen aus der Ini-Datei. Vor dem Produktivbetrieb das Passwort dort löschen und in der Userverwaltung abändern.&lt;br /&gt;
&lt;br /&gt;
==Version 1.04==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren sowie wesentliche Parameterergänzungen. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_04.zip, 25.971 KB)[[https://bafbal.de/downloads/bc3_v1_04.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_04.zip, 26.427 KB)[[https://bafbal.de/downloads/bs_v1_04.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.02==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Var: #file_wait, $BFMT(), $CFMT()&lt;br /&gt;
* Form: #dlg, #dlg_close&lt;br /&gt;
* XML: $XML_VALEX()&lt;br /&gt;
* Code-Dialog: Es wurde die Seite ''Fav'' und die entsprechende Checkbox auf der Seite ''Code'' hinzugefügt. Um dies nutzen zu können, muss die folgende Tabelle existieren:&lt;br /&gt;
&lt;br /&gt;
 create table sys_userfav(&lt;br /&gt;
   name varchar(80) not null,&lt;br /&gt;
   user_user_id varchar(40) not null&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_02.zip, 23.627 KB)[[https://bafbal.de/downloads/bc3_v1_02.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_02.zip, 25.071 KB)[[https://bafbal.de/downloads/bs_v1_02.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.01==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Interpreter: Funktion $INCP() ergänzt (if not command parameter)&lt;br /&gt;
* DB: #sql_upsert2 (gibt es den Datensatz noch nicht, wird er angelegt, haben sich die Daten geändert, werden sie geschrieben)&lt;br /&gt;
* Form: $DLG_YESNO() (Dialog mit Yes/No)&lt;br /&gt;
* Form: #tree_clearnode (Entfernt einen Zweig, damit er neu aufgebaut werden kann)&lt;br /&gt;
* Form: #grd_dub (ermittelt Dubletten in einem Grid)&lt;br /&gt;
* XML: $XML_DATATEXT (ermittelt ein XML in einer Schleife)&lt;br /&gt;
* XML: $XML_LFR (loop first regex)&lt;br /&gt;
* XLS: #xls_load (öffnet eine XLS-Datei)&lt;br /&gt;
* XLS: #xls_looprows (loop über die Zeilen einer XLS-Datei)&lt;br /&gt;
* XLS: $XLS_COUNT() (ermittelt die Anzahl von Sheets, Zeilen oder Zellen)&lt;br /&gt;
* XLS: $XLS_CELL() (Gibt der Wert einer Zelle aus)&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_01.zip, 23.620 KB)[[https://bafbal.de/downloads/bc3_v1_01.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_01.zip, 25.067 KB)[[https://bafbal.de/downloads/bs_v1_01.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.00==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Im Code-Dialog wurde die Seite ''Open SQL'' überarbeitet und auf drei solche Seiten erweitert&lt;br /&gt;
*[[Modul_VAR_neu#.23csv_check|#csv_check]] Prüft eine CSV-Datei&lt;br /&gt;
*[[Modul_VAR_neu#.24CSV_LINE.28.29|$CSV_LINE()]] Gibt eine ganze Zeile einer CSV-Datei zurück &lt;br /&gt;
*[[Modul_VAR_neu#.23tvl_add|#tvl_add]] Addiert einem Wert in einer Text-Value-Liste einen Wert hinzu &lt;br /&gt;
*[[Modul_VAR_neu#.23exit|#exit]] Bricht die Ausführung eines (Sub-)Kommandos ab&lt;br /&gt;
*[[Modul_VAR_neu#.24STROP.28.29|$STROP()]] Verschiedene String-Bearbeitungen wie Trim, Quote oder Unquote&lt;br /&gt;
*[[Modul_Form#.24CCI.28.29|$CCI()]] Ermittelt die zu setzende Zellen-Farbe&lt;br /&gt;
*[[Modul_Form#.23grd_sort|#grd_sort]] Sortiert ein Grid&lt;br /&gt;
*[[Modul_Form#.23grd_pos|#grd_pos]] Ermittelt das erste Vorkommen einer Zeile, deren Zelleninhalte den Kriterien entsprechen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_00.zip, 23.476 KB)[[https://bafbal.de/downloads/bc3_v1_00.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_00.zip, 25.040 KB)[[https://bafbal.de/downloads/bs_v1_00.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.99==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Vereinzelt wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier meist nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
*[[Modul_VAR_neu#.23text_act|#text_act]] Bearbeitet einen Text&lt;br /&gt;
*[[Modul_VAR_neu#.24FILEINFO.28.29|$FILEINFO()]] Liefert Infos zu einer Datei&lt;br /&gt;
*[[Modul_VAR_neu#.23zip_create|#zip_create]] Erzeugt eine ZIP-Datei&lt;br /&gt;
*[[Modul_VAR_neu#.24LEVENSHTEIN.28.29|$LEVENSHTEIN()]] Ermittelt die Levensthein-Distanz (Größe bei einem String-Vergleich)&lt;br /&gt;
*[[Modul_VAR_neu#.24RANDOM.28.29_2|$RANDOM()]] Erzeugt eine Zufalls-Zahl&lt;br /&gt;
* Bei Konsolen-Programmen kann nun auf den Bestätigungsdialog verzichtet werden, siehe [[Modul_Form#.23frm|#frm]]&lt;br /&gt;
* Bei [[Modul_Form#.23tree_sel|#tree_sel]] können nun auch Unterknoten durchsucht werden.&lt;br /&gt;
*[[Modul_Form#.23tree_fillthread|#tree_fillthread]] - Ergänzt den Baum in einem Thread (meist, um Daten aus einer Datenbank zu ergänzen)&lt;br /&gt;
*[[Modul_Form#.23vl_thread|#vl_thread]] Ergänzt die Daten in einem VL-Segment (meist, um Daten aus einer Datenbank zu ergänzen)&lt;br /&gt;
*[[Modul_Form#.23xgrd_calc|#xgrd_calc]] Berechnet einen Wert in einem XGrid-Segment&lt;br /&gt;
*[[Modul_Form#.24XGRD_CALC|$XGRD_CALC()]] Berechnet einen Wert in einem XGrid-Segment, aber als Funktion&lt;br /&gt;
*[[Modul_Form#XXGrid-Segmente|XX-Grid-Segmente]] (mehrere Prozeduren)&lt;br /&gt;
*[[Modul_XML#.23xml_gav|#xml_gav]] Holt die Array-Werte aus einem XML&lt;br /&gt;
* In [[Modul_JSON#.24JSON_DATA|$JSON_DATA()]] können nun auch Namen ausgelesen werden&lt;br /&gt;
* In [[Modul_XLS#.23xls_cell|#xls_cell]] kann nun auch die vertikale Ausrichtung in einer Zelle spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_99.zip, 23.345 KB)[[https://bafbal.de/downloads/bc3_v0_99.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_99.zip, 24.935 KB)[[https://bafbal.de/downloads/bs_v0_99.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.98==&lt;br /&gt;
&lt;br /&gt;
* Im GridWizard funktioniert nun der Hint der Spaltenüberschriften&lt;br /&gt;
* Links funktionieren nun im VL-Segment&lt;br /&gt;
* #tree_sel erweitert&lt;br /&gt;
* #sql_opentvl&lt;br /&gt;
* #sql_line &lt;br /&gt;
* Lookups, Specials und Kommandos cachen nun&lt;br /&gt;
* XGrid und XXGrid stretchen nun&lt;br /&gt;
* grd_thread y=gridlist&lt;br /&gt;
* #grd_seg und #vl_seg - whs&lt;br /&gt;
* Werte werden nun nur vom Grid in den Baum zurück geschrieben, wenn sie tatsächlich geändert wurden&lt;br /&gt;
* #tree_fillthread&lt;br /&gt;
* Prozessabbruch beim Fortschrittsdialog wird nun resettet&lt;br /&gt;
* cmd no_crlf&lt;br /&gt;
* Verbesserung von dateMin und dateSek&lt;br /&gt;
* $INCP&lt;br /&gt;
* Pos1 und End im Grid&lt;br /&gt;
* Wizzard für csv und xlsx&lt;br /&gt;
* Beim Debug-Fenster Select werden nun nicht mehr die Selects angezeigt, die Commands holen&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_98.zip, 20.246 KB)[[https://bafbal.de/downloads/bc3_v0_98.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_98.zip, 24.577 KB)[[https://bafbal.de/downloads/bs_v0_98.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.97==&lt;br /&gt;
&lt;br /&gt;
* #grd_ac ergänzt&lt;br /&gt;
* $INCLUDE() ergänzt&lt;br /&gt;
* $ONLYNUM() ergänzt&lt;br /&gt;
* Fehler beim Parsen von XML behoben&lt;br /&gt;
* UserIni wird nun beim ServerProzess beim Ende gespeichert&lt;br /&gt;
* Cursor beim Login-Dialog&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_97.zip, 20.236 KB)[[https://bafbal.de/downloads/bc3_v0_97.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_97.zip, 24.572 KB)[[https://bafbal.de/downloads/bs_v0_97.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.96==&lt;br /&gt;
&lt;br /&gt;
* TBafTree Scrollbar bei langen Listen gleich&lt;br /&gt;
* #ftp_connect Parameter isc&lt;br /&gt;
* #email_init Parameter port, isc und to&lt;br /&gt;
* Menu scrollt nun richtig&lt;br /&gt;
* PDF Grid (#pdf_gdef, #pdf_grow, #pdf_gend)&lt;br /&gt;
* #upsert, y=c und n&lt;br /&gt;
* Performance Log&lt;br /&gt;
* Debug, Request and Response&lt;br /&gt;
* History Statement bei anderen DB&lt;br /&gt;
* PG, AlterTable, AlterHistory, Leerzeilen in CREATE TABLE kein Problem mehr bei Funktionen&lt;br /&gt;
* Vorbelegung Username aus INI beim Login-Dialog&lt;br /&gt;
* Baum kann mit Tasten gesteuert werden&lt;br /&gt;
* Page, kleinere Bugs behoben, TAB nun auch bei VL-Segment&lt;br /&gt;
* $ISDATE ergänzt&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_96.zip, 20.232 KB)[[https://bafbal.de/downloads/bc3_v0_96.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_96.zip, 24.569 KB)[[https://bafbal.de/downloads/bs_v0_96.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.95==&lt;br /&gt;
&lt;br /&gt;
* REST und JSON&lt;br /&gt;
* Bilder&lt;br /&gt;
* ein wenig XML&lt;br /&gt;
* tvl bei Nachschlagelisten&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_95.zip, 24.541 KB)[[https://bafbal.de/downloads/bc3_v0_95.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_95.zip, 24.518 KB)[[https://bafbal.de/downloads/bs_v0_95.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.91==&lt;br /&gt;
&lt;br /&gt;
* TBafTree&lt;br /&gt;
* uServer und uServer2&lt;br /&gt;
* Parameter isc bei #http_request&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_91.zip, 19,7 MB)[[https://bafbal.de/downloads/bc3_v0_91.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.9==&lt;br /&gt;
&lt;br /&gt;
* Werden Texte in Nachschlagelisten geladen, werden nun Funktionen (z.B. Übersetzungen) ersetzt&lt;br /&gt;
* Werden nach einer Änderung im Tree Werte in den Baum zurückgeschrieben, wird nicht nur - wie bisher - c1 und c2 geschrieben, sondern auch k. Zudem werden nun Funktionen ersetzt&lt;br /&gt;
* Wurde bei VL-Wizard nachgebessert&lt;br /&gt;
* lookuptext&lt;br /&gt;
* Die Listen im Code-Dialog wurden erweitert&lt;br /&gt;
* Funktion $BASE64&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_9.zip, 19,7 MB)[[https://bafbal.de/downloads/bc3_v0_9.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.8==&lt;br /&gt;
&lt;br /&gt;
* Grid- und VL-Wizard&lt;br /&gt;
* SQL-Creator&lt;br /&gt;
* Dialoge&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_8.zip, 19,87 MB)[[https://bafbal.de/downloads/bc3_v0_8.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.7==&lt;br /&gt;
&lt;br /&gt;
Download nicht mehr verfügbar&lt;br /&gt;
&lt;br /&gt;
==Version 0.3 &amp;quot;Public Preview&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Hinweise:&lt;br /&gt;
&lt;br /&gt;
Download (copy_303.zip, 9,39 MB)[[https://bafbal.de/downloads/copy_303.zip]]&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_XLS&amp;diff=22554</id>
		<title>Modul XLS</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_XLS&amp;diff=22554"/>
		<updated>2026-01-09T10:26:06Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #xls_cell */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=XLS=&lt;br /&gt;
&lt;br /&gt;
Im Modul XLS werden die Routinen zusammengefasst, die zur Erstellung von Dateien im Excel- oder OpenOffice Calc-Format verwendet werden. Es können auch Dateien geöffnet und ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
==#xls_start==&lt;br /&gt;
&lt;br /&gt;
Startet den Export einer Excel-Datei.&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_sd_xls&amp;quot;   y=console &lt;br /&gt;
 &lt;br /&gt;
 #xls_start&lt;br /&gt;
 #xls_sheet c=&amp;quot;BAF Demo&amp;quot;&lt;br /&gt;
 #xls_row&lt;br /&gt;
 #xls_cell   z=Text&lt;br /&gt;
 #xls_cell   z=Text   w=200   fc=red&lt;br /&gt;
 #xls_row&lt;br /&gt;
 #xls_cell   z=Datum&lt;br /&gt;
 #xls_cell   y=datemin   z=$NOW()&lt;br /&gt;
 #xls_row&lt;br /&gt;
 #xls_cell   z=Zahl&lt;br /&gt;
 #xls_cell   y=curr   z=3,14&lt;br /&gt;
 &lt;br /&gt;
 #xls_stop&lt;br /&gt;
 #cout  c=&amp;quot;c_sd_xls executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#xls_load==&lt;br /&gt;
&lt;br /&gt;
Lädt eine Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname; wenn leer, wird ein Datei-Dialog geöffnet; Default leer, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #xls_load   fn=c:\temp\$VAR(filename)&lt;br /&gt;
&lt;br /&gt;
==#xls_stop==&lt;br /&gt;
&lt;br /&gt;
Beendet den Export und speichert die Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname, unter dem die Datei gespeichert wird; Funktionen werden ersetzt. Aus der Endung ergibt sich dann der Typ der Datei. Wenn der Parameter leer bleibt, öffnet sich ein Dateiauswahldialog zum Speichern.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Wenn Y, word wird nach der Erstellung gleich geöffnet; default Y, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
(siehe #xls_start)&lt;br /&gt;
&lt;br /&gt;
==#xls_sheet==&lt;br /&gt;
&lt;br /&gt;
Fügt der Datei ein (weiteres) Sheet hinzu oder selektiert ein Sheet. Alle weiteren #xls_row-Prozeduren fügen dann diesem Sheet Reihen hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Tabs&lt;br /&gt;
* fc (&amp;quot;fixed cols&amp;quot;) - Anzahl der Spalten, die links fixiert werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* fr (&amp;quot;fixed rows&amp;quot;) - Anzahl der Zeilen, die oben fixiert werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - 0-relativer Index des Sheets, das selektiert werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #xls_sheet c=&amp;quot;Daten&amp;quot;   fr=1&lt;br /&gt;
 #xls_sheet   n=0&lt;br /&gt;
&lt;br /&gt;
==#xls_delete_sheet==&lt;br /&gt;
&lt;br /&gt;
Löscht das aktuelle Sheet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #xls_delete_sheet cnd=$INVAR(zeilenzahl,0)&lt;br /&gt;
&lt;br /&gt;
==#xls_row==&lt;br /&gt;
&lt;br /&gt;
Fügt dem aktuellen Sheet eine weitere Reihe hinzu oder selektiert eine solche.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* h (height) - Höhe der Zelle; default 20, Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - 0-relativer Index der Reihe, die selektiert werden soll&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
(siehe #xls_start)&lt;br /&gt;
&lt;br /&gt;
==#xls_cell==&lt;br /&gt;
&lt;br /&gt;
Fügt der aktuellen Reihe eine weitere Zelle hinzu oder schreibt den Wert der mit n spezifizierten.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (&amp;quot;align&amp;quot;) - Ausrichtung des Textes / des Wertes in der Zelle&lt;br /&gt;
** c (&amp;quot;center&amp;quot;) - mittig&lt;br /&gt;
** d2 / d4 (decimal) - ausgerichtet am Komma für zwei oder vier Nachkommastellen&lt;br /&gt;
** l (&amp;quot;left&amp;quot;) - linksbündig&lt;br /&gt;
** r (&amp;quot;right&amp;quot;) - rechtsbündig&lt;br /&gt;
* bt, bl, br, bb (&amp;quot;border top&amp;quot;, &amp;quot;border left&amp;quot;, &amp;quot;border right&amp;quot;, &amp;quot;border bottom&amp;quot;) - Ränder der Zelle, default thin, Funktionen werden ersetzt (auto, none, thin, medium, dashed, dotted, thick, double, hair, mediumdashed, dashdotted, mediumdashdotted, dashdotdotted, mediumdashdotdotted, slanteddashdotted)&lt;br /&gt;
* cl (&amp;quot;color&amp;quot;) - Farbe der Zelle; default weiß&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* cs (&amp;quot;ColSpan&amp;quot;) - Anzahl der Spalten, die zusammengefasst werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* fc (&amp;quot;FontColor&amp;quot;) - Farbe der Schrift; default schwarz&lt;br /&gt;
* frml (&amp;quot;Formula&amp;quot;) - Formel, die berechnet werden soll. Wenn gesetzt, dann wird z ignoriert; default leer, Funktionen werden ersetzt. HINWEIS: Die Formel muss auf englisch formuliert werden, also z.B. SUM(C1:C11) statt SUMME(C1:C11); und: Parameter y muss gesetzt werden.&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - 0-relativer Index der Spalte, die geschrieben werden soll; wenn leer, wird eine neue Zelle hinzugefügt; default leer, Funktionen werden ersetzt&lt;br /&gt;
* va (&amp;quot;vertivcal align&amp;quot;) - vertikale Ausrichtung des Textes; default t, Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;bottom&amp;quot;) - unten&lt;br /&gt;
** c (&amp;quot;center&amp;quot;) - mittig&lt;br /&gt;
** t (&amp;quot;top&amp;quot;) - oben&lt;br /&gt;
* fs (&amp;quot;FontStyle&amp;quot;) - Style der Schrift, die einzelnen Optionen können kombiniert werden; default keine Option&lt;br /&gt;
** b - bold&lt;br /&gt;
** i - italic&lt;br /&gt;
** u - underline&lt;br /&gt;
** s - strikeout&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Zelle&lt;br /&gt;
* y - Typ der Zelle, default Text&lt;br /&gt;
** curr - Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum und Uhrzeit ohne Sekunden&lt;br /&gt;
** datesek - Datum und Uhrzeit mit Sekunden&lt;br /&gt;
** int - Zahlen ohne Nachkommastellen&lt;br /&gt;
** text - Text&lt;br /&gt;
* z - Wert/Text, der in der Zelle eingefügt werden soll; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #xls_cell   z=Text   w=200   fc=red&lt;br /&gt;
 #xls_cell   y=datemin   z=$NOW()&lt;br /&gt;
&lt;br /&gt;
==#xls_looprows==&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y; Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Transaktion bezieht; Funktionen werden ersetzt&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen; Funktionen werden ersetzt&lt;br /&gt;
* m - (&amp;quot;maximum&amp;quot;) Es wird maximal für die Anzahl der angegebenen Zeilen das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten; Funktionen werden ersetzt&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N; Funktionen werden ersetzt.&lt;br /&gt;
* n - Name der Variablen, in welche die aktuelle, 0-relative Schleifennummer geschrieben wird&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #xls_looprows   er=sof_7836_line   m_=5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==#xls_page==&lt;br /&gt;
&lt;br /&gt;
Exportiert alle VL-, Grid- und XGrid-Segmente der aktuellen Seite. Für jedes Segment wird eine neues Sheet angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=xls   s=#xls_page   se=b&lt;br /&gt;
&lt;br /&gt;
==$XLS_COUNT()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Anzahl der Sheets, Zeilen oder Zellen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Von was wird die Anzahl ermittelt&lt;br /&gt;
## sheets - Sheets in einer Datei&lt;br /&gt;
## rows - Zeilen in einem Sheet&lt;br /&gt;
## cells - Zellen in einer Zeile&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;Dieses Sheet hat $XLS_COUNT(rows) Zeilen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$XLS_CELL()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Zelle aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Index der Zelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=$XLS_CELL(0)&lt;br /&gt;
 &lt;br /&gt;
 ~ $INTLEN($VAL(1)) = 9&lt;br /&gt;
 #var_add   n=zeile   z=1   y=int&lt;br /&gt;
 #cout   c=&amp;quot;$VAL(1)   -   $VAR(datei) / $VAR(zeile)&amp;quot;   m=20   md=10&lt;br /&gt;
 #sql_upsert   y=a   t=neuland.sof_7836   k=adrnr   f_adrnr=$VAL(1)   hst=N&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Beispiel: XLSX-Datei mit Daten anreichern==&lt;br /&gt;
&lt;br /&gt;
===Kommando c_fp_lieferanten===&lt;br /&gt;
&lt;br /&gt;
Öffnet die Datei c:\temp\lieferanten.xlsx und geht durch alle vorhandenen Zeilen mit Ausnahme der Titelzeile (darum lf=1). Danach öffnet sich ein Datei-Dialog, um die Datei abzuspeichern.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_fp_lieferanten&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #xls_load   fn=c:\temp\lieferanten.xlsx&lt;br /&gt;
 #xls_sheet   n=0&lt;br /&gt;
 &lt;br /&gt;
 #loop   lf=1   lt=$ICALC(-,$XLS_COUNT(rows),1)   er=c_fp_lieferanten_line   n=loopvar&lt;br /&gt;
 &lt;br /&gt;
 #xls_stop&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_fp_lieferanten executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Sub-Kommando c_fp_lieferanten_line===&lt;br /&gt;
&lt;br /&gt;
Zunächst wird die korrekte Zeile gesetzt, die ist 0-relativ anzugeben. Die Lieferantennummer ist in der zweiten Spalte, das wird mit $XLS_CELL(1) ausgelesen und auch gleich ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile im Ausgangs-Sheet ist eine Summenzeile und hat keine Lieferantennummer, darum wird darauf geprüft. Mit einer einfachen SQL-Abfrage werden Steuernummer, Umsatzsteuer-ID und IBAN abgefragt und in Values zwischengespeichert. Diese werden dann in die dafür vorgesehenen Zellen geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #xls_row   n=$VAR(loopvar)&lt;br /&gt;
 #cout   c=$XLS_CELL(1)&lt;br /&gt;
 &lt;br /&gt;
 ~ $NEMPTY($XLS_CELL(1))&lt;br /&gt;
 #sql select iban, coast_steuernr, coast_ustid from cache_lieferant &lt;br /&gt;
 #sql   where lieferant_number = $XLS_CELL(1)&lt;br /&gt;
 #sql_openval    f_iban=1   f_coast_steuernr=2   f_coast_ustid=3&lt;br /&gt;
 &lt;br /&gt;
 #xls_cell   n=4   z=$VAL(3)&lt;br /&gt;
 #xls_cell   n=5   z=$VAL(2)&lt;br /&gt;
 #xls_cell   n=11   z=$VAL(1)&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_XLS&amp;diff=22553</id>
		<title>Modul XLS</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_XLS&amp;diff=22553"/>
		<updated>2026-01-09T10:25:13Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #xls_cell */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=XLS=&lt;br /&gt;
&lt;br /&gt;
Im Modul XLS werden die Routinen zusammengefasst, die zur Erstellung von Dateien im Excel- oder OpenOffice Calc-Format verwendet werden. Es können auch Dateien geöffnet und ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
==#xls_start==&lt;br /&gt;
&lt;br /&gt;
Startet den Export einer Excel-Datei.&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_sd_xls&amp;quot;   y=console &lt;br /&gt;
 &lt;br /&gt;
 #xls_start&lt;br /&gt;
 #xls_sheet c=&amp;quot;BAF Demo&amp;quot;&lt;br /&gt;
 #xls_row&lt;br /&gt;
 #xls_cell   z=Text&lt;br /&gt;
 #xls_cell   z=Text   w=200   fc=red&lt;br /&gt;
 #xls_row&lt;br /&gt;
 #xls_cell   z=Datum&lt;br /&gt;
 #xls_cell   y=datemin   z=$NOW()&lt;br /&gt;
 #xls_row&lt;br /&gt;
 #xls_cell   z=Zahl&lt;br /&gt;
 #xls_cell   y=curr   z=3,14&lt;br /&gt;
 &lt;br /&gt;
 #xls_stop&lt;br /&gt;
 #cout  c=&amp;quot;c_sd_xls executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#xls_load==&lt;br /&gt;
&lt;br /&gt;
Lädt eine Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname; wenn leer, wird ein Datei-Dialog geöffnet; Default leer, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #xls_load   fn=c:\temp\$VAR(filename)&lt;br /&gt;
&lt;br /&gt;
==#xls_stop==&lt;br /&gt;
&lt;br /&gt;
Beendet den Export und speichert die Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname, unter dem die Datei gespeichert wird; Funktionen werden ersetzt. Aus der Endung ergibt sich dann der Typ der Datei. Wenn der Parameter leer bleibt, öffnet sich ein Dateiauswahldialog zum Speichern.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Wenn Y, word wird nach der Erstellung gleich geöffnet; default Y, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
(siehe #xls_start)&lt;br /&gt;
&lt;br /&gt;
==#xls_sheet==&lt;br /&gt;
&lt;br /&gt;
Fügt der Datei ein (weiteres) Sheet hinzu oder selektiert ein Sheet. Alle weiteren #xls_row-Prozeduren fügen dann diesem Sheet Reihen hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Tabs&lt;br /&gt;
* fc (&amp;quot;fixed cols&amp;quot;) - Anzahl der Spalten, die links fixiert werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* fr (&amp;quot;fixed rows&amp;quot;) - Anzahl der Zeilen, die oben fixiert werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - 0-relativer Index des Sheets, das selektiert werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #xls_sheet c=&amp;quot;Daten&amp;quot;   fr=1&lt;br /&gt;
 #xls_sheet   n=0&lt;br /&gt;
&lt;br /&gt;
==#xls_delete_sheet==&lt;br /&gt;
&lt;br /&gt;
Löscht das aktuelle Sheet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #xls_delete_sheet cnd=$INVAR(zeilenzahl,0)&lt;br /&gt;
&lt;br /&gt;
==#xls_row==&lt;br /&gt;
&lt;br /&gt;
Fügt dem aktuellen Sheet eine weitere Reihe hinzu oder selektiert eine solche.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* h (height) - Höhe der Zelle; default 20, Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - 0-relativer Index der Reihe, die selektiert werden soll&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
(siehe #xls_start)&lt;br /&gt;
&lt;br /&gt;
==#xls_cell==&lt;br /&gt;
&lt;br /&gt;
Fügt der aktuellen Reihe eine weitere Zelle hinzu oder schreibt den Wert der mit n spezifizierten.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (&amp;quot;align&amp;quot;) - Ausrichtung des Textes / des Wertes in der Zelle&lt;br /&gt;
** c (&amp;quot;center&amp;quot;) - mittig&lt;br /&gt;
** d2 / d4 (decimal) - ausgerichtet am Komma für zwei oder vier Nachkommastellen&lt;br /&gt;
** l (&amp;quot;left&amp;quot;) - linksbündig&lt;br /&gt;
** r (&amp;quot;right&amp;quot;) - rechtsbündig&lt;br /&gt;
* bt, bl, br, bb (&amp;quot;border top&amp;quot;, &amp;quot;border left&amp;quot;, &amp;quot;border right&amp;quot;, &amp;quot;border bottom&amp;quot;) - Ränder der Zelle, default thin, Funktionen werden ersetzt (auto, none, thin, medium, dashed, dotted, thick, double, hair, mediumdashed, dashdotted, mediumdashdotted, dashdotdotted, mediumdashdotdotted, slanteddashdotted)&lt;br /&gt;
* cl (&amp;quot;color&amp;quot;) - Farbe der Zelle; default weiß&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* cs (&amp;quot;ColSpan&amp;quot;) - Anzahl der Spalten, die zusammengefasst werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* fc (&amp;quot;FontColor&amp;quot;) - Farbe der Schrift; default schwarz&lt;br /&gt;
* frml (&amp;quot;Formula&amp;quot;) - Formel, die berechnet werden soll. Wenn gesetzt, dann wird z ignoriert; default leer, Funktionen werden ersetzt. HINWEIS: Die Formel muss auf englisch formuliert werden, also z.B. SUM(C1:C11) statt SUMME(C1:C11) &lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - 0-relativer Index der Spalte, die geschrieben werden soll; wenn leer, wird eine neue Zelle hinzugefügt; default leer, Funktionen werden ersetzt&lt;br /&gt;
* va (&amp;quot;vertivcal align&amp;quot;) - vertikale Ausrichtung des Textes; default t, Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;bottom&amp;quot;) - unten&lt;br /&gt;
** c (&amp;quot;center&amp;quot;) - mittig&lt;br /&gt;
** t (&amp;quot;top&amp;quot;) - oben&lt;br /&gt;
* fs (&amp;quot;FontStyle&amp;quot;) - Style der Schrift, die einzelnen Optionen können kombiniert werden; default keine Option&lt;br /&gt;
** b - bold&lt;br /&gt;
** i - italic&lt;br /&gt;
** u - underline&lt;br /&gt;
** s - strikeout&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Zelle&lt;br /&gt;
* y - Typ der Zelle, default Text&lt;br /&gt;
** curr - Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum und Uhrzeit ohne Sekunden&lt;br /&gt;
** datesek - Datum und Uhrzeit mit Sekunden&lt;br /&gt;
** int - Zahlen ohne Nachkommastellen&lt;br /&gt;
** text - Text&lt;br /&gt;
* z - Wert/Text, der in der Zelle eingefügt werden soll; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #xls_cell   z=Text   w=200   fc=red&lt;br /&gt;
 #xls_cell   y=datemin   z=$NOW()&lt;br /&gt;
&lt;br /&gt;
==#xls_looprows==&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y; Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Transaktion bezieht; Funktionen werden ersetzt&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen; Funktionen werden ersetzt&lt;br /&gt;
* m - (&amp;quot;maximum&amp;quot;) Es wird maximal für die Anzahl der angegebenen Zeilen das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten; Funktionen werden ersetzt&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N; Funktionen werden ersetzt.&lt;br /&gt;
* n - Name der Variablen, in welche die aktuelle, 0-relative Schleifennummer geschrieben wird&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #xls_looprows   er=sof_7836_line   m_=5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==#xls_page==&lt;br /&gt;
&lt;br /&gt;
Exportiert alle VL-, Grid- und XGrid-Segmente der aktuellen Seite. Für jedes Segment wird eine neues Sheet angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=xls   s=#xls_page   se=b&lt;br /&gt;
&lt;br /&gt;
==$XLS_COUNT()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Anzahl der Sheets, Zeilen oder Zellen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Von was wird die Anzahl ermittelt&lt;br /&gt;
## sheets - Sheets in einer Datei&lt;br /&gt;
## rows - Zeilen in einem Sheet&lt;br /&gt;
## cells - Zellen in einer Zeile&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;Dieses Sheet hat $XLS_COUNT(rows) Zeilen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$XLS_CELL()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Zelle aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Index der Zelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=$XLS_CELL(0)&lt;br /&gt;
 &lt;br /&gt;
 ~ $INTLEN($VAL(1)) = 9&lt;br /&gt;
 #var_add   n=zeile   z=1   y=int&lt;br /&gt;
 #cout   c=&amp;quot;$VAL(1)   -   $VAR(datei) / $VAR(zeile)&amp;quot;   m=20   md=10&lt;br /&gt;
 #sql_upsert   y=a   t=neuland.sof_7836   k=adrnr   f_adrnr=$VAL(1)   hst=N&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Beispiel: XLSX-Datei mit Daten anreichern==&lt;br /&gt;
&lt;br /&gt;
===Kommando c_fp_lieferanten===&lt;br /&gt;
&lt;br /&gt;
Öffnet die Datei c:\temp\lieferanten.xlsx und geht durch alle vorhandenen Zeilen mit Ausnahme der Titelzeile (darum lf=1). Danach öffnet sich ein Datei-Dialog, um die Datei abzuspeichern.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_fp_lieferanten&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #xls_load   fn=c:\temp\lieferanten.xlsx&lt;br /&gt;
 #xls_sheet   n=0&lt;br /&gt;
 &lt;br /&gt;
 #loop   lf=1   lt=$ICALC(-,$XLS_COUNT(rows),1)   er=c_fp_lieferanten_line   n=loopvar&lt;br /&gt;
 &lt;br /&gt;
 #xls_stop&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_fp_lieferanten executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Sub-Kommando c_fp_lieferanten_line===&lt;br /&gt;
&lt;br /&gt;
Zunächst wird die korrekte Zeile gesetzt, die ist 0-relativ anzugeben. Die Lieferantennummer ist in der zweiten Spalte, das wird mit $XLS_CELL(1) ausgelesen und auch gleich ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile im Ausgangs-Sheet ist eine Summenzeile und hat keine Lieferantennummer, darum wird darauf geprüft. Mit einer einfachen SQL-Abfrage werden Steuernummer, Umsatzsteuer-ID und IBAN abgefragt und in Values zwischengespeichert. Diese werden dann in die dafür vorgesehenen Zellen geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #xls_row   n=$VAR(loopvar)&lt;br /&gt;
 #cout   c=$XLS_CELL(1)&lt;br /&gt;
 &lt;br /&gt;
 ~ $NEMPTY($XLS_CELL(1))&lt;br /&gt;
 #sql select iban, coast_steuernr, coast_ustid from cache_lieferant &lt;br /&gt;
 #sql   where lieferant_number = $XLS_CELL(1)&lt;br /&gt;
 #sql_openval    f_iban=1   f_coast_steuernr=2   f_coast_ustid=3&lt;br /&gt;
 &lt;br /&gt;
 #xls_cell   n=4   z=$VAL(3)&lt;br /&gt;
 #xls_cell   n=5   z=$VAL(2)&lt;br /&gt;
 #xls_cell   n=11   z=$VAL(1)&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22552</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22552"/>
		<updated>2025-12-29T09:00:11Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #cout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I; HINWEIS: Für korrekte Zählung in Server-Kommandos bitte #log verwenden.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
* ?firstnempty - der erste Wert (in der entsprechenden Gruppe), der nicht leer ist. &lt;br /&gt;
* ?lasttnempty - der letzte Wert (in der entsprechenden Gruppe), der nicht leer ist. &lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ca1, ca2... (characters allowed) - Zeichen, die bei der Eingabe über die Tastatur erlaubt sind; wenn leer, sind alle Zeichen erlaubt; default leer; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* rof1, rof2... (&amp;quot;read only field&amp;quot;) - Feldname der Spalte, aus dem die Read-Only-Funktion bezogen wird; Funktionen werden ersetzt&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ca (characters allowed) - Zeichen, die bei der Eingabe über die Tastatur erlaubt sind; wenn leer, sind alle Zeichen erlaubt; default leer; Funktionen werden ersetzt&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, aus dem die Daten bei q=text bezogen werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** text - die Daten werden aus dem mit dem Parameter n spezifizierten Text bezogen. Mögliche Werte für den Parameter f sind ''text'' (ganze Zeile), ''key'' (vor dem Gleichheitszeichen) und ''value'' (nach dem Gleichheitszeichen)&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Name der Variablen oder Nummer des Values, in die/den die Anzahl der erzeugten Zeilen geschrieben wird&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Kategorie, Funktionen werden ersetzt. Nur bei y=kat&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer der Kategorie-Valueliste; default 1, Funktionen werden ersetzt&lt;br /&gt;
* y - Type. Default sql, Funktionen werden ersetzt&lt;br /&gt;
** kat - die Werte kommen aus einer Kategorie-Valueliste.&lt;br /&gt;
** sql - die Werte kommen aus einem SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Kategorie-Valueliste'''&lt;br /&gt;
&lt;br /&gt;
 #sql select t.tournr as ckat, s.bus_haltestelle_id as ckey, s.land || ' ' || s.plz || ' ' || s.ort || ' - ' || s.beschreibung as cvalue, h.position&lt;br /&gt;
 #sql   from bus_touren t&lt;br /&gt;
 #sql     inner join bus_tour_hs h   on h.bus_touren_id = t.bus_touren_id   and h.status &amp;lt; 7   and (h.position &amp;lt; 99   or t.tournr between 30000 and 40000)&lt;br /&gt;
 #sql     inner join bus_haltestelle s   on s.bus_haltestelle_id = h.haltestelle   and s.status = 1   and s.land &amp;lt;&amp;gt; &lt;br /&gt;
 #sql   where t.kuerzel = '$FND(s,kuerzel)'   and t.datum = to_date('$FND(s,datum)', 'dd.mm.yyyy') &lt;br /&gt;
 #sql   order by 1, 4&lt;br /&gt;
 #sql_openkvl   n=1&lt;br /&gt;
&lt;br /&gt;
Für die Nachschlageliste wird dann wie folgt formuliert:&lt;br /&gt;
&lt;br /&gt;
 #grd_lookuplivefill   y=kat   n=1   k=$PVAL(pl,tournr,lookuplive)&lt;br /&gt;
&lt;br /&gt;
==#grd_lookupliveclear==&lt;br /&gt;
&lt;br /&gt;
Setzt das Flag, dass die LokupLive-Nachschlagelisten neu gefüllt werden müssen. Kann beim Einsatz von #page_val erforderlich werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
keine&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_lookupliveclear&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, dann wird die erste Zeile (die Zeile mit den Spaltenüberschriften) nicht eingelesen; default N, Funktionen werden ersetzt.&lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;condition count&amp;quot;) - Anzahl der Bedingungen bei y=gridcache, Default 1, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd1, cnd2 - Bedingungen bei y=gridcache. Die Bedingung besteht komma-separiert aus der Funktion und den Parametern&lt;br /&gt;
** eq (&amp;quot;equals&amp;quot;) - Werte müssen übereinstimmen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_gdd - Datum im Grid muss zwischen den beiden Datumswerten in der Datenmenge liegen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
** date_ggd - Datum in der Datenmenge muss zwischen den beiden Datumswerten im Grid liegen; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_ggdd - Datumsbereich im Grid und Datumsbereich in der Datenmenge brauchen eine Schnittmenge; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 4: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben. Bei y=gridcache nicht erforderlich&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** grdcache - Mit einem SQL-Statement wird ein Cache aufgebaut, aus dem dann mit den Konditions abgefragt wird; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #sql select r.servicecode, r.servicedescription, case r.exttype when 'PBUS' then 'Bus' when 'PFLUG' then 'Flug' end as exttype, j.erster_fahrtag, j.letzter_fahrtag&lt;br /&gt;
 #sql   from xr_jahr j&lt;br /&gt;
 #sql     inner join cache_reisen r   on r.cache_reisen_id = j.cache_reisen_id&lt;br /&gt;
 #sql   where extract(year from erster_fahrtag) = $VAR(jahr)   or extract(year from letzter_fahrtag) = $VAR(jahr)&lt;br /&gt;
 #sql   order by servicecode&lt;br /&gt;
 #code   cc=2   cnd1=eq,keycode,servicecode   cnd2=date_ggdd,datum_ab,datum_bis,erster_fahrtag,letzter_fahrtag&lt;br /&gt;
 #grd_thread   y=gridcache   ready=xrlt_page_stationmanager_get_reiseleiter    $CODE$&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$GRD_REGEX==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_REGEX prüft ein Grid-Segment die die Einhaltung eines Regex-Staements in einer bestimmten Spalte. Eignet sich insbesondere für #page_check, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Regex-Statement&lt;br /&gt;
# Optionen&lt;br /&gt;
## e (&amp;quot;allow empty&amp;quot;) - $GRD_REGEX gibt auch Y zurück, wenn der Zellenwert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Aktionscode entspricht nicht den Formatvorgaben&amp;quot;   chk=$GRD_REGEX(reisen,aktionscode,all,[A-Z]{3}\d{4},e)&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* ca1, ca2 (characters allowed) - Zeichen, die bei der Eingabe über die Tastatur erlaubt sind; wenn leer, sind alle Zeichen erlaubt; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22551</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22551"/>
		<updated>2025-12-28T16:59:16Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* $PVAL() */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
* ?firstnempty - der erste Wert (in der entsprechenden Gruppe), der nicht leer ist. &lt;br /&gt;
* ?lasttnempty - der letzte Wert (in der entsprechenden Gruppe), der nicht leer ist. &lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ca1, ca2... (characters allowed) - Zeichen, die bei der Eingabe über die Tastatur erlaubt sind; wenn leer, sind alle Zeichen erlaubt; default leer; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* rof1, rof2... (&amp;quot;read only field&amp;quot;) - Feldname der Spalte, aus dem die Read-Only-Funktion bezogen wird; Funktionen werden ersetzt&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ca (characters allowed) - Zeichen, die bei der Eingabe über die Tastatur erlaubt sind; wenn leer, sind alle Zeichen erlaubt; default leer; Funktionen werden ersetzt&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, aus dem die Daten bei q=text bezogen werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** text - die Daten werden aus dem mit dem Parameter n spezifizierten Text bezogen. Mögliche Werte für den Parameter f sind ''text'' (ganze Zeile), ''key'' (vor dem Gleichheitszeichen) und ''value'' (nach dem Gleichheitszeichen)&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Name der Variablen oder Nummer des Values, in die/den die Anzahl der erzeugten Zeilen geschrieben wird&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Kategorie, Funktionen werden ersetzt. Nur bei y=kat&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer der Kategorie-Valueliste; default 1, Funktionen werden ersetzt&lt;br /&gt;
* y - Type. Default sql, Funktionen werden ersetzt&lt;br /&gt;
** kat - die Werte kommen aus einer Kategorie-Valueliste.&lt;br /&gt;
** sql - die Werte kommen aus einem SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Kategorie-Valueliste'''&lt;br /&gt;
&lt;br /&gt;
 #sql select t.tournr as ckat, s.bus_haltestelle_id as ckey, s.land || ' ' || s.plz || ' ' || s.ort || ' - ' || s.beschreibung as cvalue, h.position&lt;br /&gt;
 #sql   from bus_touren t&lt;br /&gt;
 #sql     inner join bus_tour_hs h   on h.bus_touren_id = t.bus_touren_id   and h.status &amp;lt; 7   and (h.position &amp;lt; 99   or t.tournr between 30000 and 40000)&lt;br /&gt;
 #sql     inner join bus_haltestelle s   on s.bus_haltestelle_id = h.haltestelle   and s.status = 1   and s.land &amp;lt;&amp;gt; &lt;br /&gt;
 #sql   where t.kuerzel = '$FND(s,kuerzel)'   and t.datum = to_date('$FND(s,datum)', 'dd.mm.yyyy') &lt;br /&gt;
 #sql   order by 1, 4&lt;br /&gt;
 #sql_openkvl   n=1&lt;br /&gt;
&lt;br /&gt;
Für die Nachschlageliste wird dann wie folgt formuliert:&lt;br /&gt;
&lt;br /&gt;
 #grd_lookuplivefill   y=kat   n=1   k=$PVAL(pl,tournr,lookuplive)&lt;br /&gt;
&lt;br /&gt;
==#grd_lookupliveclear==&lt;br /&gt;
&lt;br /&gt;
Setzt das Flag, dass die LokupLive-Nachschlagelisten neu gefüllt werden müssen. Kann beim Einsatz von #page_val erforderlich werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
keine&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_lookupliveclear&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, dann wird die erste Zeile (die Zeile mit den Spaltenüberschriften) nicht eingelesen; default N, Funktionen werden ersetzt.&lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;condition count&amp;quot;) - Anzahl der Bedingungen bei y=gridcache, Default 1, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd1, cnd2 - Bedingungen bei y=gridcache. Die Bedingung besteht komma-separiert aus der Funktion und den Parametern&lt;br /&gt;
** eq (&amp;quot;equals&amp;quot;) - Werte müssen übereinstimmen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_gdd - Datum im Grid muss zwischen den beiden Datumswerten in der Datenmenge liegen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
** date_ggd - Datum in der Datenmenge muss zwischen den beiden Datumswerten im Grid liegen; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_ggdd - Datumsbereich im Grid und Datumsbereich in der Datenmenge brauchen eine Schnittmenge; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 4: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben. Bei y=gridcache nicht erforderlich&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** grdcache - Mit einem SQL-Statement wird ein Cache aufgebaut, aus dem dann mit den Konditions abgefragt wird; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #sql select r.servicecode, r.servicedescription, case r.exttype when 'PBUS' then 'Bus' when 'PFLUG' then 'Flug' end as exttype, j.erster_fahrtag, j.letzter_fahrtag&lt;br /&gt;
 #sql   from xr_jahr j&lt;br /&gt;
 #sql     inner join cache_reisen r   on r.cache_reisen_id = j.cache_reisen_id&lt;br /&gt;
 #sql   where extract(year from erster_fahrtag) = $VAR(jahr)   or extract(year from letzter_fahrtag) = $VAR(jahr)&lt;br /&gt;
 #sql   order by servicecode&lt;br /&gt;
 #code   cc=2   cnd1=eq,keycode,servicecode   cnd2=date_ggdd,datum_ab,datum_bis,erster_fahrtag,letzter_fahrtag&lt;br /&gt;
 #grd_thread   y=gridcache   ready=xrlt_page_stationmanager_get_reiseleiter    $CODE$&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$GRD_REGEX==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_REGEX prüft ein Grid-Segment die die Einhaltung eines Regex-Staements in einer bestimmten Spalte. Eignet sich insbesondere für #page_check, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Regex-Statement&lt;br /&gt;
# Optionen&lt;br /&gt;
## e (&amp;quot;allow empty&amp;quot;) - $GRD_REGEX gibt auch Y zurück, wenn der Zellenwert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Aktionscode entspricht nicht den Formatvorgaben&amp;quot;   chk=$GRD_REGEX(reisen,aktionscode,all,[A-Z]{3}\d{4},e)&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* ca1, ca2 (characters allowed) - Zeichen, die bei der Eingabe über die Tastatur erlaubt sind; wenn leer, sind alle Zeichen erlaubt; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Interpreter&amp;diff=22550</id>
		<title>Interpreter</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Interpreter&amp;diff=22550"/>
		<updated>2025-11-26T16:46:42Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #tab_new */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Im Interpreter sind nur wenige Prozeduren und Funktionen direkt implementiert. Die meisten Routinen finden sich in den Modulen.&lt;br /&gt;
&lt;br /&gt;
=Values=&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Variablen ist der Gültigkeitsbereich von Values auf das jeweilige (Primär- oder Sub-) Kommando beschränkt. Values haben Nummern, während Variable Namen haben.&lt;br /&gt;
&lt;br /&gt;
==#val_set==&lt;br /&gt;
&lt;br /&gt;
Setzt der Wert für einen Value.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Der Value wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie (if empty) - Wenn der Wert von z leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei Oracle; Funktionen werden ersetzt&lt;br /&gt;
*n - Nummer des Values&lt;br /&gt;
*r (rights) - Der Value wird nur dann gesetzt, wenn das Recht vorliegt; default ist ''frm''&lt;br /&gt;
*rf (replace functions) - Wenn Y, dann werden nach der Zuweisung auf den Value nochmals die Funktionen ersetzt. Wird zum Beispiel benötigt, wenn Code mit Funktionen mittels $DATA() aus der Datenbank geladen wird; Funktionen werden ersetzt, default N; siehe Beispiel&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=7   z=$GUID()&lt;br /&gt;
 #val_set   n=1   z=$GUID()   r=admin&lt;br /&gt;
&lt;br /&gt;
 -- Zum Parameter rf: $NOW() in die Zwischenablage kopieren und dann ausführen&lt;br /&gt;
 #val_set   n=1  z=$CLIPBOARD()   rf=N&lt;br /&gt;
 #message   c=$VAL(1)&lt;br /&gt;
 #val_set   n=1  z=$CLIPBOARD()   rf=Y&lt;br /&gt;
 #message   c=$VAL(1)&lt;br /&gt;
&lt;br /&gt;
==#val_add==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#val_add fügt einem Value einen Wert hinzu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Der Value wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*n - Nummer des Values; zwingend erforderlich&lt;br /&gt;
*r (rights) - Der Value wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. &lt;br /&gt;
* y -Typ der Operation; default ''text''&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
*z - Wert, welcher dem Value hinzugefügt wird, Funktionen werden ersetzt, default ist ein leerer String oder eine 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=$NOW()&lt;br /&gt;
 #val_add   n=1   z=1   y=datetime&lt;br /&gt;
 #cout   c=$VAL(1)&lt;br /&gt;
&lt;br /&gt;
==#val_clearall==&lt;br /&gt;
&lt;br /&gt;
Löscht alle Values. Wird selten benötigt, da die Values mit Ende des (Primär- oder Sub-) Kommandos ohnehin ihre Gültigkeit verlieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_clearall&lt;br /&gt;
&lt;br /&gt;
==$VAL()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Inhalt eines Values zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Values&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout c=$VAL(3)&lt;br /&gt;
&lt;br /&gt;
==$EMPTYVAL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Value ein leerer String ist, dessen Nummer im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Values&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTYVAL(1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$NEMPTYVAL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Value kein leerer String ist, dessen Nummer im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Values&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $NEMPTYVAL(2)&lt;br /&gt;
&lt;br /&gt;
=Log=&lt;br /&gt;
&lt;br /&gt;
==#exception_info==&lt;br /&gt;
&lt;br /&gt;
Tritt eine Exception auf, dann wird die entsprechende Fehlermeldung in das Log geschrieben. Mit #exception_info kann eine Information ergänzt werden, die vor diese Fehlermeldung gesetzt wird. Üblicherweise wird das dazu verwendet, um eine ID zu schreiben, damit der fehlerhafte Datensatz gefunden wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* z - Wert, welcher vor die Fehlermeldung geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #exception_info   z=$DATA(dat,knd_nr)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==#log==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Text in das Log.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der in das Log geschrieben wird; Funktionen werden ersetzt; default ist ''#log, Parameter c nicht gesetzt''&lt;br /&gt;
* y - Typ des Log-Eintrags; default I. Vorgesehen sind die folgenden Typen:&lt;br /&gt;
** E - Error&lt;br /&gt;
** I - Info&lt;br /&gt;
** W - Warning&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #log   y=W   c=&amp;quot;Ermittelte Summe untypisch gering&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#logi==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Text als Info in das Log.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #logi hat keine benannten Parameter. Der komplette Text nach dem #logi und dem folgenden Leerzeichen wird in das Log geschrieben; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #logi   Berechnung beendet&lt;br /&gt;
&lt;br /&gt;
=Kommandos=&lt;br /&gt;
&lt;br /&gt;
==#tab_new==&lt;br /&gt;
&lt;br /&gt;
Öffnet einen neuen Tab im BAF-Client und führt dort ein Kommando aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des neuen Tabs; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das im neuen Tab ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* debug - Wenn Y, wird für den neuen Tab das Debug-Log aktiviert; Default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tab_new   c=xuser   cmd=xuser($PAGE(link))&lt;br /&gt;
&lt;br /&gt;
==$CP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;command parameter&amp;quot;) - Greift auf einen Parameter des Kommandos zu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Parameters. 0-relativ, der erste Parameter hat somit die Nummer 0.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_fill  d=$CP(1)&lt;br /&gt;
&lt;br /&gt;
==$ICP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;is command parameter&amp;quot;) - Vergleicht den Parameter des Kommandos mit dem im zweiten oder weiteren Parameter angegebenen Wert; Unterschiede in Groß- und Kleinschreibung werden dabei nicht berücksichtigt. Gibt Y zurück, wenn der Parameter mit einem der Vergleichswerte übereinstimmt.&lt;br /&gt;
&lt;br /&gt;
Wird fast immer in Verbindung mit Verzweigungsbedingungen verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Parameters. 0-relativ, der erste Parameter hat somit die Nummer 0.&lt;br /&gt;
# und Folgende: Vergleichswerte&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $ICP(0,ex)&lt;br /&gt;
 ~ $ICP(0,ex,im,new)&lt;br /&gt;
&lt;br /&gt;
==$INCP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;is not command parameter&amp;quot;) - Vergleicht den Parameter des Kommandos mit dem im zweiten oder weiteren Parameter angegebenen Wert; Unterschiede in Groß- und Kleinschreibung werden dabei nicht berücksichtigt. Gibt Y zurück, wenn der Parameter mit keinem der Vergleichswerte übereinstimmt.&lt;br /&gt;
&lt;br /&gt;
Wird fast immer in Verbindung mit Verzweigungsbedingungen verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Parameters. 0-relativ, der erste Parameter hat somit die Nummer 0.&lt;br /&gt;
# und Folgende: Vergleichswerte&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INCP(0,ex)&lt;br /&gt;
 ~ $INCP(0,ex,im,new)&lt;br /&gt;
&lt;br /&gt;
=Internes=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen werden für interne Zwecke verwendet:&lt;br /&gt;
&lt;br /&gt;
* $INTER() - Name des Interpreters&lt;br /&gt;
* $HISTSQL() - SQL-Statement für den History-Dialog&lt;br /&gt;
* $HISTTABLE() - Tabellenname der History-Tabelle&lt;br /&gt;
* $HISTMEMOFIELD() - Feldname des Memo-Feldes für den History-Dialog&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Interpreter&amp;diff=22549</id>
		<title>Interpreter</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Interpreter&amp;diff=22549"/>
		<updated>2025-11-26T16:27:04Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #tab_new */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Im Interpreter sind nur wenige Prozeduren und Funktionen direkt implementiert. Die meisten Routinen finden sich in den Modulen.&lt;br /&gt;
&lt;br /&gt;
=Values=&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Variablen ist der Gültigkeitsbereich von Values auf das jeweilige (Primär- oder Sub-) Kommando beschränkt. Values haben Nummern, während Variable Namen haben.&lt;br /&gt;
&lt;br /&gt;
==#val_set==&lt;br /&gt;
&lt;br /&gt;
Setzt der Wert für einen Value.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Der Value wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie (if empty) - Wenn der Wert von z leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei Oracle; Funktionen werden ersetzt&lt;br /&gt;
*n - Nummer des Values&lt;br /&gt;
*r (rights) - Der Value wird nur dann gesetzt, wenn das Recht vorliegt; default ist ''frm''&lt;br /&gt;
*rf (replace functions) - Wenn Y, dann werden nach der Zuweisung auf den Value nochmals die Funktionen ersetzt. Wird zum Beispiel benötigt, wenn Code mit Funktionen mittels $DATA() aus der Datenbank geladen wird; Funktionen werden ersetzt, default N; siehe Beispiel&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=7   z=$GUID()&lt;br /&gt;
 #val_set   n=1   z=$GUID()   r=admin&lt;br /&gt;
&lt;br /&gt;
 -- Zum Parameter rf: $NOW() in die Zwischenablage kopieren und dann ausführen&lt;br /&gt;
 #val_set   n=1  z=$CLIPBOARD()   rf=N&lt;br /&gt;
 #message   c=$VAL(1)&lt;br /&gt;
 #val_set   n=1  z=$CLIPBOARD()   rf=Y&lt;br /&gt;
 #message   c=$VAL(1)&lt;br /&gt;
&lt;br /&gt;
==#val_add==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#val_add fügt einem Value einen Wert hinzu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Der Value wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*n - Nummer des Values; zwingend erforderlich&lt;br /&gt;
*r (rights) - Der Value wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. &lt;br /&gt;
* y -Typ der Operation; default ''text''&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
*z - Wert, welcher dem Value hinzugefügt wird, Funktionen werden ersetzt, default ist ein leerer String oder eine 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=$NOW()&lt;br /&gt;
 #val_add   n=1   z=1   y=datetime&lt;br /&gt;
 #cout   c=$VAL(1)&lt;br /&gt;
&lt;br /&gt;
==#val_clearall==&lt;br /&gt;
&lt;br /&gt;
Löscht alle Values. Wird selten benötigt, da die Values mit Ende des (Primär- oder Sub-) Kommandos ohnehin ihre Gültigkeit verlieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_clearall&lt;br /&gt;
&lt;br /&gt;
==$VAL()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Inhalt eines Values zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Values&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout c=$VAL(3)&lt;br /&gt;
&lt;br /&gt;
==$EMPTYVAL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Value ein leerer String ist, dessen Nummer im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Values&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTYVAL(1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$NEMPTYVAL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Value kein leerer String ist, dessen Nummer im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Values&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $NEMPTYVAL(2)&lt;br /&gt;
&lt;br /&gt;
=Log=&lt;br /&gt;
&lt;br /&gt;
==#exception_info==&lt;br /&gt;
&lt;br /&gt;
Tritt eine Exception auf, dann wird die entsprechende Fehlermeldung in das Log geschrieben. Mit #exception_info kann eine Information ergänzt werden, die vor diese Fehlermeldung gesetzt wird. Üblicherweise wird das dazu verwendet, um eine ID zu schreiben, damit der fehlerhafte Datensatz gefunden wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* z - Wert, welcher vor die Fehlermeldung geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #exception_info   z=$DATA(dat,knd_nr)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==#log==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Text in das Log.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der in das Log geschrieben wird; Funktionen werden ersetzt; default ist ''#log, Parameter c nicht gesetzt''&lt;br /&gt;
* y - Typ des Log-Eintrags; default I. Vorgesehen sind die folgenden Typen:&lt;br /&gt;
** E - Error&lt;br /&gt;
** I - Info&lt;br /&gt;
** W - Warning&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #log   y=W   c=&amp;quot;Ermittelte Summe untypisch gering&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#logi==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Text als Info in das Log.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #logi hat keine benannten Parameter. Der komplette Text nach dem #logi und dem folgenden Leerzeichen wird in das Log geschrieben; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #logi   Berechnung beendet&lt;br /&gt;
&lt;br /&gt;
=Kommandos=&lt;br /&gt;
&lt;br /&gt;
==#tab_new==&lt;br /&gt;
&lt;br /&gt;
Öffnet einen neuen Tab im BAF-Client und führt dort ein Kommando aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des neuen Tabs; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das im neuen Tab ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tab_new   c=xuser   cmd=xuser($PAGE(link))&lt;br /&gt;
&lt;br /&gt;
==$CP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;command parameter&amp;quot;) - Greift auf einen Parameter des Kommandos zu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Parameters. 0-relativ, der erste Parameter hat somit die Nummer 0.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_fill  d=$CP(1)&lt;br /&gt;
&lt;br /&gt;
==$ICP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;is command parameter&amp;quot;) - Vergleicht den Parameter des Kommandos mit dem im zweiten oder weiteren Parameter angegebenen Wert; Unterschiede in Groß- und Kleinschreibung werden dabei nicht berücksichtigt. Gibt Y zurück, wenn der Parameter mit einem der Vergleichswerte übereinstimmt.&lt;br /&gt;
&lt;br /&gt;
Wird fast immer in Verbindung mit Verzweigungsbedingungen verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Parameters. 0-relativ, der erste Parameter hat somit die Nummer 0.&lt;br /&gt;
# und Folgende: Vergleichswerte&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $ICP(0,ex)&lt;br /&gt;
 ~ $ICP(0,ex,im,new)&lt;br /&gt;
&lt;br /&gt;
==$INCP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;is not command parameter&amp;quot;) - Vergleicht den Parameter des Kommandos mit dem im zweiten oder weiteren Parameter angegebenen Wert; Unterschiede in Groß- und Kleinschreibung werden dabei nicht berücksichtigt. Gibt Y zurück, wenn der Parameter mit keinem der Vergleichswerte übereinstimmt.&lt;br /&gt;
&lt;br /&gt;
Wird fast immer in Verbindung mit Verzweigungsbedingungen verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Parameters. 0-relativ, der erste Parameter hat somit die Nummer 0.&lt;br /&gt;
# und Folgende: Vergleichswerte&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INCP(0,ex)&lt;br /&gt;
 ~ $INCP(0,ex,im,new)&lt;br /&gt;
&lt;br /&gt;
=Internes=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen werden für interne Zwecke verwendet:&lt;br /&gt;
&lt;br /&gt;
* $INTER() - Name des Interpreters&lt;br /&gt;
* $HISTSQL() - SQL-Statement für den History-Dialog&lt;br /&gt;
* $HISTTABLE() - Tabellenname der History-Tabelle&lt;br /&gt;
* $HISTMEMOFIELD() - Feldname des Memo-Feldes für den History-Dialog&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22548</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22548"/>
		<updated>2025-11-14T13:49:24Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #sgrd_node */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ca1, ca2... (characters allowed) - Zeichen, die bei der Eingabe über die Tastatur erlaubt sind; wenn leer, sind alle Zeichen erlaubt; default leer; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* rof1, rof2... (&amp;quot;read only field&amp;quot;) - Feldname der Spalte, aus dem die Read-Only-Funktion bezogen wird; Funktionen werden ersetzt&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ca (characters allowed) - Zeichen, die bei der Eingabe über die Tastatur erlaubt sind; wenn leer, sind alle Zeichen erlaubt; default leer; Funktionen werden ersetzt&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, aus dem die Daten bei q=text bezogen werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** text - die Daten werden aus dem mit dem Parameter n spezifizierten Text bezogen. Mögliche Werte für den Parameter f sind ''text'' (ganze Zeile), ''key'' (vor dem Gleichheitszeichen) und ''value'' (nach dem Gleichheitszeichen)&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Name der Variablen oder Nummer des Values, in die/den die Anzahl der erzeugten Zeilen geschrieben wird&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Kategorie, Funktionen werden ersetzt. Nur bei y=kat&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer der Kategorie-Valueliste; default 1, Funktionen werden ersetzt&lt;br /&gt;
* y - Type. Default sql, Funktionen werden ersetzt&lt;br /&gt;
** kat - die Werte kommen aus einer Kategorie-Valueliste.&lt;br /&gt;
** sql - die Werte kommen aus einem SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Kategorie-Valueliste'''&lt;br /&gt;
&lt;br /&gt;
 #sql select t.tournr as ckat, s.bus_haltestelle_id as ckey, s.land || ' ' || s.plz || ' ' || s.ort || ' - ' || s.beschreibung as cvalue, h.position&lt;br /&gt;
 #sql   from bus_touren t&lt;br /&gt;
 #sql     inner join bus_tour_hs h   on h.bus_touren_id = t.bus_touren_id   and h.status &amp;lt; 7   and (h.position &amp;lt; 99   or t.tournr between 30000 and 40000)&lt;br /&gt;
 #sql     inner join bus_haltestelle s   on s.bus_haltestelle_id = h.haltestelle   and s.status = 1   and s.land &amp;lt;&amp;gt; &lt;br /&gt;
 #sql   where t.kuerzel = '$FND(s,kuerzel)'   and t.datum = to_date('$FND(s,datum)', 'dd.mm.yyyy') &lt;br /&gt;
 #sql   order by 1, 4&lt;br /&gt;
 #sql_openkvl   n=1&lt;br /&gt;
&lt;br /&gt;
Für die Nachschlageliste wird dann wie folgt formuliert:&lt;br /&gt;
&lt;br /&gt;
 #grd_lookuplivefill   y=kat   n=1   k=$PVAL(pl,tournr,lookuplive)&lt;br /&gt;
&lt;br /&gt;
==#grd_lookupliveclear==&lt;br /&gt;
&lt;br /&gt;
Setzt das Flag, dass die LokupLive-Nachschlagelisten neu gefüllt werden müssen. Kann beim Einsatz von #page_val erforderlich werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
keine&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_lookupliveclear&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, dann wird die erste Zeile (die Zeile mit den Spaltenüberschriften) nicht eingelesen; default N, Funktionen werden ersetzt.&lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;condition count&amp;quot;) - Anzahl der Bedingungen bei y=gridcache, Default 1, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd1, cnd2 - Bedingungen bei y=gridcache. Die Bedingung besteht komma-separiert aus der Funktion und den Parametern&lt;br /&gt;
** eq (&amp;quot;equals&amp;quot;) - Werte müssen übereinstimmen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_gdd - Datum im Grid muss zwischen den beiden Datumswerten in der Datenmenge liegen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
** date_ggd - Datum in der Datenmenge muss zwischen den beiden Datumswerten im Grid liegen; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_ggdd - Datumsbereich im Grid und Datumsbereich in der Datenmenge brauchen eine Schnittmenge; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 4: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben. Bei y=gridcache nicht erforderlich&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** grdcache - Mit einem SQL-Statement wird ein Cache aufgebaut, aus dem dann mit den Konditions abgefragt wird; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #sql select r.servicecode, r.servicedescription, case r.exttype when 'PBUS' then 'Bus' when 'PFLUG' then 'Flug' end as exttype, j.erster_fahrtag, j.letzter_fahrtag&lt;br /&gt;
 #sql   from xr_jahr j&lt;br /&gt;
 #sql     inner join cache_reisen r   on r.cache_reisen_id = j.cache_reisen_id&lt;br /&gt;
 #sql   where extract(year from erster_fahrtag) = $VAR(jahr)   or extract(year from letzter_fahrtag) = $VAR(jahr)&lt;br /&gt;
 #sql   order by servicecode&lt;br /&gt;
 #code   cc=2   cnd1=eq,keycode,servicecode   cnd2=date_ggdd,datum_ab,datum_bis,erster_fahrtag,letzter_fahrtag&lt;br /&gt;
 #grd_thread   y=gridcache   ready=xrlt_page_stationmanager_get_reiseleiter    $CODE$&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$GRD_REGEX==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_REGEX prüft ein Grid-Segment die die Einhaltung eines Regex-Staements in einer bestimmten Spalte. Eignet sich insbesondere für #page_check, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Regex-Statement&lt;br /&gt;
# Optionen&lt;br /&gt;
## e (&amp;quot;allow empty&amp;quot;) - $GRD_REGEX gibt auch Y zurück, wenn der Zellenwert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Aktionscode entspricht nicht den Formatvorgaben&amp;quot;   chk=$GRD_REGEX(reisen,aktionscode,all,[A-Z]{3}\d{4},e)&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* ca1, ca2 (characters allowed) - Zeichen, die bei der Eingabe über die Tastatur erlaubt sind; wenn leer, sind alle Zeichen erlaubt; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22547</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22547"/>
		<updated>2025-11-14T13:48:45Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #vl_line */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ca1, ca2... (characters allowed) - Zeichen, die bei der Eingabe über die Tastatur erlaubt sind; wenn leer, sind alle Zeichen erlaubt; default leer; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* rof1, rof2... (&amp;quot;read only field&amp;quot;) - Feldname der Spalte, aus dem die Read-Only-Funktion bezogen wird; Funktionen werden ersetzt&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ca (characters allowed) - Zeichen, die bei der Eingabe über die Tastatur erlaubt sind; wenn leer, sind alle Zeichen erlaubt; default leer; Funktionen werden ersetzt&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, aus dem die Daten bei q=text bezogen werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** text - die Daten werden aus dem mit dem Parameter n spezifizierten Text bezogen. Mögliche Werte für den Parameter f sind ''text'' (ganze Zeile), ''key'' (vor dem Gleichheitszeichen) und ''value'' (nach dem Gleichheitszeichen)&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Name der Variablen oder Nummer des Values, in die/den die Anzahl der erzeugten Zeilen geschrieben wird&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Kategorie, Funktionen werden ersetzt. Nur bei y=kat&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer der Kategorie-Valueliste; default 1, Funktionen werden ersetzt&lt;br /&gt;
* y - Type. Default sql, Funktionen werden ersetzt&lt;br /&gt;
** kat - die Werte kommen aus einer Kategorie-Valueliste.&lt;br /&gt;
** sql - die Werte kommen aus einem SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Kategorie-Valueliste'''&lt;br /&gt;
&lt;br /&gt;
 #sql select t.tournr as ckat, s.bus_haltestelle_id as ckey, s.land || ' ' || s.plz || ' ' || s.ort || ' - ' || s.beschreibung as cvalue, h.position&lt;br /&gt;
 #sql   from bus_touren t&lt;br /&gt;
 #sql     inner join bus_tour_hs h   on h.bus_touren_id = t.bus_touren_id   and h.status &amp;lt; 7   and (h.position &amp;lt; 99   or t.tournr between 30000 and 40000)&lt;br /&gt;
 #sql     inner join bus_haltestelle s   on s.bus_haltestelle_id = h.haltestelle   and s.status = 1   and s.land &amp;lt;&amp;gt; &lt;br /&gt;
 #sql   where t.kuerzel = '$FND(s,kuerzel)'   and t.datum = to_date('$FND(s,datum)', 'dd.mm.yyyy') &lt;br /&gt;
 #sql   order by 1, 4&lt;br /&gt;
 #sql_openkvl   n=1&lt;br /&gt;
&lt;br /&gt;
Für die Nachschlageliste wird dann wie folgt formuliert:&lt;br /&gt;
&lt;br /&gt;
 #grd_lookuplivefill   y=kat   n=1   k=$PVAL(pl,tournr,lookuplive)&lt;br /&gt;
&lt;br /&gt;
==#grd_lookupliveclear==&lt;br /&gt;
&lt;br /&gt;
Setzt das Flag, dass die LokupLive-Nachschlagelisten neu gefüllt werden müssen. Kann beim Einsatz von #page_val erforderlich werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
keine&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_lookupliveclear&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, dann wird die erste Zeile (die Zeile mit den Spaltenüberschriften) nicht eingelesen; default N, Funktionen werden ersetzt.&lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;condition count&amp;quot;) - Anzahl der Bedingungen bei y=gridcache, Default 1, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd1, cnd2 - Bedingungen bei y=gridcache. Die Bedingung besteht komma-separiert aus der Funktion und den Parametern&lt;br /&gt;
** eq (&amp;quot;equals&amp;quot;) - Werte müssen übereinstimmen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_gdd - Datum im Grid muss zwischen den beiden Datumswerten in der Datenmenge liegen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
** date_ggd - Datum in der Datenmenge muss zwischen den beiden Datumswerten im Grid liegen; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_ggdd - Datumsbereich im Grid und Datumsbereich in der Datenmenge brauchen eine Schnittmenge; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 4: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben. Bei y=gridcache nicht erforderlich&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** grdcache - Mit einem SQL-Statement wird ein Cache aufgebaut, aus dem dann mit den Konditions abgefragt wird; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #sql select r.servicecode, r.servicedescription, case r.exttype when 'PBUS' then 'Bus' when 'PFLUG' then 'Flug' end as exttype, j.erster_fahrtag, j.letzter_fahrtag&lt;br /&gt;
 #sql   from xr_jahr j&lt;br /&gt;
 #sql     inner join cache_reisen r   on r.cache_reisen_id = j.cache_reisen_id&lt;br /&gt;
 #sql   where extract(year from erster_fahrtag) = $VAR(jahr)   or extract(year from letzter_fahrtag) = $VAR(jahr)&lt;br /&gt;
 #sql   order by servicecode&lt;br /&gt;
 #code   cc=2   cnd1=eq,keycode,servicecode   cnd2=date_ggdd,datum_ab,datum_bis,erster_fahrtag,letzter_fahrtag&lt;br /&gt;
 #grd_thread   y=gridcache   ready=xrlt_page_stationmanager_get_reiseleiter    $CODE$&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$GRD_REGEX==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_REGEX prüft ein Grid-Segment die die Einhaltung eines Regex-Staements in einer bestimmten Spalte. Eignet sich insbesondere für #page_check, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Regex-Statement&lt;br /&gt;
# Optionen&lt;br /&gt;
## e (&amp;quot;allow empty&amp;quot;) - $GRD_REGEX gibt auch Y zurück, wenn der Zellenwert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Aktionscode entspricht nicht den Formatvorgaben&amp;quot;   chk=$GRD_REGEX(reisen,aktionscode,all,[A-Z]{3}\d{4},e)&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22546</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22546"/>
		<updated>2025-11-14T13:48:04Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #grd_col */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* rof1, rof2... (&amp;quot;read only field&amp;quot;) - Feldname der Spalte, aus dem die Read-Only-Funktion bezogen wird; Funktionen werden ersetzt&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ca (characters allowed) - Zeichen, die bei der Eingabe über die Tastatur erlaubt sind; wenn leer, sind alle Zeichen erlaubt; default leer; Funktionen werden ersetzt&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, aus dem die Daten bei q=text bezogen werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** text - die Daten werden aus dem mit dem Parameter n spezifizierten Text bezogen. Mögliche Werte für den Parameter f sind ''text'' (ganze Zeile), ''key'' (vor dem Gleichheitszeichen) und ''value'' (nach dem Gleichheitszeichen)&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Name der Variablen oder Nummer des Values, in die/den die Anzahl der erzeugten Zeilen geschrieben wird&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Kategorie, Funktionen werden ersetzt. Nur bei y=kat&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer der Kategorie-Valueliste; default 1, Funktionen werden ersetzt&lt;br /&gt;
* y - Type. Default sql, Funktionen werden ersetzt&lt;br /&gt;
** kat - die Werte kommen aus einer Kategorie-Valueliste.&lt;br /&gt;
** sql - die Werte kommen aus einem SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Kategorie-Valueliste'''&lt;br /&gt;
&lt;br /&gt;
 #sql select t.tournr as ckat, s.bus_haltestelle_id as ckey, s.land || ' ' || s.plz || ' ' || s.ort || ' - ' || s.beschreibung as cvalue, h.position&lt;br /&gt;
 #sql   from bus_touren t&lt;br /&gt;
 #sql     inner join bus_tour_hs h   on h.bus_touren_id = t.bus_touren_id   and h.status &amp;lt; 7   and (h.position &amp;lt; 99   or t.tournr between 30000 and 40000)&lt;br /&gt;
 #sql     inner join bus_haltestelle s   on s.bus_haltestelle_id = h.haltestelle   and s.status = 1   and s.land &amp;lt;&amp;gt; &lt;br /&gt;
 #sql   where t.kuerzel = '$FND(s,kuerzel)'   and t.datum = to_date('$FND(s,datum)', 'dd.mm.yyyy') &lt;br /&gt;
 #sql   order by 1, 4&lt;br /&gt;
 #sql_openkvl   n=1&lt;br /&gt;
&lt;br /&gt;
Für die Nachschlageliste wird dann wie folgt formuliert:&lt;br /&gt;
&lt;br /&gt;
 #grd_lookuplivefill   y=kat   n=1   k=$PVAL(pl,tournr,lookuplive)&lt;br /&gt;
&lt;br /&gt;
==#grd_lookupliveclear==&lt;br /&gt;
&lt;br /&gt;
Setzt das Flag, dass die LokupLive-Nachschlagelisten neu gefüllt werden müssen. Kann beim Einsatz von #page_val erforderlich werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
keine&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_lookupliveclear&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, dann wird die erste Zeile (die Zeile mit den Spaltenüberschriften) nicht eingelesen; default N, Funktionen werden ersetzt.&lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;condition count&amp;quot;) - Anzahl der Bedingungen bei y=gridcache, Default 1, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd1, cnd2 - Bedingungen bei y=gridcache. Die Bedingung besteht komma-separiert aus der Funktion und den Parametern&lt;br /&gt;
** eq (&amp;quot;equals&amp;quot;) - Werte müssen übereinstimmen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_gdd - Datum im Grid muss zwischen den beiden Datumswerten in der Datenmenge liegen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
** date_ggd - Datum in der Datenmenge muss zwischen den beiden Datumswerten im Grid liegen; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_ggdd - Datumsbereich im Grid und Datumsbereich in der Datenmenge brauchen eine Schnittmenge; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 4: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben. Bei y=gridcache nicht erforderlich&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** grdcache - Mit einem SQL-Statement wird ein Cache aufgebaut, aus dem dann mit den Konditions abgefragt wird; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #sql select r.servicecode, r.servicedescription, case r.exttype when 'PBUS' then 'Bus' when 'PFLUG' then 'Flug' end as exttype, j.erster_fahrtag, j.letzter_fahrtag&lt;br /&gt;
 #sql   from xr_jahr j&lt;br /&gt;
 #sql     inner join cache_reisen r   on r.cache_reisen_id = j.cache_reisen_id&lt;br /&gt;
 #sql   where extract(year from erster_fahrtag) = $VAR(jahr)   or extract(year from letzter_fahrtag) = $VAR(jahr)&lt;br /&gt;
 #sql   order by servicecode&lt;br /&gt;
 #code   cc=2   cnd1=eq,keycode,servicecode   cnd2=date_ggdd,datum_ab,datum_bis,erster_fahrtag,letzter_fahrtag&lt;br /&gt;
 #grd_thread   y=gridcache   ready=xrlt_page_stationmanager_get_reiseleiter    $CODE$&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$GRD_REGEX==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_REGEX prüft ein Grid-Segment die die Einhaltung eines Regex-Staements in einer bestimmten Spalte. Eignet sich insbesondere für #page_check, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Regex-Statement&lt;br /&gt;
# Optionen&lt;br /&gt;
## e (&amp;quot;allow empty&amp;quot;) - $GRD_REGEX gibt auch Y zurück, wenn der Zellenwert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Aktionscode entspricht nicht den Formatvorgaben&amp;quot;   chk=$GRD_REGEX(reisen,aktionscode,all,[A-Z]{3}\d{4},e)&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_XLS&amp;diff=22545</id>
		<title>Modul XLS</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_XLS&amp;diff=22545"/>
		<updated>2025-11-14T11:07:43Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #xls_sheet */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=XLS=&lt;br /&gt;
&lt;br /&gt;
Im Modul XLS werden die Routinen zusammengefasst, die zur Erstellung von Dateien im Excel- oder OpenOffice Calc-Format verwendet werden. Es können auch Dateien geöffnet und ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
==#xls_start==&lt;br /&gt;
&lt;br /&gt;
Startet den Export einer Excel-Datei.&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_sd_xls&amp;quot;   y=console &lt;br /&gt;
 &lt;br /&gt;
 #xls_start&lt;br /&gt;
 #xls_sheet c=&amp;quot;BAF Demo&amp;quot;&lt;br /&gt;
 #xls_row&lt;br /&gt;
 #xls_cell   z=Text&lt;br /&gt;
 #xls_cell   z=Text   w=200   fc=red&lt;br /&gt;
 #xls_row&lt;br /&gt;
 #xls_cell   z=Datum&lt;br /&gt;
 #xls_cell   y=datemin   z=$NOW()&lt;br /&gt;
 #xls_row&lt;br /&gt;
 #xls_cell   z=Zahl&lt;br /&gt;
 #xls_cell   y=curr   z=3,14&lt;br /&gt;
 &lt;br /&gt;
 #xls_stop&lt;br /&gt;
 #cout  c=&amp;quot;c_sd_xls executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#xls_load==&lt;br /&gt;
&lt;br /&gt;
Lädt eine Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname; wenn leer, wird ein Datei-Dialog geöffnet; Default leer, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #xls_load   fn=c:\temp\$VAR(filename)&lt;br /&gt;
&lt;br /&gt;
==#xls_stop==&lt;br /&gt;
&lt;br /&gt;
Beendet den Export und speichert die Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname, unter dem die Datei gespeichert wird; Funktionen werden ersetzt. Aus der Endung ergibt sich dann der Typ der Datei. Wenn der Parameter leer bleibt, öffnet sich ein Dateiauswahldialog zum Speichern.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Wenn Y, word wird nach der Erstellung gleich geöffnet; default Y, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
(siehe #xls_start)&lt;br /&gt;
&lt;br /&gt;
==#xls_sheet==&lt;br /&gt;
&lt;br /&gt;
Fügt der Datei ein (weiteres) Sheet hinzu oder selektiert ein Sheet. Alle weiteren #xls_row-Prozeduren fügen dann diesem Sheet Reihen hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Tabs&lt;br /&gt;
* fc (&amp;quot;fixed cols&amp;quot;) - Anzahl der Spalten, die links fixiert werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* fr (&amp;quot;fixed rows&amp;quot;) - Anzahl der Zeilen, die oben fixiert werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - 0-relativer Index des Sheets, das selektiert werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #xls_sheet c=&amp;quot;Daten&amp;quot;   fr=1&lt;br /&gt;
 #xls_sheet   n=0&lt;br /&gt;
&lt;br /&gt;
==#xls_delete_sheet==&lt;br /&gt;
&lt;br /&gt;
Löscht das aktuelle Sheet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #xls_delete_sheet cnd=$INVAR(zeilenzahl,0)&lt;br /&gt;
&lt;br /&gt;
==#xls_row==&lt;br /&gt;
&lt;br /&gt;
Fügt dem aktuellen Sheet eine weitere Reihe hinzu oder selektiert eine solche.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* h (height) - Höhe der Zelle; default 20, Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - 0-relativer Index der Reihe, die selektiert werden soll&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
(siehe #xls_start)&lt;br /&gt;
&lt;br /&gt;
==#xls_cell==&lt;br /&gt;
&lt;br /&gt;
Fügt der aktuellen Reihe eine weitere Zelle hinzu oder schreibt den Wert der mit n spezifizierten.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (&amp;quot;align&amp;quot;) - Ausrichtung des Textes / des Wertes in der Zelle&lt;br /&gt;
** c (&amp;quot;center&amp;quot;) - mittig&lt;br /&gt;
** d2 / d4 (decimal) - ausgerichtet am Komma für zwei oder vier Nachkommastellen&lt;br /&gt;
** l (&amp;quot;left&amp;quot;) - linksbündig&lt;br /&gt;
** r (&amp;quot;right&amp;quot;) - rechtsbündig&lt;br /&gt;
* bt, bl, br, bb (&amp;quot;border top&amp;quot;, &amp;quot;border left&amp;quot;, &amp;quot;border right&amp;quot;, &amp;quot;border bottom&amp;quot;) - Ränder der Zelle, default thin, Funktionen werden ersetzt (auto, none, thin, medium, dashed, dotted, thick, double, hair, mediumdashed, dashdotted, mediumdashdotted, dashdotdotted, mediumdashdotdotted, slanteddashdotted)&lt;br /&gt;
* cl (&amp;quot;color&amp;quot;) - Farbe der Zelle; default weiß&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* cs (&amp;quot;ColSpan&amp;quot;) - Anzahl der Spalten, die zusammengefasst werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* fc (&amp;quot;FontColor&amp;quot;) - Farbe der Schrift; default schwarz&lt;br /&gt;
n (&amp;quot;number&amp;quot;) - 0-relativer Index der Spalte, die geschrieben werden soll; wenn leer, wird eine neue Zelle hinzugefügt; default leer, Funktionen werden ersetzt&lt;br /&gt;
* va (&amp;quot;vertivcal align&amp;quot;) - vertikale Ausrichtung des Textes; default t, Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;bottom&amp;quot;) - unten&lt;br /&gt;
** c (&amp;quot;center&amp;quot;) - mittig&lt;br /&gt;
** t (&amp;quot;top&amp;quot;) - oben&lt;br /&gt;
* fs (&amp;quot;FontStyle&amp;quot;) - Style der Schrift, die einzelnen Optionen können kombiniert werden; default keine Option&lt;br /&gt;
** b - bold&lt;br /&gt;
** i - italic&lt;br /&gt;
** u - underline&lt;br /&gt;
** s - strikeout&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Zelle&lt;br /&gt;
* y - Typ der Zelle, default Text&lt;br /&gt;
** curr - Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum und Uhrzeit ohne Sekunden&lt;br /&gt;
** datesek - Datum und Uhrzeit mit Sekunden&lt;br /&gt;
** int - Zahlen ohne Nachkommastellen&lt;br /&gt;
** text - Text&lt;br /&gt;
* z - Wert/Text, der in der Zelle eingefügt werden soll; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #xls_cell   z=Text   w=200   fc=red&lt;br /&gt;
 #xls_cell   y=datemin   z=$NOW()&lt;br /&gt;
&lt;br /&gt;
==#xls_looprows==&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y; Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Transaktion bezieht; Funktionen werden ersetzt&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen; Funktionen werden ersetzt&lt;br /&gt;
* m - (&amp;quot;maximum&amp;quot;) Es wird maximal für die Anzahl der angegebenen Zeilen das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten; Funktionen werden ersetzt&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N; Funktionen werden ersetzt.&lt;br /&gt;
* n - Name der Variablen, in welche die aktuelle, 0-relative Schleifennummer geschrieben wird&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #xls_looprows   er=sof_7836_line   m_=5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==#xls_page==&lt;br /&gt;
&lt;br /&gt;
Exportiert alle VL-, Grid- und XGrid-Segmente der aktuellen Seite. Für jedes Segment wird eine neues Sheet angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=xls   s=#xls_page   se=b&lt;br /&gt;
&lt;br /&gt;
==$XLS_COUNT()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Anzahl der Sheets, Zeilen oder Zellen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Von was wird die Anzahl ermittelt&lt;br /&gt;
## sheets - Sheets in einer Datei&lt;br /&gt;
## rows - Zeilen in einem Sheet&lt;br /&gt;
## cells - Zellen in einer Zeile&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;Dieses Sheet hat $XLS_COUNT(rows) Zeilen&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$XLS_CELL()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Zelle aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Index der Zelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=$XLS_CELL(0)&lt;br /&gt;
 &lt;br /&gt;
 ~ $INTLEN($VAL(1)) = 9&lt;br /&gt;
 #var_add   n=zeile   z=1   y=int&lt;br /&gt;
 #cout   c=&amp;quot;$VAL(1)   -   $VAR(datei) / $VAR(zeile)&amp;quot;   m=20   md=10&lt;br /&gt;
 #sql_upsert   y=a   t=neuland.sof_7836   k=adrnr   f_adrnr=$VAL(1)   hst=N&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Beispiel: XLSX-Datei mit Daten anreichern==&lt;br /&gt;
&lt;br /&gt;
===Kommando c_fp_lieferanten===&lt;br /&gt;
&lt;br /&gt;
Öffnet die Datei c:\temp\lieferanten.xlsx und geht durch alle vorhandenen Zeilen mit Ausnahme der Titelzeile (darum lf=1). Danach öffnet sich ein Datei-Dialog, um die Datei abzuspeichern.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_fp_lieferanten&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #xls_load   fn=c:\temp\lieferanten.xlsx&lt;br /&gt;
 #xls_sheet   n=0&lt;br /&gt;
 &lt;br /&gt;
 #loop   lf=1   lt=$ICALC(-,$XLS_COUNT(rows),1)   er=c_fp_lieferanten_line   n=loopvar&lt;br /&gt;
 &lt;br /&gt;
 #xls_stop&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_fp_lieferanten executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Sub-Kommando c_fp_lieferanten_line===&lt;br /&gt;
&lt;br /&gt;
Zunächst wird die korrekte Zeile gesetzt, die ist 0-relativ anzugeben. Die Lieferantennummer ist in der zweiten Spalte, das wird mit $XLS_CELL(1) ausgelesen und auch gleich ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile im Ausgangs-Sheet ist eine Summenzeile und hat keine Lieferantennummer, darum wird darauf geprüft. Mit einer einfachen SQL-Abfrage werden Steuernummer, Umsatzsteuer-ID und IBAN abgefragt und in Values zwischengespeichert. Diese werden dann in die dafür vorgesehenen Zellen geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #xls_row   n=$VAR(loopvar)&lt;br /&gt;
 #cout   c=$XLS_CELL(1)&lt;br /&gt;
 &lt;br /&gt;
 ~ $NEMPTY($XLS_CELL(1))&lt;br /&gt;
 #sql select iban, coast_steuernr, coast_ustid from cache_lieferant &lt;br /&gt;
 #sql   where lieferant_number = $XLS_CELL(1)&lt;br /&gt;
 #sql_openval    f_iban=1   f_coast_steuernr=2   f_coast_ustid=3&lt;br /&gt;
 &lt;br /&gt;
 #xls_cell   n=4   z=$VAL(3)&lt;br /&gt;
 #xls_cell   n=5   z=$VAL(2)&lt;br /&gt;
 #xls_cell   n=11   z=$VAL(1)&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22544</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22544"/>
		<updated>2025-11-13T11:16:41Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #grd_lookuplivefill */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* rof1, rof2... (&amp;quot;read only field&amp;quot;) - Feldname der Spalte, aus dem die Read-Only-Funktion bezogen wird; Funktionen werden ersetzt&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, aus dem die Daten bei q=text bezogen werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** text - die Daten werden aus dem mit dem Parameter n spezifizierten Text bezogen. Mögliche Werte für den Parameter f sind ''text'' (ganze Zeile), ''key'' (vor dem Gleichheitszeichen) und ''value'' (nach dem Gleichheitszeichen)&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Name der Variablen oder Nummer des Values, in die/den die Anzahl der erzeugten Zeilen geschrieben wird&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Kategorie, Funktionen werden ersetzt. Nur bei y=kat&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer der Kategorie-Valueliste; default 1, Funktionen werden ersetzt&lt;br /&gt;
* y - Type. Default sql, Funktionen werden ersetzt&lt;br /&gt;
** kat - die Werte kommen aus einer Kategorie-Valueliste.&lt;br /&gt;
** sql - die Werte kommen aus einem SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Kategorie-Valueliste'''&lt;br /&gt;
&lt;br /&gt;
 #sql select t.tournr as ckat, s.bus_haltestelle_id as ckey, s.land || ' ' || s.plz || ' ' || s.ort || ' - ' || s.beschreibung as cvalue, h.position&lt;br /&gt;
 #sql   from bus_touren t&lt;br /&gt;
 #sql     inner join bus_tour_hs h   on h.bus_touren_id = t.bus_touren_id   and h.status &amp;lt; 7   and (h.position &amp;lt; 99   or t.tournr between 30000 and 40000)&lt;br /&gt;
 #sql     inner join bus_haltestelle s   on s.bus_haltestelle_id = h.haltestelle   and s.status = 1   and s.land &amp;lt;&amp;gt; &lt;br /&gt;
 #sql   where t.kuerzel = '$FND(s,kuerzel)'   and t.datum = to_date('$FND(s,datum)', 'dd.mm.yyyy') &lt;br /&gt;
 #sql   order by 1, 4&lt;br /&gt;
 #sql_openkvl   n=1&lt;br /&gt;
&lt;br /&gt;
Für die Nachschlageliste wird dann wie folgt formuliert:&lt;br /&gt;
&lt;br /&gt;
 #grd_lookuplivefill   y=kat   n=1   k=$PVAL(pl,tournr,lookuplive)&lt;br /&gt;
&lt;br /&gt;
==#grd_lookupliveclear==&lt;br /&gt;
&lt;br /&gt;
Setzt das Flag, dass die LokupLive-Nachschlagelisten neu gefüllt werden müssen. Kann beim Einsatz von #page_val erforderlich werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
keine&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_lookupliveclear&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, dann wird die erste Zeile (die Zeile mit den Spaltenüberschriften) nicht eingelesen; default N, Funktionen werden ersetzt.&lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;condition count&amp;quot;) - Anzahl der Bedingungen bei y=gridcache, Default 1, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd1, cnd2 - Bedingungen bei y=gridcache. Die Bedingung besteht komma-separiert aus der Funktion und den Parametern&lt;br /&gt;
** eq (&amp;quot;equals&amp;quot;) - Werte müssen übereinstimmen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_gdd - Datum im Grid muss zwischen den beiden Datumswerten in der Datenmenge liegen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
** date_ggd - Datum in der Datenmenge muss zwischen den beiden Datumswerten im Grid liegen; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_ggdd - Datumsbereich im Grid und Datumsbereich in der Datenmenge brauchen eine Schnittmenge; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 4: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben. Bei y=gridcache nicht erforderlich&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** grdcache - Mit einem SQL-Statement wird ein Cache aufgebaut, aus dem dann mit den Konditions abgefragt wird; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #sql select r.servicecode, r.servicedescription, case r.exttype when 'PBUS' then 'Bus' when 'PFLUG' then 'Flug' end as exttype, j.erster_fahrtag, j.letzter_fahrtag&lt;br /&gt;
 #sql   from xr_jahr j&lt;br /&gt;
 #sql     inner join cache_reisen r   on r.cache_reisen_id = j.cache_reisen_id&lt;br /&gt;
 #sql   where extract(year from erster_fahrtag) = $VAR(jahr)   or extract(year from letzter_fahrtag) = $VAR(jahr)&lt;br /&gt;
 #sql   order by servicecode&lt;br /&gt;
 #code   cc=2   cnd1=eq,keycode,servicecode   cnd2=date_ggdd,datum_ab,datum_bis,erster_fahrtag,letzter_fahrtag&lt;br /&gt;
 #grd_thread   y=gridcache   ready=xrlt_page_stationmanager_get_reiseleiter    $CODE$&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$GRD_REGEX==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_REGEX prüft ein Grid-Segment die die Einhaltung eines Regex-Staements in einer bestimmten Spalte. Eignet sich insbesondere für #page_check, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Regex-Statement&lt;br /&gt;
# Optionen&lt;br /&gt;
## e (&amp;quot;allow empty&amp;quot;) - $GRD_REGEX gibt auch Y zurück, wenn der Zellenwert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Aktionscode entspricht nicht den Formatvorgaben&amp;quot;   chk=$GRD_REGEX(reisen,aktionscode,all,[A-Z]{3}\d{4},e)&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22543</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22543"/>
		<updated>2025-11-10T08:10:00Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #grd_thread */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* rof1, rof2... (&amp;quot;read only field&amp;quot;) - Feldname der Spalte, aus dem die Read-Only-Funktion bezogen wird; Funktionen werden ersetzt&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, aus dem die Daten bei q=text bezogen werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** text - die Daten werden aus dem mit dem Parameter n spezifizierten Text bezogen. Mögliche Werte für den Parameter f sind ''text'' (ganze Zeile), ''key'' (vor dem Gleichheitszeichen) und ''value'' (nach dem Gleichheitszeichen)&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Name der Variablen oder Nummer des Values, in die/den die Anzahl der erzeugten Zeilen geschrieben wird&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Kategorie, Funktionen werden ersetzt. Nur bei y=kat&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer der Kategorie-Valueliste; default 1, Funktionen werden ersetzt&lt;br /&gt;
* y - Type. Default sql, Funktionen werden ersetzt&lt;br /&gt;
** kat - die Werte kommen aus einer Kategorie-Valueliste.&lt;br /&gt;
** sql - die Werte kommen aus einem SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Kategorie-Valueliste'''&lt;br /&gt;
&lt;br /&gt;
 #sql select t.tournr as ckat, s.bus_haltestelle_id as ckey, s.land || ' ' || s.plz || ' ' || s.ort || ' - ' || s.beschreibung as cvalue, h.position&lt;br /&gt;
 #sql   from bus_touren t&lt;br /&gt;
 #sql     inner join bus_tour_hs h   on h.bus_touren_id = t.bus_touren_id   and h.status &amp;lt; 7   and (h.position &amp;lt; 99   or t.tournr between 30000 and 40000)&lt;br /&gt;
 #sql     inner join bus_haltestelle s   on s.bus_haltestelle_id = h.haltestelle   and s.status = 1   and s.land &amp;lt;&amp;gt; &lt;br /&gt;
 #sql   where t.kuerzel = '$FND(s,kuerzel)'   and t.datum = to_date('$FND(s,datum)', 'dd.mm.yyyy') &lt;br /&gt;
 #sql   order by 1, 4&lt;br /&gt;
 #sql_openkvl   n=1&lt;br /&gt;
&lt;br /&gt;
Für die Nachschlageliste wird dann wie folgt formuliert:&lt;br /&gt;
&lt;br /&gt;
 #grd_lookuplivefill   y=kat   n=1   k=$PVAL(pl,tournr,lookuplive)&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, dann wird die erste Zeile (die Zeile mit den Spaltenüberschriften) nicht eingelesen; default N, Funktionen werden ersetzt.&lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;condition count&amp;quot;) - Anzahl der Bedingungen bei y=gridcache, Default 1, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd1, cnd2 - Bedingungen bei y=gridcache. Die Bedingung besteht komma-separiert aus der Funktion und den Parametern&lt;br /&gt;
** eq (&amp;quot;equals&amp;quot;) - Werte müssen übereinstimmen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_gdd - Datum im Grid muss zwischen den beiden Datumswerten in der Datenmenge liegen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
** date_ggd - Datum in der Datenmenge muss zwischen den beiden Datumswerten im Grid liegen; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_ggdd - Datumsbereich im Grid und Datumsbereich in der Datenmenge brauchen eine Schnittmenge; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 4: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben. Bei y=gridcache nicht erforderlich&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** grdcache - Mit einem SQL-Statement wird ein Cache aufgebaut, aus dem dann mit den Konditions abgefragt wird; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #sql select r.servicecode, r.servicedescription, case r.exttype when 'PBUS' then 'Bus' when 'PFLUG' then 'Flug' end as exttype, j.erster_fahrtag, j.letzter_fahrtag&lt;br /&gt;
 #sql   from xr_jahr j&lt;br /&gt;
 #sql     inner join cache_reisen r   on r.cache_reisen_id = j.cache_reisen_id&lt;br /&gt;
 #sql   where extract(year from erster_fahrtag) = $VAR(jahr)   or extract(year from letzter_fahrtag) = $VAR(jahr)&lt;br /&gt;
 #sql   order by servicecode&lt;br /&gt;
 #code   cc=2   cnd1=eq,keycode,servicecode   cnd2=date_ggdd,datum_ab,datum_bis,erster_fahrtag,letzter_fahrtag&lt;br /&gt;
 #grd_thread   y=gridcache   ready=xrlt_page_stationmanager_get_reiseleiter    $CODE$&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$GRD_REGEX==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_REGEX prüft ein Grid-Segment die die Einhaltung eines Regex-Staements in einer bestimmten Spalte. Eignet sich insbesondere für #page_check, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Regex-Statement&lt;br /&gt;
# Optionen&lt;br /&gt;
## e (&amp;quot;allow empty&amp;quot;) - $GRD_REGEX gibt auch Y zurück, wenn der Zellenwert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Aktionscode entspricht nicht den Formatvorgaben&amp;quot;   chk=$GRD_REGEX(reisen,aktionscode,all,[A-Z]{3}\d{4},e)&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22542</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22542"/>
		<updated>2025-11-10T08:08:42Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #grd_thread */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* rof1, rof2... (&amp;quot;read only field&amp;quot;) - Feldname der Spalte, aus dem die Read-Only-Funktion bezogen wird; Funktionen werden ersetzt&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, aus dem die Daten bei q=text bezogen werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** text - die Daten werden aus dem mit dem Parameter n spezifizierten Text bezogen. Mögliche Werte für den Parameter f sind ''text'' (ganze Zeile), ''key'' (vor dem Gleichheitszeichen) und ''value'' (nach dem Gleichheitszeichen)&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Name der Variablen oder Nummer des Values, in die/den die Anzahl der erzeugten Zeilen geschrieben wird&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Kategorie, Funktionen werden ersetzt. Nur bei y=kat&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer der Kategorie-Valueliste; default 1, Funktionen werden ersetzt&lt;br /&gt;
* y - Type. Default sql, Funktionen werden ersetzt&lt;br /&gt;
** kat - die Werte kommen aus einer Kategorie-Valueliste.&lt;br /&gt;
** sql - die Werte kommen aus einem SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Kategorie-Valueliste'''&lt;br /&gt;
&lt;br /&gt;
 #sql select t.tournr as ckat, s.bus_haltestelle_id as ckey, s.land || ' ' || s.plz || ' ' || s.ort || ' - ' || s.beschreibung as cvalue, h.position&lt;br /&gt;
 #sql   from bus_touren t&lt;br /&gt;
 #sql     inner join bus_tour_hs h   on h.bus_touren_id = t.bus_touren_id   and h.status &amp;lt; 7   and (h.position &amp;lt; 99   or t.tournr between 30000 and 40000)&lt;br /&gt;
 #sql     inner join bus_haltestelle s   on s.bus_haltestelle_id = h.haltestelle   and s.status = 1   and s.land &amp;lt;&amp;gt; &lt;br /&gt;
 #sql   where t.kuerzel = '$FND(s,kuerzel)'   and t.datum = to_date('$FND(s,datum)', 'dd.mm.yyyy') &lt;br /&gt;
 #sql   order by 1, 4&lt;br /&gt;
 #sql_openkvl   n=1&lt;br /&gt;
&lt;br /&gt;
Für die Nachschlageliste wird dann wie folgt formuliert:&lt;br /&gt;
&lt;br /&gt;
 #grd_lookuplivefill   y=kat   n=1   k=$PVAL(pl,tournr,lookuplive)&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, dann wird die erste Zeile (die Zeile mit den Spaltenüberschriften) nicht eingelesen; default N, Funktionen werden ersetzt.&lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;condition count&amp;quot;) - Anzahl der Bedingungen bei y=gridcache, Default 1, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd1, cnd2 - Bedingungen bei y=gridcache. Die Bedingung besteht komma-separiert aus der Funktion und den Parametern&lt;br /&gt;
** eq (&amp;quot;equals&amp;quot;) - Werte müssen übereinstimmen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_gdd - Datum im Grid muss zwischen den beiden Datumswerten in der Datenmenge liegen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
** date_ggd - Datum in der Datenmenge muss zwischen den beiden Datumswerten im Grid liegen; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_ggdd - Datumsbereich im Grid und Datumsbereich in der Datenmenge brauchen eine Schnittmenge; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 4: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** grdcache - Mit einem SQL-Statement wird ein Cache aufgebaut, aus dem dann mit den Konditions abgefragt wird; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #sql select r.servicecode, r.servicedescription, case r.exttype when 'PBUS' then 'Bus' when 'PFLUG' then 'Flug' end as exttype, j.erster_fahrtag, j.letzter_fahrtag&lt;br /&gt;
 #sql   from xr_jahr j&lt;br /&gt;
 #sql     inner join cache_reisen r   on r.cache_reisen_id = j.cache_reisen_id&lt;br /&gt;
 #sql   where extract(year from erster_fahrtag) = $VAR(jahr)   or extract(year from letzter_fahrtag) = $VAR(jahr)&lt;br /&gt;
 #sql   order by servicecode&lt;br /&gt;
 #code   cc=2   cnd1=eq,keycode,servicecode   cnd2=date_ggdd,datum_ab,datum_bis,erster_fahrtag,letzter_fahrtag&lt;br /&gt;
 #grd_thread   y=gridcache   ready=xrlt_page_stationmanager_get_reiseleiter    $CODE$&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$GRD_REGEX==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_REGEX prüft ein Grid-Segment die die Einhaltung eines Regex-Staements in einer bestimmten Spalte. Eignet sich insbesondere für #page_check, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Regex-Statement&lt;br /&gt;
# Optionen&lt;br /&gt;
## e (&amp;quot;allow empty&amp;quot;) - $GRD_REGEX gibt auch Y zurück, wenn der Zellenwert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Aktionscode entspricht nicht den Formatvorgaben&amp;quot;   chk=$GRD_REGEX(reisen,aktionscode,all,[A-Z]{3}\d{4},e)&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22541</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22541"/>
		<updated>2025-11-10T08:07:52Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #grd_thread */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* rof1, rof2... (&amp;quot;read only field&amp;quot;) - Feldname der Spalte, aus dem die Read-Only-Funktion bezogen wird; Funktionen werden ersetzt&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, aus dem die Daten bei q=text bezogen werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** text - die Daten werden aus dem mit dem Parameter n spezifizierten Text bezogen. Mögliche Werte für den Parameter f sind ''text'' (ganze Zeile), ''key'' (vor dem Gleichheitszeichen) und ''value'' (nach dem Gleichheitszeichen)&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Name der Variablen oder Nummer des Values, in die/den die Anzahl der erzeugten Zeilen geschrieben wird&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Kategorie, Funktionen werden ersetzt. Nur bei y=kat&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer der Kategorie-Valueliste; default 1, Funktionen werden ersetzt&lt;br /&gt;
* y - Type. Default sql, Funktionen werden ersetzt&lt;br /&gt;
** kat - die Werte kommen aus einer Kategorie-Valueliste.&lt;br /&gt;
** sql - die Werte kommen aus einem SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Kategorie-Valueliste'''&lt;br /&gt;
&lt;br /&gt;
 #sql select t.tournr as ckat, s.bus_haltestelle_id as ckey, s.land || ' ' || s.plz || ' ' || s.ort || ' - ' || s.beschreibung as cvalue, h.position&lt;br /&gt;
 #sql   from bus_touren t&lt;br /&gt;
 #sql     inner join bus_tour_hs h   on h.bus_touren_id = t.bus_touren_id   and h.status &amp;lt; 7   and (h.position &amp;lt; 99   or t.tournr between 30000 and 40000)&lt;br /&gt;
 #sql     inner join bus_haltestelle s   on s.bus_haltestelle_id = h.haltestelle   and s.status = 1   and s.land &amp;lt;&amp;gt; &lt;br /&gt;
 #sql   where t.kuerzel = '$FND(s,kuerzel)'   and t.datum = to_date('$FND(s,datum)', 'dd.mm.yyyy') &lt;br /&gt;
 #sql   order by 1, 4&lt;br /&gt;
 #sql_openkvl   n=1&lt;br /&gt;
&lt;br /&gt;
Für die Nachschlageliste wird dann wie folgt formuliert:&lt;br /&gt;
&lt;br /&gt;
 #grd_lookuplivefill   y=kat   n=1   k=$PVAL(pl,tournr,lookuplive)&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, dann wird die erste Zeile (die Zeile mit den Spaltenüberschriften) nicht eingelesen; default N, Funktionen werden ersetzt.&lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;condition count&amp;quot;) - Anzahl der Bedingungen bei y=gridcache, Default 1, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd1, cnd2 - Bedingungen bei y=gridcache. Die Bedingung besteht komma-separiert aus der Funktion und den Parametern&lt;br /&gt;
** eq (&amp;quot;equals&amp;quot;) - Werte müssen übereinstimmen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_gdd - Datum im Grid muss zwischen den beiden Datumswerten in der Datenmenge liegen; Parameter 1: Spaltennamen im Grid; Parameter 2: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
** date_ggd - Datum in der Datenmenge muss zwischen den beiden Datumswerten im Grid liegen; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge&lt;br /&gt;
** date_ggdd - Datumsbereich im Grid und Datumsbereich in der Datenmenge brauchen eine Schnittmenge; Parameter 1: Spaltennamen im Grid für die untere Datumsgrenze; Parameter 2: Spaltennamen im Grid für die obere Datumsgrenze; Parameter 3: Spaltennamen in der Datenmenge für die untere Datumsgrenze; Parameter 4: Spaltennamen in der Datenmenge für die obere Datumsgrenze&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** grdcache - Mit einem SQL-Statement wird ein Cache aufgebaut, aus dem dann mit den Konditions abgefragt wird; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #sql select r.servicecode, r.servicedescription, case r.exttype when 'PBUS' then 'Bus' when 'PFLUG' then 'Flug' end as exttype, j.erster_fahrtag, j.letzter_fahrtag&lt;br /&gt;
 #sql   from xr_jahr j&lt;br /&gt;
 #sql     inner join cache_reisen r   on r.cache_reisen_id = j.cache_reisen_id&lt;br /&gt;
 #sql   where extract(year from erster_fahrtag) = 2025   or extract(year from letzter_fahrtag) = 2025   &lt;br /&gt;
 #sql   order by servicecode&lt;br /&gt;
 #code   cc=2   cnd1=eq,keycode,servicecode   cnd2=date_ggdd,datum_ab,datum_bis,erster_fahrtag,letzter_fahrtag&lt;br /&gt;
 #grd_thread   y=gridcache   ready=xrlt_page_stationmanager_get_reiseleiter    $CODE$&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$GRD_REGEX==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_REGEX prüft ein Grid-Segment die die Einhaltung eines Regex-Staements in einer bestimmten Spalte. Eignet sich insbesondere für #page_check, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Regex-Statement&lt;br /&gt;
# Optionen&lt;br /&gt;
## e (&amp;quot;allow empty&amp;quot;) - $GRD_REGEX gibt auch Y zurück, wenn der Zellenwert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Aktionscode entspricht nicht den Formatvorgaben&amp;quot;   chk=$GRD_REGEX(reisen,aktionscode,all,[A-Z]{3}\d{4},e)&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22540</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22540"/>
		<updated>2025-10-29T09:03:41Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #grd_paste */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* rof1, rof2... (&amp;quot;read only field&amp;quot;) - Feldname der Spalte, aus dem die Read-Only-Funktion bezogen wird; Funktionen werden ersetzt&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, aus dem die Daten bei q=text bezogen werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** text - die Daten werden aus dem mit dem Parameter n spezifizierten Text bezogen. Mögliche Werte für den Parameter f sind ''text'' (ganze Zeile), ''key'' (vor dem Gleichheitszeichen) und ''value'' (nach dem Gleichheitszeichen)&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Name der Variablen oder Nummer des Values, in die/den die Anzahl der erzeugten Zeilen geschrieben wird&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Kategorie, Funktionen werden ersetzt. Nur bei y=kat&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer der Kategorie-Valueliste; default 1, Funktionen werden ersetzt&lt;br /&gt;
* y - Type. Default sql, Funktionen werden ersetzt&lt;br /&gt;
** kat - die Werte kommen aus einer Kategorie-Valueliste.&lt;br /&gt;
** sql - die Werte kommen aus einem SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Kategorie-Valueliste'''&lt;br /&gt;
&lt;br /&gt;
 #sql select t.tournr as ckat, s.bus_haltestelle_id as ckey, s.land || ' ' || s.plz || ' ' || s.ort || ' - ' || s.beschreibung as cvalue, h.position&lt;br /&gt;
 #sql   from bus_touren t&lt;br /&gt;
 #sql     inner join bus_tour_hs h   on h.bus_touren_id = t.bus_touren_id   and h.status &amp;lt; 7   and (h.position &amp;lt; 99   or t.tournr between 30000 and 40000)&lt;br /&gt;
 #sql     inner join bus_haltestelle s   on s.bus_haltestelle_id = h.haltestelle   and s.status = 1   and s.land &amp;lt;&amp;gt; &lt;br /&gt;
 #sql   where t.kuerzel = '$FND(s,kuerzel)'   and t.datum = to_date('$FND(s,datum)', 'dd.mm.yyyy') &lt;br /&gt;
 #sql   order by 1, 4&lt;br /&gt;
 #sql_openkvl   n=1&lt;br /&gt;
&lt;br /&gt;
Für die Nachschlageliste wird dann wie folgt formuliert:&lt;br /&gt;
&lt;br /&gt;
 #grd_lookuplivefill   y=kat   n=1   k=$PVAL(pl,tournr,lookuplive)&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, dann wird die erste Zeile (die Zeile mit den Spaltenüberschriften) nicht eingelesen; default N, Funktionen werden ersetzt.&lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$GRD_REGEX==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_REGEX prüft ein Grid-Segment die die Einhaltung eines Regex-Staements in einer bestimmten Spalte. Eignet sich insbesondere für #page_check, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Regex-Statement&lt;br /&gt;
# Optionen&lt;br /&gt;
## e (&amp;quot;allow empty&amp;quot;) - $GRD_REGEX gibt auch Y zurück, wenn der Zellenwert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Aktionscode entspricht nicht den Formatvorgaben&amp;quot;   chk=$GRD_REGEX(reisen,aktionscode,all,[A-Z]{3}\d{4},e)&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22539</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22539"/>
		<updated>2025-10-10T07:21:32Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #grd_lookuplivefill */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* rof1, rof2... (&amp;quot;read only field&amp;quot;) - Feldname der Spalte, aus dem die Read-Only-Funktion bezogen wird; Funktionen werden ersetzt&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, aus dem die Daten bei q=text bezogen werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** text - die Daten werden aus dem mit dem Parameter n spezifizierten Text bezogen. Mögliche Werte für den Parameter f sind ''text'' (ganze Zeile), ''key'' (vor dem Gleichheitszeichen) und ''value'' (nach dem Gleichheitszeichen)&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Name der Variablen oder Nummer des Values, in die/den die Anzahl der erzeugten Zeilen geschrieben wird&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Kategorie, Funktionen werden ersetzt. Nur bei y=kat&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer der Kategorie-Valueliste; default 1, Funktionen werden ersetzt&lt;br /&gt;
* y - Type. Default sql, Funktionen werden ersetzt&lt;br /&gt;
** kat - die Werte kommen aus einer Kategorie-Valueliste.&lt;br /&gt;
** sql - die Werte kommen aus einem SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Kategorie-Valueliste'''&lt;br /&gt;
&lt;br /&gt;
 #sql select t.tournr as ckat, s.bus_haltestelle_id as ckey, s.land || ' ' || s.plz || ' ' || s.ort || ' - ' || s.beschreibung as cvalue, h.position&lt;br /&gt;
 #sql   from bus_touren t&lt;br /&gt;
 #sql     inner join bus_tour_hs h   on h.bus_touren_id = t.bus_touren_id   and h.status &amp;lt; 7   and (h.position &amp;lt; 99   or t.tournr between 30000 and 40000)&lt;br /&gt;
 #sql     inner join bus_haltestelle s   on s.bus_haltestelle_id = h.haltestelle   and s.status = 1   and s.land &amp;lt;&amp;gt; &lt;br /&gt;
 #sql   where t.kuerzel = '$FND(s,kuerzel)'   and t.datum = to_date('$FND(s,datum)', 'dd.mm.yyyy') &lt;br /&gt;
 #sql   order by 1, 4&lt;br /&gt;
 #sql_openkvl   n=1&lt;br /&gt;
&lt;br /&gt;
Für die Nachschlageliste wird dann wie folgt formuliert:&lt;br /&gt;
&lt;br /&gt;
 #grd_lookuplivefill   y=kat   n=1   k=$PVAL(pl,tournr,lookuplive)&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$GRD_REGEX==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_REGEX prüft ein Grid-Segment die die Einhaltung eines Regex-Staements in einer bestimmten Spalte. Eignet sich insbesondere für #page_check, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Regex-Statement&lt;br /&gt;
# Optionen&lt;br /&gt;
## e (&amp;quot;allow empty&amp;quot;) - $GRD_REGEX gibt auch Y zurück, wenn der Zellenwert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Aktionscode entspricht nicht den Formatvorgaben&amp;quot;   chk=$GRD_REGEX(reisen,aktionscode,all,[A-Z]{3}\d{4},e)&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22538</id>
		<title>Modul VAR neu</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22538"/>
		<updated>2025-10-06T15:52:49Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #exec */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das Modul Var sammelt neben den Variablen auch die grundlegenden Prozeduren und Funktionen.&lt;br /&gt;
&lt;br /&gt;
=Variable=&lt;br /&gt;
&lt;br /&gt;
==#var_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#setvar setzt den Wert einer Variablen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis: Variable sind global, auf sie kann auch in Sub-Kommandos zugegriffen werden. Values sind dagegen lokal.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*rf (replace functions) - Wenn Y, dann werden nach der Zuweisung auf die Variable nochmals die Funktionen ersetzt. Wird zum Beispiel benötigt, wenn Code mit Funktionen mittels $DATA() aus der Datenbank geladen wird; Funktionen werden ersetzt, default N; siehe Beispiel&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_set   n=test2  z=$GUID()&lt;br /&gt;
 #var_set   n=edt    z=$EDT(edt1)   ie=42&lt;br /&gt;
 #var_set   n=_page_kunde_adressänderung_ro   z=N   zn=Y   zr=Y   r=kundenservice&lt;br /&gt;
&lt;br /&gt;
Zum Parameter rf: $NOW() in die Zwischenablage kopieren und dann ausführen:&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=N&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=Y&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_setempty==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_setempty setzt den Wert einer Variablen, sofern sie (noch) leer ist.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Besteht der Variableninhalt aus Leerzeichen, gilt die Variable auch als leer.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_setempty   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_setempty   n=test2  z=$GUID()&lt;br /&gt;
 #var_setempty   n=edt    z=$EDT(edt1)    ie=42&lt;br /&gt;
&lt;br /&gt;
==#var_add==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_add fügt einer Variablen einen Wert hinzu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. &lt;br /&gt;
* y -Typ der Operation; default ''text''&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** month - Es wird dem Datum eine Anzahl von Monaten hinzugefügt&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
*z - Wert, welcher der Variablen hinzugefügt wird, Funktionen werden ersetzt, default ist ein leerer String oder eine 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$NOW()&lt;br /&gt;
 #var_add   n=test   z=1   y=datetime&lt;br /&gt;
 #cout   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_log==&lt;br /&gt;
&lt;br /&gt;
Schreibt den Inhalt aller Variablen in das Debug-Log.&lt;br /&gt;
&lt;br /&gt;
Wird nur zur Fehlersuche verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_log&lt;br /&gt;
&lt;br /&gt;
==$VAR()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $VAR() wird auf den Inhalt der Variable zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
# optional: Der Wert wird vor oder nach der Rückgabe als Funktionsergebnis verändert; nur für ganzzahlige Werte&lt;br /&gt;
## ib (&amp;quot;increment before&amp;quot;) - Der Wert wird vor der Rückgabe um eins erhöht&lt;br /&gt;
## db (&amp;quot;decrement before&amp;quot;) - Der Wert wird vor der Rückgabe um eins verringert&lt;br /&gt;
## ia (&amp;quot;increment after&amp;quot;) - Der Wert wird nach der Rückgabe um eins erhöht&lt;br /&gt;
## da (&amp;quot;decrement after&amp;quot;) - Der Wert wird nach der Rückgabe um eins verringert&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #message  c=$VAR(test)&lt;br /&gt;
 #var_set  n=neuer_wert   z=$VAR(wert)   ie=$VAR(alternativwert)&lt;br /&gt;
 #execsql   k_lfdnr=$VAR(lfdnr,ib)&lt;br /&gt;
&lt;br /&gt;
=Kommandos=&lt;br /&gt;
&lt;br /&gt;
(Primär- und Sub) Kommandos sind üblicherweise benannt und werden im Code-Dialog eingegeben.&lt;br /&gt;
&lt;br /&gt;
Es besteht jedoch auch die Möglichkeit, lokale Kommandos innerhalb eines anderen Kommandos zu definieren. Diese Kommandos haben statt eines Kommando-Namens dann dann eine Kommando-Nummer.&lt;br /&gt;
&lt;br /&gt;
Lokale Kommandos werden üblicherweise für folgende Zwecke verwendet:&lt;br /&gt;
&lt;br /&gt;
* Bei der Verwendung von xlive werden bisweilen Prozeduren eingesetzt, die ihrerseits ein Kommando aufrufen (z.B. #sql_open). Wenn dieses Kommando nichts bereits existiert, kann es nur als lokales Kommando erstellt werden.&lt;br /&gt;
&lt;br /&gt;
* Wenn das auszuführende Kommando auf derselben Seite stehen soll wie die aufrufende Prozedur.&lt;br /&gt;
&lt;br /&gt;
Siehe als Beispiel: [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd fügt dem Kommando eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd fügt dem ersten Kommando eine Zeile hinzu, #cmd2 fügt dem zweiten Kommando eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd hat keine benannten Parameter. Die ganze Zeile nach dem #cmd und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd3 #text $DATA(n,login);$DATA(n,shortname);$DATA(n,firstname);$DATA(n,lastname);$DATA(n,userid);&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clear löscht ein Kommando&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd_clear löscht das erste Kommando, #cmd_clear2 löscht das zweite Kommando, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #cmd_clear Zeichen, so werden die dem gerade gelöschten Kommando hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear3&lt;br /&gt;
 #cmd_clear #grd_add   i=grid   f_logtext=&amp;quot;Kunde angerufen und nicht erreicht.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#cmd_clearall==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clearall löscht alle Kommandos&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clearall&lt;br /&gt;
&lt;br /&gt;
=CSV=&lt;br /&gt;
&lt;br /&gt;
Die CSV-Routinen werden verwendet, um CSV-Dateien einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==#csv_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_open öffnet eine CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_open öffnet die erste CSV-Datei, #csv_open2 öffnet die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*ber - wenn Y, werden die Zeilenumbrüche innerhalb von Feldern durch Leerzeichen ersetzt. Die Felder müssen dabei in doppelten Anführungszeichen eingeschlossen sein.&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - (&amp;quot;Filename&amp;quot;) Dateiname der CSV-Datei&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich. Muss bereits hier gesetzt werden, wenn mit $CSV_LINE auf den Header zugegriffen werden soll, bevor #csv_line ausgeführt wird.&lt;br /&gt;
*txt (&amp;quot;Text&amp;quot;) - alternativ zum Dateinamen fn die Nummer eines Textes, der als CSV-Datei verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open  fn=c:\temp\text.csv&lt;br /&gt;
&lt;br /&gt;
==#csv_line==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_line geht zeilenweise durch die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_line geht durch die erste CSV-Datei, #csv_line2 geht durch die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;database&amp;quot;) - Die Datenbank, für welche die Transaktion ausgeführt wird, wenn ert=Y gesetzt ist. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
*er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
*ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt, Funktionen werden ersetzt&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich.&lt;br /&gt;
*m (&amp;quot;maximum&amp;quot;) - Maximale Anzahl der Zeilen, die verarbeitet wird. Wird gerne bei der Entwicklung verwendet, um die Bearbeitungsgeschwindigkeit zu erhöhen. Funktionen werden ersetzt&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird im Falle einer Exception die Bearbeitung nicht abgebrochen, sondern lediglich Warnungen geloggt; Default N, Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Semikolon, Funktionen werden ersetzt&lt;br /&gt;
*trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_line  er=test_csv_line   hhr=Y   m=3&lt;br /&gt;
&lt;br /&gt;
==#csv_check==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_check prüft die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnt (&amp;quot;count&amp;quot;) - Anzahl der Header-Einträge, die geprüft wird; Funktionen werden ersetzt&lt;br /&gt;
*h1, h2... (&amp;quot;header&amp;quot;) - Eintrag im Header, der auf existenz geprüft wird; Groß und Kleinschreibung ist unerheblich, Funktionen werden ersetzt.&lt;br /&gt;
*n (&amp;quot;name&amp;quot; / &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in die/den das Ergebnis (Y oder N) geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*res (&amp;quot;result&amp;quot;) - Name der Variable oder Nummer des Values, in die/den der Ergebnistext geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwischen den einzelnen Spalten; Funktionen werden ersetzt&lt;br /&gt;
*y - Typ der Prüfung; Funktionen werden ersetzt, default header&lt;br /&gt;
** header - Prüft die Existenz von Spaltennamen im Header. Die zu prüfenden Spaltennamen werden als h1, h2... übergeben, cnt ist entsprechend zu setzen. Wenn alle geprüften Spaltennamen vorhanden sind, wird Y zurück gegeben, ansonsten N. Die fehlenden Spaltennamen werden als Ergebnistext zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open   fn=C:\temp\mad\done\MTF3108_ET2607_selektion.CSV&lt;br /&gt;
 #csv_check   n=1   res=2   cnt=3   h1=eins   h2=zwei   h3=drei&lt;br /&gt;
 #coutl $VAL(1) - $VAL(2)&lt;br /&gt;
&lt;br /&gt;
==#csv_paste==&lt;br /&gt;
&lt;br /&gt;
Übernimmt eine CSV-Datei aus der Zwischenablage. Auf die Werte kann mit $SEPLINE() zugegriffen werden, siehe [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
'''Multi-Row'''&lt;br /&gt;
&lt;br /&gt;
Mit dem Multi-Row-Modus können Daten eingelesen werden, die in einer Zeile mehrere gleichartige Werte haben.&lt;br /&gt;
&lt;br /&gt;
Daten, die im Single-Row-Modus wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465&lt;br /&gt;
 01.01.2020     8574&lt;br /&gt;
 01.01.2020     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     3456&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     4457&lt;br /&gt;
 03.01.2020     7658&lt;br /&gt;
&lt;br /&gt;
Würden im Multi-Row-Modus wie folgt aussehen (und könnten auch so eingelesen werden):&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465     8574     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436     6578     3456     6578     4457     7658&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Wenn dieser Parameter einen Wert hat, dann muss die kopierte CSV-Datei in der ersten Zeile auch diesen Wert haben, oder die Aktion wird abgebrochen; Funktionen werden ersetzt&lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden.&lt;br /&gt;
* mrs (&amp;quot;multi row start&amp;quot;) - Erste Spalte für den Multi-Row-Bereich&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Tabulatorzeichen&lt;br /&gt;
* trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ; default s&lt;br /&gt;
** m - multi; siehe Abschnitt Multi-Row&lt;br /&gt;
** s - single; die CSV-Datei wird Zeile für Zeile eingelesen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
* [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
 #csv_paste   er=imp_line   hhr=Y&lt;br /&gt;
 #csv_paste   er=imp_line   y=m   mrs=1&lt;br /&gt;
&lt;br /&gt;
==$CSV()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV() greift auf einen Feldinhalt der aktuellen CSV-Zeile zu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Spalte oder 0-relative Spaltennummer. Name der Spalte setzt voraus, dass bei #csv_line der Parameter hhr gleich Y ist.&lt;br /&gt;
# optional: Stelle der Zeichens, ab dem der Inhalt des CSV-Feldes zurück gegeben wird&lt;br /&gt;
# optional: Anzahl der Zeichen, die maximal zurück gegeben werden; wird meist dafür verwendet, damit die maximale Länge von Datenbankfeldern nicht überschritten wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0)&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird in der ersten CSV-Datei (#csv_open) auf die erste Spalte (0, da 0-relativ) zugegriffen.&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0,1,30)&lt;br /&gt;
&lt;br /&gt;
Wie oben, nur werden nur die ersten 30 Zeichen zurück gegeben&lt;br /&gt;
&lt;br /&gt;
==$CSV_LINE()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV_LINE() Gibt eine ganze Zeile einer CSV-Datei zurück&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Zeile: header gibt die Header-Zeile zurück, current die aktuelle Zeile in #csv_line&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CSV_LINE wird insbesondere dafür verwendet, um CSV-Dateien mit Daten zu ergänzen. Hier im Beispiel wird jede Zeile mit einer GUID ergänzt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #text $CSV_LINE(1,current)$GUID();&lt;br /&gt;
 &lt;br /&gt;
 #csv_open   fn=c:\temp\ex.csv   hhr=Y&lt;br /&gt;
 #text_clear $CSV_LINE(1,header)guid;&lt;br /&gt;
 #csv_line   er=1   hhr=Y&lt;br /&gt;
 &lt;br /&gt;
 #text_save   fn=c:\temp\ex2.csv&lt;br /&gt;
&lt;br /&gt;
Nach dem Öffnen der bestehenden CSV-Datei (es muss hier bereits hhr gesetzt werden) wird zunächst der Header in Text 1 eingefügt, ergänzt um die Spalte ''guid'' und das abschließende Semikolon. Danach gehen wir mit #csv_line durch alle Zeile, fügen diese komplett in Text 1 ein und hängen eine GUID hinten dran. Danach wird die Datei gespeichert.&lt;br /&gt;
&lt;br /&gt;
=Text=&lt;br /&gt;
&lt;br /&gt;
==#text==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text fügt dem Text eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text fügt dem ersten Text eine Zeile hinzu, #text2 fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Und jetzt noch eine GUID: $GUID()&lt;br /&gt;
 #text Der folgende Text kommt in Großbuchstaben: $UPP(hello world)&lt;br /&gt;
&lt;br /&gt;
==#textn==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#textn fügt dem Text eine Zeile hinzu. Im Unterschied zu #text werden dabei keine Funktionen ersetzt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #textn fügt dem ersten Text eine Zeile hinzu, #text2n fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #textn und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden dabei '''nicht''' ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #textn Zeile 1&lt;br /&gt;
 #textn Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_clear löscht einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_clear löscht den ersten Text, #text_clear2 löscht den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #text_clear Zeichen, so werden die dem gerade gelöschten Text hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear7&lt;br /&gt;
 #text7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
Das vorangestellt #text_clear stellt sicher, dass Text7 leer ist. Alternativ könnte man formulieren:&lt;br /&gt;
&lt;br /&gt;
 #text_clear7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_save==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_save speichert einen Text in einer Datei.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_save speichert den ersten Text, #text_save2 speichert den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* bom (&amp;quot;Byte order mark&amp;quot;) - Wenn Y, dann wird die Datei mit BOM geschrieben; default Y&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu speichernden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname, unter dem die Datei gespeichert wird. Bestehende Dateien werden überschrieben, sofern das Betriebssystem das nicht verhindert (z.B, weil die Datei gerade geöffnet ist)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Öffnet die gespeicherte Datei gleich anschließend.&lt;br /&gt;
*sort - Wenn Y, dann wird die Datei vor dem Speichern sortiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Hello world&lt;br /&gt;
 #text_save  fn=$DIR(userroot)hello_world.txt&lt;br /&gt;
 #text_save  fn=c:\temp\export_vert_export.prepared_.csv   e=utf8   bom=N&lt;br /&gt;
&lt;br /&gt;
==#text_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_open öffnet einen Text aus einer Datei, der bisherige Inhalt der Datei wird überschrieben.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_open öffnet den ersten Text, #text_open2 öffnet den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname der Datei, die geöffnet wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_open  fn=$DIR(userroot)test.txt&lt;br /&gt;
 #text Eine weitere Zeile, $GUID()&lt;br /&gt;
 #text_save  fn=$DIR(userroot)test.txt&lt;br /&gt;
&lt;br /&gt;
==#text_props==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_props stellt Eigenschaften des Textes ein.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_props bezieht sich auf den ersten Text, #text_props2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* dub (&amp;quot;duplicates&amp;quot;) - Verhalten einer sortierten Liste bezüglich Dubletten&lt;br /&gt;
** acc (&amp;quot;accept&amp;quot;) - Dubletten werden akzeptiert&lt;br /&gt;
** err (&amp;quot;error&amp;quot;) - Dubletten führen zu Fehlern&lt;br /&gt;
** ign (&amp;quot;ignore) - Dubletten werden ignoriert&lt;br /&gt;
* srt (&amp;quot;sorted&amp;quot;) - Wenn ja, dann ist die Liste sortiert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_props   srt=Y   dup=ign&lt;br /&gt;
&lt;br /&gt;
==#text_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_set setzt eine bestimmte Zeile eines Textes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_set bezieht sich auf den ersten Text, #text_set2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;index&amp;quot;) - 0-relativer Index der Zeile, die geschrieben werden soll. Mit ''last'' kann die letzte Zeile geschrieben werden, mit ''all'' werden alle Zeilen ersetzt, das wird dann gebraucht, wenn mehrzeiliger Text zugewiesen werden soll; Funktionen werden ersetzt&lt;br /&gt;
* z - Text, der geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text_set   i=2   z=&amp;quot;dritte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=last   z=&amp;quot;letzte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=all   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
==#text_sort==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_sort sortiert einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_sort bezieht sich auf den ersten Text, #text_sort2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* y - Typ, default alpha, Funktionen werden ersetzt&lt;br /&gt;
** alpha - sortiert alphanumerisch&lt;br /&gt;
** inv - invertiert die gegebene Reihenfolge&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=&amp;quot;,OU=2nd_Level_T1,OU=Kundenservice,OU=Benutzer,OU=Testtours,OU=Travel&amp;quot;&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text_dissect   z=$VAL(1)   sep=&amp;quot;,OU=&amp;quot;&lt;br /&gt;
 #coutl  $TEXT(1)&lt;br /&gt;
 #text_sort   y=inv&lt;br /&gt;
 #text_compose   n=1   sep=.&lt;br /&gt;
 #val_set   n=1   z=tt.$VAL(1)&lt;br /&gt;
 #coutl $VAL(1)&lt;br /&gt;
&lt;br /&gt;
 Ergebnis ist:&lt;br /&gt;
 2nd_Level_T1&lt;br /&gt;
 Kundenservice&lt;br /&gt;
 Benutzer&lt;br /&gt;
 Testtours&lt;br /&gt;
 tt.Testtours.Benutzer.Kundenservice.2nd_Level_T1.&lt;br /&gt;
&lt;br /&gt;
==#text_dissect==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_dissect zerteilt einen String anhand einer vorgegebenen Trennzeichenfolge und fügt das Ergebnis dem betreffenden Text hinzu. Gegebenenfalls muss der Text vorher mit #text_clear geleert werden.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_dissect bezieht sich auf den ersten Text, #text_dissect bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - wenn Y, wird die sep-Zeichenfolge noch mal dem String angehängt; default N, Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, anhand der String zerteilt wird; Funktionen werden ersetzt&lt;br /&gt;
* z - String, der zerlegt wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_compose==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_compose setzt einen Text mithilfe eines Trennzeichens zu einem String zusammen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_compose bezieht sich auf den ersten Text, #text_compose bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - Wenn Y, wird die Trennzeichenfolge auch noch mal am Ende des Strings eingefügt; default N, Funktionen werden ersetzt&lt;br /&gt;
* n - Nummer des Values oder Name der Variable, in welche der String geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichenfolge, die beim Zusammenfügen des Textes verwendet wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_act==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_act bearbeitet einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_act bezieht sich auf den ersten Text, #text_act2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text der Zeile, die bei insert eingefügt werden soll; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* cu (&amp;quot;current&amp;quot;) - 0-relative Zeilennummer der Operation; default 0, Funktionen werden ersetzt&lt;br /&gt;
* ne (&amp;quot;new&amp;quot;) - 0-relative Zeilennummer als Ziel bei move; default 0, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt&lt;br /&gt;
** delete - Löscht die Zeile an Position cu (&amp;quot;current&amp;quot;)&lt;br /&gt;
** insert - Fügt den Text c an der Position cu (&amp;quot;current&amp;quot;) ein&lt;br /&gt;
** move - verschiebt die Zeile cu (&amp;quot;current&amp;quot;) nach Zeile ne (&amp;quot;new&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #text_act   y=move   cu=0&lt;br /&gt;
&lt;br /&gt;
==#text_loop==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_loop geht durch die Zeilen eines Textes und ruft für jede Zeile ''er'' auf&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_loop  bezieht sich auf den ersten Text, #text_loop2  bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich ert bezieht&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m - (&amp;quot;maximum&amp;quot;) Es wird maximal für die Anzahl der angegebenen Zeilen das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* n - Name der Variable, in welche die 0-relative Schleifenvariable geschrieben wird. (Es würde auch in einen Value geschrieben, wenn es sich um eine Nummer handelt, das ergibt in der Praxis aber meist nicht viel Sinn) Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear eins&lt;br /&gt;
 #text zwei&lt;br /&gt;
 #text drei&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear #coutl - $TEXT(1,$VAR(eins))&lt;br /&gt;
 #text_loop   er=1   n=eins&lt;br /&gt;
&lt;br /&gt;
==#tvl_add==&lt;br /&gt;
&lt;br /&gt;
Addiert dem Wert in einer Text-Valueliste einen Wert hinzu. Es handelt sich dabei um eine nummerierte Prozedur: #tvl_add arbeitet mit Text 1, #tvl_add2 mit Text 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Zeile, der ein Wert hinzugefügt wird; Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Operation, Funktionen werden ersetzt, default text&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
* z - Der Wert, der hinzugefügt wird&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text eins=1&lt;br /&gt;
 #text zwei=2&lt;br /&gt;
 #text drei=3&lt;br /&gt;
 #tvl_add   y=int   n=zwei   z=1&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==$TEXT()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $TEXT() wird auf den Inhalt des Textes zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# optional Zeile des Textes (0-relativ). Wenn es keinen zweiten Parameter gibt, wird der komplette Text zurück gegeben. Alternativ als zweiter Parameter eine Sonderfunktion:&lt;br /&gt;
## cnt / count - Gibt die Anzahl der Zeilen zurück&lt;br /&gt;
## last - Gibt die letzte Zeile zurück&lt;br /&gt;
## ix - Gibt die Position des Textes im dritten Parameter zurück&lt;br /&gt;
## as_line - Gibt den Text als eine Zeile zurück, Zeilenumbrüche werden durch den dritten Parameter ersetzt&lt;br /&gt;
# optional in abhängigkeit vom zweiten Paremeter&lt;br /&gt;
## wenn zweiter Parameter ix: Textzeile, nach der mit ix gesucht wird&lt;br /&gt;
## wenn zweiter Parameter as_line: Zeichenfolge, mit der die Zeilenumbrüche ersetzt werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Zeile 3&lt;br /&gt;
 #message  c=$TEXT(1)&lt;br /&gt;
&lt;br /&gt;
 #code url=$TEXT(1,as_line,&amp;amp;)&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich gilt in BAL: Eine Prozedur - eine Zeile.&lt;br /&gt;
&lt;br /&gt;
Bei vielen und/oder langen Parametern führt das zu recht langen Code-Zeilen und zu Unübersichtlichkeit. Hier können nun Teile der Parameter mit #code in weitere Zeile ausgelagert werden, deren Inhalt dann mit $CODE$ oder $CODE$ der eigentlichen Code-Zeile hinzugefügt wird.&lt;br /&gt;
&lt;br /&gt;
==#code==&lt;br /&gt;
&lt;br /&gt;
Fügt Text dem Code-Speicher hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#code hat keine benannten Parameter. Die ganze Zeile nach dem #code und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=G:\pics\pic5d68865cdaba62_62767562.jpg&lt;br /&gt;
 #code fn2=G:\pics\pic5d913c48682128_67979256.jpg&lt;br /&gt;
 #email_send   from=test@****.de   to=info@*****************.de   bcc=info@*****.de   subject=Testmail   text=$TEXT(1)   $CODE$&lt;br /&gt;
&lt;br /&gt;
==$CODE$ / $CODEN$==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CODE$ und $CODEN$ sind keine Funktionen, auch wenn sie auf den ersten Blick ähnlich aussehen. Sie haben keine Parameter und auch keine Klammern, dafür ein abschließendes $.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen fügen den Code-Speicher der jeweiligen Zeile hinzu. $CODE$ löscht danach den Code-Speicher, $CODEN$ tut das nicht, so dass dieselben Parameter wiederholt eingefügt werden können (beim letzten Einfügen sollte dann $CODE$ verwendet werden).&lt;br /&gt;
&lt;br /&gt;
=Separierte Zeile=&lt;br /&gt;
&lt;br /&gt;
Eine separierte Zeile ist eine Textzeile, die mehrere gleichartige Werte enthält, die durch Trennzeichen getrennt sind.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 3244,4465,7763,4536,4356,7777&lt;br /&gt;
&lt;br /&gt;
Solche Zeilen können mit #sepline aufgetrennt werden.&lt;br /&gt;
&lt;br /&gt;
==#sepline==&lt;br /&gt;
&lt;br /&gt;
Trennt eine separierte Zeile auf und führt für jeden Wert das mit er angegebene Kommando aus.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur (#sepline, #sepline2...)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y; Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, für welche die Transaktion gestartet wird, wenn ert=Y. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern (&amp;quot;each row no&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Wenn Y, wird für jeden Wert der separierten Zeile eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Es wird maximal für die Anzahl der angegebenen Werte das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten; Funktionen werden ersetzt.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N; Funktionen werden ersetzt.&lt;br /&gt;
* nn (&amp;quot;not null&amp;quot;) - Wenn Y, dann wird er nur für Werte der separierten Zeile aufgerufen, die nicht leer sind. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Das oder die Trennzeichen; default ist das Semikolon, Funktionen werden ersetzt.&lt;br /&gt;
* z - Der Inhalt der separierten Zeile; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(1)&lt;br /&gt;
 #sepline z=3244,4465,7763,4536,4356,7777   sep=,   er=1&lt;br /&gt;
&lt;br /&gt;
==$SEPLINE()==&lt;br /&gt;
&lt;br /&gt;
Greift auf den einzelnen Wert einer mit #sepline getrennten Zeile zu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der separierten Zeile&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(3)&lt;br /&gt;
 #sepline3 z=3244;4465;7763;4536;4356;7777     er=1&lt;br /&gt;
&lt;br /&gt;
=User und Rechte=&lt;br /&gt;
&lt;br /&gt;
Aus Gründen der Übersichtlichkeit ist die Rechtevergabe zweistufig:&lt;br /&gt;
&lt;br /&gt;
# Es werden (meist am Anfang eines Primär-Kommandos) Rechte-Definitionen erstellt, die einer oder mehreren Benutzergruppen Rechte (lesen oder lesen und schreiben) zuweisen. Die Rechte werden dabei implizit auch allen Untergruppen der angegebenen Benutzergruppe erteilt (Zum Beispiel: Rechte der Gruppe ''user'' hat auch implizit die Gruppe ''user.admin'').&lt;br /&gt;
# Dem Parameter r verschiedener Prozeduren kann dann eine Rechte-Definition zugewiesen werden.&lt;br /&gt;
&lt;br /&gt;
Den Parameter r als Rechte-Definition berücksichtigen die folgenden Prozeduren:&lt;br /&gt;
&lt;br /&gt;
* #frm&lt;br /&gt;
* Buttons (#btn, #btns_btn)&lt;br /&gt;
* Alle Segmente (#text_seg, #memo_seg, #btns_seg, vl_seg, #grd_seg, #xgrd_seg)&lt;br /&gt;
* Tree (#tree_add, #tree_fill, #tree_fillsql, Lese-Recht reicht)&lt;br /&gt;
* Grid-Spalten (#grd_col, #xgrd_col)&lt;br /&gt;
* #vl_line (für die komplette Zeile (r) und die einzelne Zelle (r1, r2, r3...))&lt;br /&gt;
&lt;br /&gt;
Wo der Parameter r nicht gesetzt ist, wird die Rechte-Definition der Formulars verwendet.&lt;br /&gt;
&lt;br /&gt;
==#rights==&lt;br /&gt;
&lt;br /&gt;
Setzt eine Rechte-Definition im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Rechte-Definition; default ist ''frm'', also dsa Default-Recht für das Formular.&lt;br /&gt;
* r_ (&amp;quot;right&amp;quot;) - Prefix für die Benutzergruppe. Für die Rechte-Definition sind die folgenden Werte zulässig&lt;br /&gt;
** n (&amp;quot;no&amp;quot;) - kein Recht&lt;br /&gt;
** r (&amp;quot;read&amp;quot;) - nur lesen&lt;br /&gt;
** w (&amp;quot;write&amp;quot;) - lesen und schreiben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights  n=frm   r_user=r   r_user.admin=w&lt;br /&gt;
&lt;br /&gt;
Setzt für alle User das Lese-Recht und für Administratoren das Lese- und Schreibrecht.&lt;br /&gt;
&lt;br /&gt;
==#rights_clear==&lt;br /&gt;
&lt;br /&gt;
Löscht alle Rechte-Definitionen im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
(Wird in der Praxis selten benötigt, weil Kommandos mit leerer Rechte-Definition starten.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights_clear&lt;br /&gt;
&lt;br /&gt;
==$USERID()==&lt;br /&gt;
&lt;br /&gt;
Die ID des angemeldeten Users&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kusr=$USERID()&lt;br /&gt;
&lt;br /&gt;
==$RIGHTUSERID()==&lt;br /&gt;
&lt;br /&gt;
Administratoren können andere User einstellen (Userliste links unten im BAF-Client), vor allem um deren Rechte zu prüfen. Die UserID dieses ausgewählten Users kann mit der Funktion $RIGHTUSERID() ermittelt werden.&lt;br /&gt;
&lt;br /&gt;
In fast allen Fällen gilt der folgende Grundsatz: Lesende Operationen mit $RIGHTUSERID(), schreibende Operationen mit $USERID().&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_open   kusr=$RIGHTUSERID()&lt;br /&gt;
&lt;br /&gt;
==$ADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der angemeldete User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $ADM()&lt;br /&gt;
&lt;br /&gt;
==$RADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der ausgewählte User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $RADM()&lt;br /&gt;
&lt;br /&gt;
=Ausführen=&lt;br /&gt;
&lt;br /&gt;
==#exec==&lt;br /&gt;
&lt;br /&gt;
Führt ein anderes Kommando aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Names des (Primär- oder Sub-) Kommandos, das ausgeführt werden soll.&lt;br /&gt;
* ex (&amp;quot;exception&amp;quot;) - Name oder Nummer des Kommandos, das ausgeführt wird, wenn bei der Ausführung von cmd eine Exception auftritt; siehe Beispiele&lt;br /&gt;
* fin (&amp;quot;finally&amp;quot;) - Name oder Nummer des Kommandos, das nach der Ausführung von cmd ausgeführt wird - egal ob eine Exception aufgetreten ist oder nicht. Wird nur berücksichtigt, wenn der Parameter ex nicht gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel löst das Problem, dass ein neues PDF unter demselben Dateinamen nicht erstellt werden kann, wenn beim vorherigen Versuche der Erstellung eine Exception aufgetreten ist. In einem solchen Fall wurde ein #pdf_start, aber kein #pdf_stop ausgeführt, und die geöffnete Datei sperrt diesen Dateiname, bis der BAF-Client geschlossen wird. Lösung dieses Problems ist es, im Parameter ex ein #pdf stop auszuführen; auf das Öffnen der Datei kann in einem solchen Fall verzichtet werden. Mit der Funktion $DATA() wird hier im Beispiel gezielt eine Exception ausgelöst.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test_pdf&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #pdf_text  c=&amp;quot;Hello World&amp;quot;&lt;br /&gt;
 -- #cmd #pdf_text  c=&amp;quot;Hello World $DATA(dat,test)&amp;quot;&lt;br /&gt;
 #cmd #pdf_stop   o=Y&lt;br /&gt;
 &lt;br /&gt;
 #pdf_start  fn=$DIR(doc)\test.pdf&lt;br /&gt;
 #exec   cmd=1   ex=&amp;quot;#pdf_stop   o=N&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test_pdf executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#exec_async==&lt;br /&gt;
&lt;br /&gt;
Führt ein anderes Kommando aus, allerdings asynchron (über einen Timer). Das wird beispielsweise dann benötigt, wenn mit einem chg-Parameter eines Grid oder eine VL-Segmentes die Seite neu aufgebaut wird. Würde hier mit #exec gearbeitet, würde nach dem Aufbau der Seite die Ausführung die diesem Segment zurückkehren, das es aber zu diesem Zeitpunkt gar nicht mehr gibt. Mit #exec_async tritt dieses Problem nicht auf.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter sind dieselben wie bei #exec&lt;br /&gt;
&lt;br /&gt;
==#batchexec==&lt;br /&gt;
&lt;br /&gt;
Speichert den Text n in der Datei batch.bat und führt diese aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clr (&amp;quot;clear&amp;quot;) - Wenn Y, wird der Text nach Ausführung des Batch-Datei gelöscht; Default Y; Funktionen werden ersetzt;&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes; der mit #text gespeicherte Text hat die Nummer 1 &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #batchexec   n=1&lt;br /&gt;
&lt;br /&gt;
==#file_open==&lt;br /&gt;
&lt;br /&gt;
Öffnet eine Datei (oder auch eine Webseite)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder die URL der Webseite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_open  fn=c:\temp\test.csv&lt;br /&gt;
 #file_open  fn=https://www.google.de&lt;br /&gt;
&lt;br /&gt;
==#loop==&lt;br /&gt;
&lt;br /&gt;
BAL kennt keine Schleifen als Sprachelement. Um Schleifen mit einer fest Schleifenzahl auszuführen, wird die Prozedur #loop verwendet. lf muss nicht kleiner als lt sein, #loop kann auch von oben nach unten zählen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* lf (&amp;quot;loop from&amp;quot;) - Anfangswert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* lt (&amp;quot;loop to&amp;quot;) - Endwert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in der die Schleifenvariable gespeichert wird (damit sie an anderer Stelle gelesen werden kann); Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #loop   lf=42   lt=1337   er=test_line&lt;br /&gt;
&lt;br /&gt;
==#exit==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #exit bricht die Ausführung auf der jeweiligen Code-Ebene (Kommando bzw. Sub-Kommando) ab&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 ~ $EMPTY($PVAL(vl,id))   and   $PVAL(vl,status) &amp;gt; 20&lt;br /&gt;
 #sql select nextval('ausza_id') as id&lt;br /&gt;
 #sql_openval   f_id=1&lt;br /&gt;
 #page_val   i=vl   f=id   z=$VAL(1)&lt;br /&gt;
 #save&lt;br /&gt;
 #exit&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Der Beispiel-Code befindet sich auf der Seite xausza_page_ausza und baut die entsprechende Seite auf. Er prüft, ob bereits eine ID-Gesetzt ist - wenn nicht, wird über eine Datenbank-Sequenz die nächste ID abgefragt, in das VL-Segment geschrieben und die Seite gespeichert. Beim Speichern der Seite wird sie jedoch neu aufgerufen, also komplett neu aufgebaut, was erst einmal kein Problem ist. Danach würde aber die Ausführung auf der Code-Ebene, auf der sich #save befindet, fortgeführt, was zur Folge hat, dass die dann folgenden Segmente doppelt erscheinen (zunächst die aus dem Neu-Aufbau der Seite, dann die, die von der Fortsetzung des Codes her stammen).&lt;br /&gt;
&lt;br /&gt;
Um dies zu vermeiden muss die Ausführung des Codes nach #save abgebrochen werden.&lt;br /&gt;
&lt;br /&gt;
==$EXEC==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando. Im ausgeführten Kommando kann eine Variable gesetzt werden, die dann als Funktionsergebnis von $EXEC zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll&lt;br /&gt;
# optional: Der Name der Variablen, in der das Ergebnis steht; default ist ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;test_funkexec&amp;quot;   y=console&lt;br /&gt;
 #cout   c=$EXEC(test_funkexec_line)&lt;br /&gt;
&lt;br /&gt;
 -- test_funkexec_line&lt;br /&gt;
 #var_set   n=result   z=42&lt;br /&gt;
&lt;br /&gt;
=Dateien und Verzeichnisse=&lt;br /&gt;
&lt;br /&gt;
==#file_op==&lt;br /&gt;
&lt;br /&gt;
Führt eine Operation mit einer Datei oder einem Verzeichnis aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder des Verzeichnisses&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in die/den das Ergebnis der Operation (Y oder N) geschrieben wird.&lt;br /&gt;
* on (&amp;quot;old name) - der bisherige Dateiname bei RenameFile&lt;br /&gt;
* y - Typ der Operation&lt;br /&gt;
** cd / createdir - Erzeugt ein Verzeichnis&lt;br /&gt;
** cf / copyfile - Kopiert eine Datei (von on zu fn)&lt;br /&gt;
** df / deletefile - Löscht eine Datei&lt;br /&gt;
** fd / forcedirectories - Stellt sicher, dass ein Pfad vorhanden ist&lt;br /&gt;
** rd / removedir - Entfernt ein Verzeichnis&lt;br /&gt;
** rf / renamefile - Benennt eine Datei um, kann auch dazu verwendet werden, eine Datei zu verschieben&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #file_op   y=renamefile   on=c:\temp\debug.txt   fn=c:\temp\test\debug.txt   n=1&lt;br /&gt;
 #cout   c=$VAL(1)&lt;br /&gt;
 &lt;br /&gt;
 #file_op   y=fd   fn=c:\eins\zwei\drei\vier&lt;br /&gt;
&lt;br /&gt;
==#file_search==&lt;br /&gt;
&lt;br /&gt;
Sucht Dateien und schreibt die Ergebnisliste in einen Text.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* clr - (&amp;quot;clear&amp;quot;) wenn Y, wird der Text vor der Suche geleert. Default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, in den die Ergebnisliste geschrieben wird; default 1, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_search   fn=c:\*.ini   n=1   y=0   all_=Y&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==#file_wait==&lt;br /&gt;
&lt;br /&gt;
Wartet, bis zumindest eine Datei vorhanden ist, die den Kriterien entspricht, und führt dann cmd aus. Wird nach der in to eingestellten Zeit keine Datei gefunden, dann wird mit dem in cmdto eingestellten Kommando abgebrochen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* cmd - Kommando, das ausgeführt wird, sobald eine Datei gefunden wird; Funktionen werden ersetzt&lt;br /&gt;
* cmdto - Kommando, das ausgeführt wird, sobald die Prozedur wegen eines TimeOuts abgebrochen wird; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* sleep - Zeit in ms zwischen den einzelnen Suchen nach einer Datei, die den Kriterien entspricht; Default 1000, Funktionen werden ersetzt&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in ms, nach der die Ausführung abgebrochen wird; Default 15000, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #cout c=&amp;quot;Gefunden&amp;quot;&lt;br /&gt;
 #cmd_clear2 #cout c=&amp;quot;TimeOut&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #file_wait   fn=C:\temp\test\*.txt   cmd=1   cmdto=2&lt;br /&gt;
&lt;br /&gt;
==#dir_force==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass es den spezifizierten Verzeichnispfad gibt, indem erforderlichenfalls Verzeichnisse angelegt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Names des Pfads&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_force   n=c:\temp\pdf&lt;br /&gt;
&lt;br /&gt;
==#dir_proc==&lt;br /&gt;
&lt;br /&gt;
Durchsucht ein Verzeichnis nach Dateien, die den angegebenen Kriterien entsprechen, und führt für jede gefundene Datei ''cmd'' aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das für jede gefundene Datei ausgeführt wird&lt;br /&gt;
* dn (&amp;quot;DirectoryName&amp;quot;) - Pfad des Verzeichnisses, in dem die Dateien gesucht werden; Funktionen werden ersetzt.&lt;br /&gt;
* done - Verzeichnis, in das die Dateien nach Abarbeitung verschoben werden (sofern der Parameter nicht leer ist). Funktionen werden ersetzt.&lt;br /&gt;
* error- Verzeichnis, in das die Dateien nach Abarbeitung verschoben werden (sofern der Parameter nicht leer ist), wenn der Inhalte der unter ndone angegebenen Variablen E ist. Funktionen werden ersetzt.&lt;br /&gt;
* fn (&amp;quot;filename&amp;quot;) - Suchkriterium für den Dateinamen; Funktionen werden ersetzt; Default *&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in welcher der Dateiname der aktuell zu bearbeitenden Datei inklusive Pfad gespeichert wird; Funktionen werden ersetzt; Default dir_proc&lt;br /&gt;
* ndone(&amp;quot;name done&amp;quot;) - Name der Variablen, die bestimmt, ob eine Datei in das Done-Verzeichnis verschoben wird. Vor jedem Aufruf von cmd wird diese Variable auf 'Y' gesetzt. Sie kann während der Bearbeitung auf N gesetzt werden - damit wird verhindert, dass die Datei in das Done-Verzeichnis verschoben wird. Wir die Variable auf E gesetzt, wird die Datei ins Error-Verzeichnis verschoben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_proc   dn=c:\temp\in   done=c:\temp\done   fn=*.csv   cmd=importcsv_line&lt;br /&gt;
&lt;br /&gt;
==$FILEINFO()==&lt;br /&gt;
&lt;br /&gt;
Liefert Infos über eine Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Dateiname&lt;br /&gt;
# Typ der Information, es stehen dabei folgende Optionen zur Verfügung&lt;br /&gt;
#* size - Dateigröße in Byte&lt;br /&gt;
#* size_point - Dateigröße in Byte, Punkte alle drei Zeichen von rechts&lt;br /&gt;
#* size_auto - Dateigröße in Byte, kB, MB oder GB, je nach Größe; mit Einheit&lt;br /&gt;
#* size_kb - Dateigröße in kB (analog Windows-Explorer)&lt;br /&gt;
#* date - Datum im Format dd.mm.yyyy&lt;br /&gt;
#* date_yyyy - Datum im Format yyyymmdd&lt;br /&gt;
#* datetime - Datum und Uhrzeit im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
#* datetime_yyyy - Datum im Format yyyymmddhhmmss&lt;br /&gt;
#* exists - Y, wenn die Datei existiert, sonst N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=fn   z=&amp;quot;T:\Tools Gruppenrechte\BC3 light\BafClientFM.exe&amp;quot;&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_point)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_auto)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_kb)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),exists)&lt;br /&gt;
&lt;br /&gt;
Ergebnis&lt;br /&gt;
&lt;br /&gt;
 27668480&lt;br /&gt;
 27.668.480&lt;br /&gt;
 26,39 MB&lt;br /&gt;
 27.020 kB&lt;br /&gt;
 02.05.2023&lt;br /&gt;
 20230502&lt;br /&gt;
 02.05.2023 12:20:09&lt;br /&gt;
 20230502122009&lt;br /&gt;
 Y&lt;br /&gt;
&lt;br /&gt;
==$DIR()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Verzeichnisnamen. Trailing Path Delimiter (\ bei Windows) wird immer angehängt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bezeichnung des Verzeichnisses&lt;br /&gt;
## appdata - Verzeichnis für Anwendungsdaten des Users&lt;br /&gt;
## cappdata - gemeinsames Verzeichnis für Anwendungsdaten aller User&lt;br /&gt;
## cdoc - gemeinsames Dokumentenverzeichnis  aller User&lt;br /&gt;
## cfav / cfavorites - gemeinsames Favoritenverzeichnis aller User&lt;br /&gt;
## cmusic - gemeinsames Musikverzeichnis aller User&lt;br /&gt;
## cpic / cpictures - gemeinsames Bilderverzeichnis aller User&lt;br /&gt;
## cvideo - gemeinsames Videoverzeichnis aller User&lt;br /&gt;
## desktop - Desktopverzeichnis des Rechners&lt;br /&gt;
## '''doc''' / docdir - Dokumentenverzeichnis des Users&lt;br /&gt;
## downloads - Downloadsverzeichnis des Users&lt;br /&gt;
## fav / favorites - Favoritenverzeichnis des Users&lt;br /&gt;
## fonts - Fontsverzeichnis des Rechners&lt;br /&gt;
## music - Musikverzeichnis des Users&lt;br /&gt;
## pic / pictures - Bilderverzeichnis des Users&lt;br /&gt;
## prog / program - Programmverzeichnis des Rechners&lt;br /&gt;
## prog86 / program86 - Programm86-Verzeichnis des Rechners&lt;br /&gt;
## '''root''' - Root-Verzeichnis des BAF-Clients bzw. des BAF-Servers&lt;br /&gt;
## '''userroot''' / usrroot - User-Verzeichnis des BAF-Clients&lt;br /&gt;
## video - Videoverzeichnis des Users&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=$DIR(doc)test.txt&lt;br /&gt;
&lt;br /&gt;
==$FILEDIALOG()==&lt;br /&gt;
&lt;br /&gt;
Führt einen Dateiauswahl-Dialog aus und gibt den gewählten Dateinamen zurück. Im Falle des Abbruchs wird ''abort'' zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wenn der erste Parameter ''save'' lautet, wird ein Speichern-Dialog, sonst ein Öffnen-Dialog aufgerufen.&lt;br /&gt;
# Filter-Statement, immer Kombinationen aus Text (Text-Dateien *.txt) und Filter-Statement(*.txt), getrennt durch Pipes.&lt;br /&gt;
# Standard-Dateierweiterung&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=&amp;quot;$FILEDIALOG(save,Text-Dateien *.txt|*.txt|Alle Dateien *.*|*.*,txt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Bitte beachten: Wegen der Leerzeichen im Filter-Statement muss der ganze Parameter in doppelte Anführungszeichen gesetzt werden.)&lt;br /&gt;
&lt;br /&gt;
=ZIP=&lt;br /&gt;
&lt;br /&gt;
==#zip_create==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine ZIP-Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Dateien, die der ZIP-Datei hinzugefügt werden; Funktionen werden ersetzt&lt;br /&gt;
* dir (&amp;quot;directory&amp;quot;) - Verzeichnis, wenn das nicht bei allen fn1, fn2... angegeben werden soll&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Der Dateiname, unter dem die ZIP-Datei gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* fn1, fn2,... (&amp;quot;FileName&amp;quot;) - Die Dateien, die in der ZIP-Datei gespeichert werden; die Anzahl wird mit dem Parameter cnt bestimmt; Funktionen werden ersetzt&lt;br /&gt;
* list - Nummer eines Textes (#text, #text2...), in dem die Dateien gelistet sind, die der ZIP-Datei hinzugefügt werden sollen. Wenn list ein Wert größer 0 hat, werden cnt und fn1, fn2... ignoriert. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* pw (&amp;quot;PassWord&amp;quot;) - Password der erzeugten ZIP-Datei; Funktionen werden ersetzt.&lt;br /&gt;
* pwc (&amp;quot;PassWordCrypted&amp;quot;) - Wenn Y, dann ist das Passwort mit der Verschlüsselungsfunktion auf der Seite Tools des Code-Dialogs verschlüsselt. Hinweis: Mit dieser Verschlüsselung verhindert man lediglich, dass das Passwort direkt aus dem Code ausgelesen werden kann. Wird der BAF-Client mit dem Delphi-Debugger ausgeführt, lässt sich leicht an die betreffende Stelle ein Breakpoint setzen und das Passwort dann im Klartext auslesen (dieselbe Unit uBafCrypt vorausgesetzt).&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #zip_create   fn=$VAR(root).zip   list=1&lt;br /&gt;
 &lt;br /&gt;
 #var_set   n=fn_zip   z=tt_mail_$VAR(reise)-$VAR(reisename)_$PAD($VAR(lfdnr),4,L,0)_$NOWFMT(yyyymmdd).zip&lt;br /&gt;
 #file_op   y=df   fn=$VAR(path)\$VAR(fn_zip)&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=$VAR(filename).txt&lt;br /&gt;
 #code fn2=$VAR(filename).sab&lt;br /&gt;
 #zip_create   dir=$VAR(path)   fn=$VAR(path)\$VAR(fn_zip)    pw=$VAR(pw)   $CODE$&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #zip_create ersetzt nicht vorherige Dateien. Von daher im Zweifelsfall wie im zweiten Beispiel vorher eine Datei dieses Namens löschen.&lt;br /&gt;
&lt;br /&gt;
=Ini-Dateien=&lt;br /&gt;
&lt;br /&gt;
Der BAF-Client verwendet eine Ini-Datei im Root-Verzeichnis (vor allem für die Datenbankverbindungen) und eine Ini-Datei ''BafClientFM.ini'' im User-Anwendungsverzeichnis (vor allem für die Formularpositionen). Es können aber auch weitere Ini-Dateien verwendet werden.&lt;br /&gt;
&lt;br /&gt;
==#ini_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Ini-Datei. #ini_val ist eine nummerierte Prozedur: #ini_val schreibt in die erste Ini-Datei, #ini_val2 in die zweite Ini-Datei und so weiter. Diese Ini-Dateien werden zunächst nur im Speicher gehalten und müssen explizit aus einer Datei geladen oder in eine Datei gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;item&amp;quot; / &amp;quot;ident&amp;quot;) - Name des Eintrags in der Ini-Datei; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Wenn der Parameter n den Wert ''usr'' oder ''user'' hat, dann bleibt die Nummer der Ini-Datei unberücksichtigt und der Wert wird in die Datei ''BafClientFM.ini'' im im User-Anwendungsverzeichnis geschrieben.&lt;br /&gt;
* sec (&amp;quot;section&amp;quot;) - Abschnitt in der Ini-Datei; Funktionen werden ersetzt; default ''values''&lt;br /&gt;
* z - Wert, der in die Ini-Datei geschrieben wird; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_val  i=date_last   z=$NOW()&lt;br /&gt;
&lt;br /&gt;
==#ini_load==&lt;br /&gt;
&lt;br /&gt;
Lädt eine Ini-Datei aus einer Datei. Es handelt sich um eine nummerierte Prozedur: #ini_load lädt die Ini-Datei 1, #ini_load2 lädt die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, die geladen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_load   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==#ini_save==&lt;br /&gt;
&lt;br /&gt;
Speichert eine Ini-Datei ineine Datei. Es handelt sich um eine nummerierte Prozedur: #ini_save speichert die Ini-Datei 1, #ini_save2 speichert die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, in die gespeichert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_save   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==$INI()==&lt;br /&gt;
&lt;br /&gt;
Liest einen Wert aus einer Ini-Datei.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
# Item (Ident)&lt;br /&gt;
# optional: Sektion; wenn nicht vorhanden, dann ''values''. Wenn ''db!'', dann wird als Sektion die aktuell gewählte Datenbankverbindung verwendet (in diesem Fall sollte als erster Parameter ''root'' verwendet werden).&lt;br /&gt;
# optional: Default-Wert; wenn nicht vorhanden, dann ein leerer String&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum)&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum,bearbeitung,$TODAY())&lt;br /&gt;
&lt;br /&gt;
==$INITEXT()==&lt;br /&gt;
&lt;br /&gt;
Gibt die komplette Ini-Datei zurück. Wird vor allem beim Debugging verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $INITEXT(usr)&lt;br /&gt;
&lt;br /&gt;
=Zwischenablage=&lt;br /&gt;
&lt;br /&gt;
Das BAF-Framework unterstützt die Zwischenablage nur für Text.&lt;br /&gt;
&lt;br /&gt;
==#clipboard==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Text in die Zwischenablage&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* z - Wert, der in der Zwischenablage gespeichert werden soll; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #clipboard   z=$TEXT()&lt;br /&gt;
 #clipboard   z=$CHR(dquote)$PVAL(test,zahl,allsel,$CHR(crlf))$CHR(dquote)&lt;br /&gt;
&lt;br /&gt;
==$CLIPBOARD()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Text aus der Zwischenablage zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setvar   n=clp   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
=String-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben einen String zurück.&lt;br /&gt;
&lt;br /&gt;
==$BASE64()==&lt;br /&gt;
&lt;br /&gt;
En- oder Decodiert einen Text im Base64-Code&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Encoding oder Decoding:&lt;br /&gt;
## e - Encoding&lt;br /&gt;
## d - Decoding&lt;br /&gt;
# Text, der en-oder decodet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $BASE64(e,Dies ist ein Test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$CHR()==&lt;br /&gt;
&lt;br /&gt;
Gibt ein Zeichen (ggf zwei Zeichen) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Ansi-Zeichennummer oder eine der folgenden Bezeichnungen:&lt;br /&gt;
## crlf - Zeilenumbruch #13#10&lt;br /&gt;
## cr - Zeichen #13&lt;br /&gt;
## lf - Zeichen #10&lt;br /&gt;
## tab - Tabulator&lt;br /&gt;
## quote - ' (einfache Anführungszeichen)&lt;br /&gt;
## dquote - &amp;quot; (doppelte Anführungszeichen)&lt;br /&gt;
## space / leer - Leerzeichen&lt;br /&gt;
## comma / komma - , (Komma)&lt;br /&gt;
## questionmark / qmark / frage / fragezeichen - ?&lt;br /&gt;
## bro / bracket_open - (&lt;br /&gt;
## brc / bracket_close - )&lt;br /&gt;
## dollar - $&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CONVERT()==&lt;br /&gt;
&lt;br /&gt;
Konvertiert einen String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Konvertierungsfunktion&lt;br /&gt;
## isodate&lt;br /&gt;
## isodatetime&lt;br /&gt;
## truefalse&lt;br /&gt;
## pointfloat&lt;br /&gt;
## urlcode&lt;br /&gt;
## utf8&lt;br /&gt;
# String, der konvertiert werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $CONVERT(isodate,2025-03-12)&lt;br /&gt;
 #coutl $CONVERT(isodatetime,2025-03-12 12:03:17)&lt;br /&gt;
 #coutl $CONVERT(truefalse,true)&lt;br /&gt;
 #coutl $CONVERT(pointfloat,12.3)&lt;br /&gt;
 #coutl $CONVERT(urlcode,Für schönen Ärger)&lt;br /&gt;
 #coutl $CONVERT(utf8,Für schönen Ärger)&lt;br /&gt;
&lt;br /&gt;
(Ergebnis)&lt;br /&gt;
 12.03.2025&lt;br /&gt;
 12.03.2025 12:03:17&lt;br /&gt;
 Y&lt;br /&gt;
 12,3&lt;br /&gt;
 F%C3%BCr%20sch%C3%B6nen%20%C3%84rger&lt;br /&gt;
 Für schönen Ärger&lt;br /&gt;
&lt;br /&gt;
==$COPY()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$COPY($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$EXEC()==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando aus und gibt ein Funktionsergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll.&lt;br /&gt;
# optional: Name der Variable, die als Funktionsergebnis zurück gegeben werden soll; default ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=test   z=$EXEC(testkommando)&lt;br /&gt;
&lt;br /&gt;
==$GUID()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine GUID und gibt sie zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# optional: Name einer Variablen, in welcher die GUID zusätzlich gespeichert wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kid=$GUID()&lt;br /&gt;
&lt;br /&gt;
==$HASH()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt einen Hash-Wert vom String im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, von welchem der Hash gebildet werden soll.&lt;br /&gt;
# zu verwendender Hash-Algorithmus:&lt;br /&gt;
## sha512&lt;br /&gt;
## sha512_256&lt;br /&gt;
## sha512_224&lt;br /&gt;
## sha384&lt;br /&gt;
## sha256&lt;br /&gt;
## sha224&lt;br /&gt;
## sha1&lt;br /&gt;
## md5 (Hinweis: MD5 gilt seit Längerem als nicht mehr sicher. Verwenden Sie ihn nur, wenn dies aus Gründen der Abwärts-Kompatbilität zwingend ist.)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$HASH($PVAL(vl,1,2),sha512)&lt;br /&gt;
&lt;br /&gt;
==$INCLUDE()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass der als dritter Parameter übergebene Text am Anfang oder am Ende steht, gegebenenfalls wird er dort eingefügt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## lead(oder leading) - Text muss am Anfang stehen&lt;br /&gt;
## leadci(oder leadingci oder leadingcaseinsensitive) - Text muss am Anfang stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
## trail(oder trailing) - Text muss am Ende stehen&lt;br /&gt;
## trailci(oder trailci oder trailingcaseinsensitive) - Text muss am Ende stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
# Text, in den gegebenenfalls eingefügt wird&lt;br /&gt;
# Text, der gegebenenfalls eingefügt wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCLUDE(trailci,test.PDF,.pdf)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$INVLOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Key aus einer Nachschlageliste bei Übergabe des Values.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Value des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$INVLOOKUP(general_status,aktiv,Wert nicht vorhanden)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus einer Nachschlageliste.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Key des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$LOOKUP(general_status,1,Status nicht gesetzt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOW()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Kleinbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Kleinbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LOW($EDT(edt1)) = bus&lt;br /&gt;
&lt;br /&gt;
==$LOWNOSPACE()==&lt;br /&gt;
&lt;br /&gt;
Wandelt einen String in Kleinbuchstaben und ersetzt alle Leerzeichen durch Unterstriche.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der gewandelt werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$LOWNOSPACE($PVAL(vl,1,2))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$NOCRLF()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Zeilenumbrüche&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem die Zeilenumbrüche entfernt werden sollen&lt;br /&gt;
# optional: Zeichenfolge, die an Stelle der Zeilenumbrüche eingefügt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=2   z=$NOCRLF($VAL(1),;)&lt;br /&gt;
&lt;br /&gt;
==$NVL()==&lt;br /&gt;
&lt;br /&gt;
Liefert einen Ersatzwert, wenn der Wert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird, wenn der erste Parameter leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   where ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0)&lt;br /&gt;
&lt;br /&gt;
Liefert $PVAL einen leeren Wert zurück (z.B., weil die Gridzeile neu angelegt wurde und daher noch keine Nummer eingetragen ist), so wird statt dessen 0 verwendet, damit die WHERE-Klausel syntaktisch korrekt ist.&lt;br /&gt;
&lt;br /&gt;
==$ONLYCHAR()==&lt;br /&gt;
&lt;br /&gt;
Entfernt unerwünschte Zeichen aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# optional: Typ der Funktion&lt;br /&gt;
## (leer) - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z', 'ä', 'ö', 'ü', 'Ä','Ö', 'Ü', 'ß']) sind&lt;br /&gt;
## charnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind&lt;br /&gt;
## low - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## upp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## charnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## charnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## uml - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z') sind, Umlaute werden konvertiert (ä -&amp;gt; ae, ö -&amp;gt; oe, ü -&amp;gt; ue, Ä -&amp;gt; Ae, Ö -&amp;gt; Oe, Ü -&amp;gt; Ue, ß -&amp;gt; ss)&lt;br /&gt;
## umlcharnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Umlaute werden konvertiert&lt;br /&gt;
## umllow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## no191 / not191 - Es werden alle Zeichen mit der ANSI-Nummer 191 (¿) entfernt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg)&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg,umllow)&lt;br /&gt;
&lt;br /&gt;
==$PAD()==&lt;br /&gt;
&lt;br /&gt;
Füllt links oder rechts bis zur vorgegebenen Länge mit Zeichen auf.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# Soll-Länge. Ist der ursprüngliche String bereits länger, wird er nicht gekürzt, es werden aber auch keine weiteren Zeichen hinzugefügt&lt;br /&gt;
# Wenn L, werden die Zeichen vorne hinzugefügt, andernfalls hinten&lt;br /&gt;
# Zeichen, die soweit und so oft hinzugefügt werden, bis die Soll-Länge erreicht ist. Umfasst der Parameter mehrere Zeichen, werden diese ggf. nicht alle hinzugefügt.&lt;br /&gt;
# optional: Länge, auf die der ursprüngliche String vor der weiteren Verarbeitung gekürzt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   text1 = '$PAD($VAR(text1),70,R, )'&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ des Ergebnisses&lt;br /&gt;
## curr - Zahl mit zwei Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## curr4 - Zahl mit vier Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## date - Datum in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## int - ganze Zahl  in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## ld - Key einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ldv - Value einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ls - Key eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## lsv - Value eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## text, text2, text3... - Zeile eines Textes&lt;br /&gt;
# untere Grenze bzw. Name der Nachschlageliste oder des Specials&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $RANDOM(date,01.01.2022,31.12.2022)&lt;br /&gt;
 #coutl $RANDOM(text2)&lt;br /&gt;
&lt;br /&gt;
==$SUBSTR()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Selbe Funktionalität wie $COPY())&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$SUBSTR($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$STREP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string replace&amp;quot;) Ersetzt Zeichen im String durch andere Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, in welchen Zeichen ersetzt werden sollen.&lt;br /&gt;
# Zeichen, die ersetzt werden sollen&lt;br /&gt;
# Zeichen, die an deren Stelle treten sollen&lt;br /&gt;
# optional: Optionen (kombinierbar)&lt;br /&gt;
## i - Groß- und Kleinschreibung ignorieren &lt;br /&gt;
## a - Alle Vorkommen ersetzen (andernfalls wird nur das erste Vorkommen ersetzt)&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=&amp;quot;$STREP($PVAL(vl,1,2), ,_,a)&amp;quot;&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$STREP($PVAL(vl,1,2),$CHR(space),_,a)&lt;br /&gt;
&lt;br /&gt;
Hinweis: Beide Beispiele haben exakt dieselbe Funktion. Im oberen Beispiel steht das Leerzeichen direkt im Text, dafür muss der komplette Parameter in doppelte Anführungszeichen, im unteren Beispiel wird das Leerzeichen durch $CHR(space) eingefügt, dafür können die Leerzeichen unterbleiben.&lt;br /&gt;
&lt;br /&gt;
==$STROP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string operation&amp;quot;) Sammelsurium von String-Operationen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## trim - entfernt führende und folgende Leerzeichen&lt;br /&gt;
## trimleft - entfernt führende Leerzeichen&lt;br /&gt;
## trimright - entferne folgende Leerzeichen&lt;br /&gt;
## quote - setzt den String in einfache Anführungszeichen&lt;br /&gt;
## unquote - entfernt einschließende einfache Anführungszeichen&lt;br /&gt;
## dquote - setzt den String in doppelte Anführungszeichen&lt;br /&gt;
## unqduote - entfernt einschließende doppelte Anführungszeichen&lt;br /&gt;
## ex_filepath - entspricht der Delphi-Funktion ExtractFilePath&lt;br /&gt;
## ex_filedir - entspricht der Delphi-Funktion ExtractFileDir&lt;br /&gt;
## ex_filedrive - entspricht der Delphi-Funktion ExtractFileDrive&lt;br /&gt;
## ex_filename - entspricht der Delphi-Funktion ExtractFileName&lt;br /&gt;
## ex_fileext - entspricht der Delphi-Funktion ExtractFileExt&lt;br /&gt;
# String, der bearbeitet werden soll&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$STROP(quote,Test)&lt;br /&gt;
&lt;br /&gt;
==$STREXTR()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string extract&amp;quot;) Extrahiert einen Teil aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem extrahiert werden soll&lt;br /&gt;
# Extraktionstyp&lt;br /&gt;
## ffe (&amp;quot;from first exclude&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## ffi (&amp;quot;from first include&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tfe (&amp;quot;to first exclude&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tfi (&amp;quot;to first include&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## fle (&amp;quot;from last exclude&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## fli (&amp;quot;from last include&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tle (&amp;quot;to last  exclude&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tli (&amp;quot;to last include&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Trennzeichen&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffe,;)&amp;quot;    -- Ergebnis: test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffi,;)&amp;quot;    -- Ergebnis: ;test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfe,;)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfi,;)&amp;quot;    -- Ergebnis: test;&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;!§§test2,tfe,;!§§)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
&lt;br /&gt;
==$TRIM()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Leerzeichen und Zeilenumbrüche am Rand des Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der getrimmt werden soll&lt;br /&gt;
# optional&lt;br /&gt;
## L - trimmt nur auf der linken Seite&lt;br /&gt;
## R - trimmt nur auf der rechten Seite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$TRIM($VAL(1),R)&lt;br /&gt;
&lt;br /&gt;
==$UPP()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Großbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Großbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $UPP($EDT(edt1)) = BUS&lt;br /&gt;
&lt;br /&gt;
==$VT()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VT (&amp;quot;Value Translate&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Vergleichswert 1&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 1 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 2&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 2 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 3&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 3 dem ersten Parameter entspricht &lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VT(Frau,1,Herr,2,Frau,3)&lt;br /&gt;
 -- Frau -&amp;gt; 3&lt;br /&gt;
 -- Herr -&amp;gt; 2&lt;br /&gt;
 -- Test -&amp;gt; 1&lt;br /&gt;
 -- Firma -&amp;gt; 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$VTRDB()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VTRDB (&amp;quot;Value Translate Root Database&amp;quot;) gibt eine String zurück, der von einem Wert im Datenbank-Segment der Root-Ini abhängt. Diese Ini-Datei (BafClientFM.ini im selben Verzeichnis wie die BafClientFM.exe) enthält die Datenbank-Zugangsdaten. Diese könnte den folgenden Block (Auszug) enthalten:&lt;br /&gt;
&lt;br /&gt;
 [DB_PGPROD]&lt;br /&gt;
 prefix=prod&lt;br /&gt;
 Name=Postgres PROD&lt;br /&gt;
 DriverName=Postgres&lt;br /&gt;
 Database=postgres&lt;br /&gt;
 User=ttbaf3prodadmin&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Der Wert in ''prefix'' spezifiziert, ob es sich um das Produktiv- oder das Test-System handelt. In Abhängigkeit davon gibt diese Funktion dann unterschiedliche Werte zurück. Es wird immer die Sektion der gerade ausgewählten Datenbank verwendet. &lt;br /&gt;
&lt;br /&gt;
Der Hauptanwendungsfall dieser Funktion, die Notwendigkeit einer Änderung des Codes bei der Migration vom Test- in das Produktiv-System oder umgekehrt zu vermeiden. Statt dessen ermittelt die Funktion, ob sie gerade im Test- oder Produktiv-System ausgeführt wird und gibt den passenden Wert (Verzeichnis-Name, URL, ...) zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Item (Ident) in der Root-Ini (die Sektion ist immer die der aktuell ausgewählten Datenbank)&lt;br /&gt;
# Vergleichswert 1&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 1 dem Wert in der Ini-Datei entspricht&lt;br /&gt;
# Vergleichswert 2&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 2 dem Wert in der Ini-Datei entspricht&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$VTRDB(prefix,test,Test-System,prod,Produktiv-System)&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$VTRDB(prefix,test,C:\temp\export\busdaten,prod,T:\files\export\busdaten)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$VTVL()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VTVL (&amp;quot;Value Translate ValueList&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu $VT werden die zu prüfenden Werte und deren Entsprechungen nicht über Parameter übergeben, sondern aus einer Werte-Liste geholt, die in einem Text gespeichert sein muss.&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich wie folgt aufbauen&lt;br /&gt;
&lt;br /&gt;
 key1=value1&lt;br /&gt;
 key2=value2&lt;br /&gt;
 key3=value3&lt;br /&gt;
 key4=value4&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich auch mit #sql_opentvl erzeugen, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Nummer des Textes, in dem sich die Werteliste befindet.&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select userid as ckey, shortname as cvalue from user_user&lt;br /&gt;
 #sql_opentvl n=1&lt;br /&gt;
 #coutl $VTVL(591,(nicht gefunden),1)&lt;br /&gt;
&lt;br /&gt;
==$XR()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $XR (&amp;quot;XmlReplace&amp;quot;) ersetzt in XML nicht zulässige Zeichen:&lt;br /&gt;
* aus &amp;amp; wird $amp ;&lt;br /&gt;
* aus &amp;lt; wird &amp;amp;lt ;&lt;br /&gt;
* aus &amp;gt; wird &amp;amp;gt ;&lt;br /&gt;
* aus &amp;quot; wird &amp;amp;quot ;&lt;br /&gt;
* aus ' wird &amp;amp;apos ;&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Das Leerzeichen vor dem Semikolon soll verhindern, dass die Zeichen hier in der Darstellung ersetzt werden und wird nicht eingefügt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text &amp;lt;firmenname&amp;gt;$XR($DATA(dat,firmenname))&amp;lt;/firmenname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==$XRR()==&lt;br /&gt;
&lt;br /&gt;
Umkehrfunktion von $XR()&lt;br /&gt;
* aus $amp ; wird &amp;amp;&lt;br /&gt;
* aus &amp;amp;lt ; wird &amp;lt;&lt;br /&gt;
* aus &amp;amp;gt ; wird &amp;gt;&lt;br /&gt;
* aus &amp;amp;quot ; wird &amp;quot;&lt;br /&gt;
* aus &amp;amp;apos ; wird '&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
=Integer-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben eine ganze Zahl zurück&lt;br /&gt;
&lt;br /&gt;
==$DEC()==&lt;br /&gt;
&lt;br /&gt;
Verringert die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die verringert werden soll.&lt;br /&gt;
# optional: Zahl, um die verringert werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$DEC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ICALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit ganzzahligen Werten durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator, es stehen zur Verfügung&lt;br /&gt;
## +&lt;br /&gt;
## -&lt;br /&gt;
## *&lt;br /&gt;
## div&lt;br /&gt;
## mod&lt;br /&gt;
# Erste Zahl&lt;br /&gt;
# Zweite Zahl&lt;br /&gt;
# optional beim Operator +: weitere Summanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$ICALC(mod,17,5)&lt;br /&gt;
&lt;br /&gt;
==$INC()==&lt;br /&gt;
&lt;br /&gt;
Erhöht die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die erhöht werden soll.&lt;br /&gt;
# optional: Zahl, um die erhöht werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$INC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$INTLEN()==&lt;br /&gt;
&lt;br /&gt;
Ist der String im Parameter eine ganz Zahl, dann wird deren Länge in Zeichen zurückgegeben, andernfalls -1; ein leerer String im ersten Parameter ergibt 0.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, deren Länge ermittelt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTLEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Länge eines Strings in Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Länge ermittelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEVENSHTEIN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Levenshtein-Distanz (https://de.wikipedia.org/wiki/Levenshtein-Distanz) der beiden übergebenen Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# erster String&lt;br /&gt;
# zweiter String&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $LEVENSHTEIN(alpha,beta)&lt;br /&gt;
&lt;br /&gt;
==$POS()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Position des Substrings in einem String. Das Funktionsergebnis ist die Position, das erste Zeichen ist 1. 0 wird zurück gegeben, wenn der Substring im String nicht vorkommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Substring (nach dem gesucht wird)&lt;br /&gt;
# String (in dem gesucht wird)&lt;br /&gt;
# optional: Wenn ic (ignore case), dann wird bei der Suche die Groß- und Kleinschreibung nicht beachtet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $POS($EDT(edt1),$VAR(1),ic) &amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert zwischen der oberen und unteren Grenze&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ&lt;br /&gt;
## int - zufällige Ganzzahl &lt;br /&gt;
## date - zufälliges Datum &lt;br /&gt;
## curr - zufällige Zahl mit zwei Nachkommastellen&lt;br /&gt;
## curr4 - zufällige Zahl mit vier Nachkommastellen&lt;br /&gt;
## text1, text2, text3... - zufällige Zeile aus dem jeweiligen Text; text ist text1; untere und obere Grenze bleiben unberücksichtigt&lt;br /&gt;
## ld - zufälliger Schlüssel-Wert aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ldv - zufälliger Text aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ls - zufälliger Schlüssel-Wert aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## lsv - zufälliger Text aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
# untere Grenze&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $RANDOM(int,1,6)&lt;br /&gt;
&lt;br /&gt;
=Datumsfunktionen=&lt;br /&gt;
&lt;br /&gt;
==$INCDATE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktione  $INCDATE() verändert das Datum im ersten Parameter um die Anzahl Tage im zweiten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das verändert werden soll&lt;br /&gt;
# optional: Die Tage, um die verändert werden soll; wenn leer, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCDATE($NOW(),-3)   clr=Y&lt;br /&gt;
&lt;br /&gt;
==$INT2TIME()==&lt;br /&gt;
&lt;br /&gt;
Macht aus z.B. 1130 die Zeit 11:30&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zeit im Integer-Format&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_time=$INT2TIME($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$NOW()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit im Format dd.mm.yyyy hh:mm:ss zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #execsql   k_datechg=$NOW()&lt;br /&gt;
&lt;br /&gt;
==$NOWFMT()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und/oder die aktuelle Uhrzeit im angegebenen Format zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Formatierungsstring (Syntax wie FormatDateTime in Delphi)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$NOWFMT(yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$NOWMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit ohne Sekunden (also dd.mm.yyyy hh:mm) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$NOWMIN()&lt;br /&gt;
&lt;br /&gt;
==$TODAY()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum im Format dd.mm.yyyy zurück.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Wenn das Datum in einem anderen Format benötigt wird, ist $NOWFMT() das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$TODAY()&lt;br /&gt;
&lt;br /&gt;
==$DFMT()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;date formated&amp;quot;) Formatiert das übergebene Datum. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, ggf. mit Uhrzeit, das formatiert werden soll.&lt;br /&gt;
# Formatierungsstring wie in Delphi&lt;br /&gt;
# optional: Wenn hn (&amp;quot;hide null&amp;quot;), dann wird ein leerer String zurück gegeben, wenn das Datum kleiner/gleich 1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$DFMT($NOW(),yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Bool'sche Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
==$BFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert einen bool'schen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'scher Wert&lt;br /&gt;
# optional: Ergebnis, wenn Wert Y ('y', 'J', 'j', '1') ist, default Y&lt;br /&gt;
# optional: Ergebnis, wenn Wert N (also nicht 'Y', 'y', 'J', 'j', '1') ist, default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cout   c=$BFMT($VAR(test),x,)&lt;br /&gt;
&lt;br /&gt;
==$BOOL()==&lt;br /&gt;
&lt;br /&gt;
Wertet das bool'sche Statement im Parameter aus.&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
* = gleich&lt;br /&gt;
* == gleich ohne Berücksichtigung der Groß- und Kleinschreibung&lt;br /&gt;
* &amp;lt;&amp;gt; ungleich&lt;br /&gt;
* != ungleich&lt;br /&gt;
* &amp;gt; größer&lt;br /&gt;
* &amp;gt;= größer gleich&lt;br /&gt;
* &amp;lt; kleiner&lt;br /&gt;
* &amp;lt;= kleiner gleich &lt;br /&gt;
* and Und-Verknüpfung&lt;br /&gt;
* or ODER-Verknüpfung&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Statements werden von links nach rechts ausgewertet, and und or sind gleichwetig, gegebenenfalls müssen Klammern eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'sches Statement, das ausgewertet wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL((17 &amp;gt; 22) or (5 &amp;gt; 3))&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL(17 &amp;gt; 22 or 5 &amp;gt; 3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATECOMP()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn Datum 2 Operator Datum 1 zutreffend ist. Ansonsten wird N zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Wird kein Operator angegeben, dann wird die Anzahl der Tage Datum 2 - Datum 1 als Zahl zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum 1&lt;br /&gt;
# Datum 2&lt;br /&gt;
# Operator&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024,&amp;lt;)&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATEMINREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMINREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEMAXREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMAXREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in ein Datum wandeln lassen, werden zu 0 (30.12.1899) konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter diesem Datum entspricht. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;Test $DATEBETWEEN($TODAY(),1.1.2020,2.2.2022)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$EMPTY()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Parameter ein leerer String ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTY($DATE(n,grpname))&lt;br /&gt;
&lt;br /&gt;
==$EMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable ein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTYVAR(buchungsnr)&lt;br /&gt;
&lt;br /&gt;
==$IN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INIC() beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die erste Anweisung gibt Y und die zweite N zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INIC()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $IN() nicht beachtet beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen geben Y zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich die Variable, deren Namen im ersten Parameter steht, in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INICVAR() beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable, die geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die erste Anweisung gibt Y und die zweite N zurück&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=beta&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INICVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich die Variable, deren Namen im ersten Parameter steht, in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INVAR() nicht beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable, die geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen geben Y zurück&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=beta&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$ISCURR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen Currency-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISCURR($DATA(n,rechnungssumme))&lt;br /&gt;
&lt;br /&gt;
==$ISDATE()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in ein Datums- oder DatumsZeit-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Prüfoperation, default ist date&lt;br /&gt;
## date - prüft, ob in ein Datum gewandelt werden kann&lt;br /&gt;
## datetime - prüft, ob in ein Datums-Zeit-Wert gewandelt werden kann&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISDATE($DATA(n,beginn))&lt;br /&gt;
&lt;br /&gt;
==$ISINT()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen ganzzahligen Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISINT($DATA(n,tage))&lt;br /&gt;
&lt;br /&gt;
==$INTMAX()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMAX($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$INTMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMIN($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$NEMPTY()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;not empty&amp;quot;) Gibt Y zurück, wenn der Parameter nicht leer ist. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalt geprüft wird. Leerzeichen gelten als leerer String.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 &lt;br /&gt;
 ~ $NEMPTY($EDT(edt1))&lt;br /&gt;
&lt;br /&gt;
==$NEMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable kein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $NEMPTYVAR(kundennr)&lt;br /&gt;
&lt;br /&gt;
==$NOT==&lt;br /&gt;
&lt;br /&gt;
Invertiert einen bool'schen Wert. Aus Y (y, J, j, 1) wird N und aus N wird Y.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der invertiert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $NOT(2)&lt;br /&gt;
&lt;br /&gt;
==$NUMBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in eine Zahl wandeln lassen, werden zu 0 konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter dieser Zahl entspricht. Siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56,)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die beiden Beispiele unterscheiden sich auf den ersten Blick kaum. Bei der ersten Zeile muss jedoch eine Schuhgröße eingegeben werden. Bleibt das Feld im VL-Segment leer, so wird dieser fehlende Wert nach 0 konvertiert und liegt nicht zwischen 28 und 56.&lt;br /&gt;
&lt;br /&gt;
Anders bei der zweiten Zeile: Das Komma vor der schließenden Klammer sorgt für einen vierten Parameter, der ebenfalls leer ist und damit nach 0 gewandelt wird. Auf diese Weise werden die leere Eingaben (und die Eingabe von 0) gültig.&lt;br /&gt;
&lt;br /&gt;
==$REGEX()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $REGEX() (&amp;quot;regular expressions&amp;quot;) prüft, ob der String in Parameter 1 den Anforderungen von Parameter 2 entspricht (Ergebnis Y) oder nicht (Ergebnis N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft werden soll&lt;br /&gt;
# Regulärer Ausdruck, mit dem der String in Parameter 2 geprüft wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $REGEX($VAR(med),^[A-Z]{3}$)&lt;br /&gt;
&lt;br /&gt;
==$TEXT_HASLINE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $TEXT_HASLINE() prüft, ob die als Parameter 2 übergebene Textzeile in einem Text vorkommt. Es wird nur auf komplette Textzeilen geprüft. Wird zum Beispiel verwendet, um eine Liste von Kundennummern zu erstellen, und dann auf einzelne Nummern zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# Textzeile, deren Vorkommen geprüft wird&lt;br /&gt;
# Ergebnis, wenn die Textzeile vorkommt; default Y&lt;br /&gt;
# Ergebnis, wenn die Textzeile nicht vorkommt; default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $TEXT_HASLINE(1,990000018,1,0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$VIBAN()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VIBAN() (&amp;quot;validate IBAN&amp;quot;) prüft eine IBAN anhand der Prüfziffern (3. und 4. Stelle).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# IBAN, die geprüft werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VIBAN(DE12345)&lt;br /&gt;
&lt;br /&gt;
=Currency-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==$CCALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit Festkommawerten durch&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
** + - Addition&lt;br /&gt;
** - - Subtraktion&lt;br /&gt;
** * - Multiplikation&lt;br /&gt;
** / - Division&lt;br /&gt;
** % - Division und Multiplikation des Ergebnisses mit 100&lt;br /&gt;
** +4 - Addition und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** -4 - Subtraktion und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** *4 - Multiplikation und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** /4 - Division und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** %4 - Division, Multiplikation des Ergebnisses mit 100 und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
** B, b, B4, b4 - Bruttobetrag, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** E, e, E4, e4 - Enthaltene MWSt, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** M, m, M4, m4 - MWSt, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** N, n, N4, n4 - Nettobetrag, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator&lt;br /&gt;
# und weitere: Operanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 10&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(+,1,2,3,4)&amp;quot;&lt;br /&gt;
 -- Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #val_set   n=1   z=1038,87&lt;br /&gt;
 #coutl $CCALC(N,$VAL(1),19)  -  $CCALC(E,$VAL(1),19)  -&lt;br /&gt;
&lt;br /&gt;
==$CURR()==&lt;br /&gt;
&lt;br /&gt;
Currency-Werte müssen in Funktionen mit einem Punkt als Dezimaltrennzeichen eingegeben werden, da das Komma die Parameter trennt. Sofern Konstanten verwendet werden, lässt sich das einfach so eingeben, sobald aber die Werte aus anderen Funktionen kommen (zum Beispiel $DATA()), müssen sie dann mit $CURR() in dieses Format umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Vorkommastellen&lt;br /&gt;
# Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 43,48&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,$CURR(2,3))&amp;quot;&lt;br /&gt;
 -- zum Vergleich; Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert Curreny-Werte&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert&lt;br /&gt;
# optional: Formatierungsstring, default 0.00&lt;br /&gt;
# optional: wenn hn (&amp;quot;hide null&amp;quot;), dann werden leere Strings als Wert auch als leerer String ausgegeben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=###,###,###,##0.00&lt;br /&gt;
 #val_set   n=2   z=1337,42&lt;br /&gt;
 #cout   c=$CFMT($VAL(2),$VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ONLYNUM()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass in einem String nur Zahlen (ggf. auch Kommas oder Punkte) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl&lt;br /&gt;
# Art der Operation; default numkomma&lt;br /&gt;
## flnnc (&amp;quot;from last not numeric character&amp;quot;) - Ab dem letzten Zeichen, das keine Ziffer ist&lt;br /&gt;
## num - Nur Ziffern, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numkomma - Nur Ziffern und Kommata, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numpoint - Nur Ziffern und Punkte, alle anderen Zeichen werden entfernt&lt;br /&gt;
## ufnnc (&amp;quot;until first not numeric character&amp;quot;) - vom Anfang bis zum ersten Zeichen, das keine Ziffer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 -- Ergebnis 123456&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,num)&lt;br /&gt;
 -- Ergebnis 123&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,ufnnc)&lt;br /&gt;
 -- Ergebnis 456 &lt;br /&gt;
 #coutl   $ONLYNUM(123-456,flnnc)&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22537</id>
		<title>Modul VAR neu</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22537"/>
		<updated>2025-10-01T09:20:48Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* $VT() */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das Modul Var sammelt neben den Variablen auch die grundlegenden Prozeduren und Funktionen.&lt;br /&gt;
&lt;br /&gt;
=Variable=&lt;br /&gt;
&lt;br /&gt;
==#var_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#setvar setzt den Wert einer Variablen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis: Variable sind global, auf sie kann auch in Sub-Kommandos zugegriffen werden. Values sind dagegen lokal.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*rf (replace functions) - Wenn Y, dann werden nach der Zuweisung auf die Variable nochmals die Funktionen ersetzt. Wird zum Beispiel benötigt, wenn Code mit Funktionen mittels $DATA() aus der Datenbank geladen wird; Funktionen werden ersetzt, default N; siehe Beispiel&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_set   n=test2  z=$GUID()&lt;br /&gt;
 #var_set   n=edt    z=$EDT(edt1)   ie=42&lt;br /&gt;
 #var_set   n=_page_kunde_adressänderung_ro   z=N   zn=Y   zr=Y   r=kundenservice&lt;br /&gt;
&lt;br /&gt;
Zum Parameter rf: $NOW() in die Zwischenablage kopieren und dann ausführen:&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=N&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=Y&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_setempty==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_setempty setzt den Wert einer Variablen, sofern sie (noch) leer ist.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Besteht der Variableninhalt aus Leerzeichen, gilt die Variable auch als leer.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_setempty   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_setempty   n=test2  z=$GUID()&lt;br /&gt;
 #var_setempty   n=edt    z=$EDT(edt1)    ie=42&lt;br /&gt;
&lt;br /&gt;
==#var_add==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_add fügt einer Variablen einen Wert hinzu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. &lt;br /&gt;
* y -Typ der Operation; default ''text''&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** month - Es wird dem Datum eine Anzahl von Monaten hinzugefügt&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
*z - Wert, welcher der Variablen hinzugefügt wird, Funktionen werden ersetzt, default ist ein leerer String oder eine 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$NOW()&lt;br /&gt;
 #var_add   n=test   z=1   y=datetime&lt;br /&gt;
 #cout   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_log==&lt;br /&gt;
&lt;br /&gt;
Schreibt den Inhalt aller Variablen in das Debug-Log.&lt;br /&gt;
&lt;br /&gt;
Wird nur zur Fehlersuche verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_log&lt;br /&gt;
&lt;br /&gt;
==$VAR()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $VAR() wird auf den Inhalt der Variable zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
# optional: Der Wert wird vor oder nach der Rückgabe als Funktionsergebnis verändert; nur für ganzzahlige Werte&lt;br /&gt;
## ib (&amp;quot;increment before&amp;quot;) - Der Wert wird vor der Rückgabe um eins erhöht&lt;br /&gt;
## db (&amp;quot;decrement before&amp;quot;) - Der Wert wird vor der Rückgabe um eins verringert&lt;br /&gt;
## ia (&amp;quot;increment after&amp;quot;) - Der Wert wird nach der Rückgabe um eins erhöht&lt;br /&gt;
## da (&amp;quot;decrement after&amp;quot;) - Der Wert wird nach der Rückgabe um eins verringert&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #message  c=$VAR(test)&lt;br /&gt;
 #var_set  n=neuer_wert   z=$VAR(wert)   ie=$VAR(alternativwert)&lt;br /&gt;
 #execsql   k_lfdnr=$VAR(lfdnr,ib)&lt;br /&gt;
&lt;br /&gt;
=Kommandos=&lt;br /&gt;
&lt;br /&gt;
(Primär- und Sub) Kommandos sind üblicherweise benannt und werden im Code-Dialog eingegeben.&lt;br /&gt;
&lt;br /&gt;
Es besteht jedoch auch die Möglichkeit, lokale Kommandos innerhalb eines anderen Kommandos zu definieren. Diese Kommandos haben statt eines Kommando-Namens dann dann eine Kommando-Nummer.&lt;br /&gt;
&lt;br /&gt;
Lokale Kommandos werden üblicherweise für folgende Zwecke verwendet:&lt;br /&gt;
&lt;br /&gt;
* Bei der Verwendung von xlive werden bisweilen Prozeduren eingesetzt, die ihrerseits ein Kommando aufrufen (z.B. #sql_open). Wenn dieses Kommando nichts bereits existiert, kann es nur als lokales Kommando erstellt werden.&lt;br /&gt;
&lt;br /&gt;
* Wenn das auszuführende Kommando auf derselben Seite stehen soll wie die aufrufende Prozedur.&lt;br /&gt;
&lt;br /&gt;
Siehe als Beispiel: [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd fügt dem Kommando eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd fügt dem ersten Kommando eine Zeile hinzu, #cmd2 fügt dem zweiten Kommando eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd hat keine benannten Parameter. Die ganze Zeile nach dem #cmd und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd3 #text $DATA(n,login);$DATA(n,shortname);$DATA(n,firstname);$DATA(n,lastname);$DATA(n,userid);&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clear löscht ein Kommando&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd_clear löscht das erste Kommando, #cmd_clear2 löscht das zweite Kommando, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #cmd_clear Zeichen, so werden die dem gerade gelöschten Kommando hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear3&lt;br /&gt;
 #cmd_clear #grd_add   i=grid   f_logtext=&amp;quot;Kunde angerufen und nicht erreicht.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#cmd_clearall==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clearall löscht alle Kommandos&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clearall&lt;br /&gt;
&lt;br /&gt;
=CSV=&lt;br /&gt;
&lt;br /&gt;
Die CSV-Routinen werden verwendet, um CSV-Dateien einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==#csv_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_open öffnet eine CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_open öffnet die erste CSV-Datei, #csv_open2 öffnet die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*ber - wenn Y, werden die Zeilenumbrüche innerhalb von Feldern durch Leerzeichen ersetzt. Die Felder müssen dabei in doppelten Anführungszeichen eingeschlossen sein.&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - (&amp;quot;Filename&amp;quot;) Dateiname der CSV-Datei&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich. Muss bereits hier gesetzt werden, wenn mit $CSV_LINE auf den Header zugegriffen werden soll, bevor #csv_line ausgeführt wird.&lt;br /&gt;
*txt (&amp;quot;Text&amp;quot;) - alternativ zum Dateinamen fn die Nummer eines Textes, der als CSV-Datei verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open  fn=c:\temp\text.csv&lt;br /&gt;
&lt;br /&gt;
==#csv_line==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_line geht zeilenweise durch die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_line geht durch die erste CSV-Datei, #csv_line2 geht durch die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;database&amp;quot;) - Die Datenbank, für welche die Transaktion ausgeführt wird, wenn ert=Y gesetzt ist. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
*er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
*ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt, Funktionen werden ersetzt&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich.&lt;br /&gt;
*m (&amp;quot;maximum&amp;quot;) - Maximale Anzahl der Zeilen, die verarbeitet wird. Wird gerne bei der Entwicklung verwendet, um die Bearbeitungsgeschwindigkeit zu erhöhen. Funktionen werden ersetzt&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird im Falle einer Exception die Bearbeitung nicht abgebrochen, sondern lediglich Warnungen geloggt; Default N, Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Semikolon, Funktionen werden ersetzt&lt;br /&gt;
*trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_line  er=test_csv_line   hhr=Y   m=3&lt;br /&gt;
&lt;br /&gt;
==#csv_check==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_check prüft die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnt (&amp;quot;count&amp;quot;) - Anzahl der Header-Einträge, die geprüft wird; Funktionen werden ersetzt&lt;br /&gt;
*h1, h2... (&amp;quot;header&amp;quot;) - Eintrag im Header, der auf existenz geprüft wird; Groß und Kleinschreibung ist unerheblich, Funktionen werden ersetzt.&lt;br /&gt;
*n (&amp;quot;name&amp;quot; / &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in die/den das Ergebnis (Y oder N) geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*res (&amp;quot;result&amp;quot;) - Name der Variable oder Nummer des Values, in die/den der Ergebnistext geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwischen den einzelnen Spalten; Funktionen werden ersetzt&lt;br /&gt;
*y - Typ der Prüfung; Funktionen werden ersetzt, default header&lt;br /&gt;
** header - Prüft die Existenz von Spaltennamen im Header. Die zu prüfenden Spaltennamen werden als h1, h2... übergeben, cnt ist entsprechend zu setzen. Wenn alle geprüften Spaltennamen vorhanden sind, wird Y zurück gegeben, ansonsten N. Die fehlenden Spaltennamen werden als Ergebnistext zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open   fn=C:\temp\mad\done\MTF3108_ET2607_selektion.CSV&lt;br /&gt;
 #csv_check   n=1   res=2   cnt=3   h1=eins   h2=zwei   h3=drei&lt;br /&gt;
 #coutl $VAL(1) - $VAL(2)&lt;br /&gt;
&lt;br /&gt;
==#csv_paste==&lt;br /&gt;
&lt;br /&gt;
Übernimmt eine CSV-Datei aus der Zwischenablage. Auf die Werte kann mit $SEPLINE() zugegriffen werden, siehe [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
'''Multi-Row'''&lt;br /&gt;
&lt;br /&gt;
Mit dem Multi-Row-Modus können Daten eingelesen werden, die in einer Zeile mehrere gleichartige Werte haben.&lt;br /&gt;
&lt;br /&gt;
Daten, die im Single-Row-Modus wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465&lt;br /&gt;
 01.01.2020     8574&lt;br /&gt;
 01.01.2020     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     3456&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     4457&lt;br /&gt;
 03.01.2020     7658&lt;br /&gt;
&lt;br /&gt;
Würden im Multi-Row-Modus wie folgt aussehen (und könnten auch so eingelesen werden):&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465     8574     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436     6578     3456     6578     4457     7658&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Wenn dieser Parameter einen Wert hat, dann muss die kopierte CSV-Datei in der ersten Zeile auch diesen Wert haben, oder die Aktion wird abgebrochen; Funktionen werden ersetzt&lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden.&lt;br /&gt;
* mrs (&amp;quot;multi row start&amp;quot;) - Erste Spalte für den Multi-Row-Bereich&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Tabulatorzeichen&lt;br /&gt;
* trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ; default s&lt;br /&gt;
** m - multi; siehe Abschnitt Multi-Row&lt;br /&gt;
** s - single; die CSV-Datei wird Zeile für Zeile eingelesen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
* [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
 #csv_paste   er=imp_line   hhr=Y&lt;br /&gt;
 #csv_paste   er=imp_line   y=m   mrs=1&lt;br /&gt;
&lt;br /&gt;
==$CSV()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV() greift auf einen Feldinhalt der aktuellen CSV-Zeile zu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Spalte oder 0-relative Spaltennummer. Name der Spalte setzt voraus, dass bei #csv_line der Parameter hhr gleich Y ist.&lt;br /&gt;
# optional: Stelle der Zeichens, ab dem der Inhalt des CSV-Feldes zurück gegeben wird&lt;br /&gt;
# optional: Anzahl der Zeichen, die maximal zurück gegeben werden; wird meist dafür verwendet, damit die maximale Länge von Datenbankfeldern nicht überschritten wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0)&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird in der ersten CSV-Datei (#csv_open) auf die erste Spalte (0, da 0-relativ) zugegriffen.&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0,1,30)&lt;br /&gt;
&lt;br /&gt;
Wie oben, nur werden nur die ersten 30 Zeichen zurück gegeben&lt;br /&gt;
&lt;br /&gt;
==$CSV_LINE()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV_LINE() Gibt eine ganze Zeile einer CSV-Datei zurück&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Zeile: header gibt die Header-Zeile zurück, current die aktuelle Zeile in #csv_line&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CSV_LINE wird insbesondere dafür verwendet, um CSV-Dateien mit Daten zu ergänzen. Hier im Beispiel wird jede Zeile mit einer GUID ergänzt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #text $CSV_LINE(1,current)$GUID();&lt;br /&gt;
 &lt;br /&gt;
 #csv_open   fn=c:\temp\ex.csv   hhr=Y&lt;br /&gt;
 #text_clear $CSV_LINE(1,header)guid;&lt;br /&gt;
 #csv_line   er=1   hhr=Y&lt;br /&gt;
 &lt;br /&gt;
 #text_save   fn=c:\temp\ex2.csv&lt;br /&gt;
&lt;br /&gt;
Nach dem Öffnen der bestehenden CSV-Datei (es muss hier bereits hhr gesetzt werden) wird zunächst der Header in Text 1 eingefügt, ergänzt um die Spalte ''guid'' und das abschließende Semikolon. Danach gehen wir mit #csv_line durch alle Zeile, fügen diese komplett in Text 1 ein und hängen eine GUID hinten dran. Danach wird die Datei gespeichert.&lt;br /&gt;
&lt;br /&gt;
=Text=&lt;br /&gt;
&lt;br /&gt;
==#text==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text fügt dem Text eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text fügt dem ersten Text eine Zeile hinzu, #text2 fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Und jetzt noch eine GUID: $GUID()&lt;br /&gt;
 #text Der folgende Text kommt in Großbuchstaben: $UPP(hello world)&lt;br /&gt;
&lt;br /&gt;
==#textn==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#textn fügt dem Text eine Zeile hinzu. Im Unterschied zu #text werden dabei keine Funktionen ersetzt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #textn fügt dem ersten Text eine Zeile hinzu, #text2n fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #textn und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden dabei '''nicht''' ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #textn Zeile 1&lt;br /&gt;
 #textn Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_clear löscht einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_clear löscht den ersten Text, #text_clear2 löscht den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #text_clear Zeichen, so werden die dem gerade gelöschten Text hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear7&lt;br /&gt;
 #text7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
Das vorangestellt #text_clear stellt sicher, dass Text7 leer ist. Alternativ könnte man formulieren:&lt;br /&gt;
&lt;br /&gt;
 #text_clear7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_save==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_save speichert einen Text in einer Datei.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_save speichert den ersten Text, #text_save2 speichert den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* bom (&amp;quot;Byte order mark&amp;quot;) - Wenn Y, dann wird die Datei mit BOM geschrieben; default Y&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu speichernden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname, unter dem die Datei gespeichert wird. Bestehende Dateien werden überschrieben, sofern das Betriebssystem das nicht verhindert (z.B, weil die Datei gerade geöffnet ist)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Öffnet die gespeicherte Datei gleich anschließend.&lt;br /&gt;
*sort - Wenn Y, dann wird die Datei vor dem Speichern sortiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Hello world&lt;br /&gt;
 #text_save  fn=$DIR(userroot)hello_world.txt&lt;br /&gt;
 #text_save  fn=c:\temp\export_vert_export.prepared_.csv   e=utf8   bom=N&lt;br /&gt;
&lt;br /&gt;
==#text_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_open öffnet einen Text aus einer Datei, der bisherige Inhalt der Datei wird überschrieben.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_open öffnet den ersten Text, #text_open2 öffnet den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname der Datei, die geöffnet wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_open  fn=$DIR(userroot)test.txt&lt;br /&gt;
 #text Eine weitere Zeile, $GUID()&lt;br /&gt;
 #text_save  fn=$DIR(userroot)test.txt&lt;br /&gt;
&lt;br /&gt;
==#text_props==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_props stellt Eigenschaften des Textes ein.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_props bezieht sich auf den ersten Text, #text_props2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* dub (&amp;quot;duplicates&amp;quot;) - Verhalten einer sortierten Liste bezüglich Dubletten&lt;br /&gt;
** acc (&amp;quot;accept&amp;quot;) - Dubletten werden akzeptiert&lt;br /&gt;
** err (&amp;quot;error&amp;quot;) - Dubletten führen zu Fehlern&lt;br /&gt;
** ign (&amp;quot;ignore) - Dubletten werden ignoriert&lt;br /&gt;
* srt (&amp;quot;sorted&amp;quot;) - Wenn ja, dann ist die Liste sortiert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_props   srt=Y   dup=ign&lt;br /&gt;
&lt;br /&gt;
==#text_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_set setzt eine bestimmte Zeile eines Textes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_set bezieht sich auf den ersten Text, #text_set2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;index&amp;quot;) - 0-relativer Index der Zeile, die geschrieben werden soll. Mit ''last'' kann die letzte Zeile geschrieben werden, mit ''all'' werden alle Zeilen ersetzt, das wird dann gebraucht, wenn mehrzeiliger Text zugewiesen werden soll; Funktionen werden ersetzt&lt;br /&gt;
* z - Text, der geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text_set   i=2   z=&amp;quot;dritte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=last   z=&amp;quot;letzte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=all   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
==#text_sort==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_sort sortiert einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_sort bezieht sich auf den ersten Text, #text_sort2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* y - Typ, default alpha, Funktionen werden ersetzt&lt;br /&gt;
** alpha - sortiert alphanumerisch&lt;br /&gt;
** inv - invertiert die gegebene Reihenfolge&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=&amp;quot;,OU=2nd_Level_T1,OU=Kundenservice,OU=Benutzer,OU=Testtours,OU=Travel&amp;quot;&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text_dissect   z=$VAL(1)   sep=&amp;quot;,OU=&amp;quot;&lt;br /&gt;
 #coutl  $TEXT(1)&lt;br /&gt;
 #text_sort   y=inv&lt;br /&gt;
 #text_compose   n=1   sep=.&lt;br /&gt;
 #val_set   n=1   z=tt.$VAL(1)&lt;br /&gt;
 #coutl $VAL(1)&lt;br /&gt;
&lt;br /&gt;
 Ergebnis ist:&lt;br /&gt;
 2nd_Level_T1&lt;br /&gt;
 Kundenservice&lt;br /&gt;
 Benutzer&lt;br /&gt;
 Testtours&lt;br /&gt;
 tt.Testtours.Benutzer.Kundenservice.2nd_Level_T1.&lt;br /&gt;
&lt;br /&gt;
==#text_dissect==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_dissect zerteilt einen String anhand einer vorgegebenen Trennzeichenfolge und fügt das Ergebnis dem betreffenden Text hinzu. Gegebenenfalls muss der Text vorher mit #text_clear geleert werden.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_dissect bezieht sich auf den ersten Text, #text_dissect bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - wenn Y, wird die sep-Zeichenfolge noch mal dem String angehängt; default N, Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, anhand der String zerteilt wird; Funktionen werden ersetzt&lt;br /&gt;
* z - String, der zerlegt wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_compose==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_compose setzt einen Text mithilfe eines Trennzeichens zu einem String zusammen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_compose bezieht sich auf den ersten Text, #text_compose bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - Wenn Y, wird die Trennzeichenfolge auch noch mal am Ende des Strings eingefügt; default N, Funktionen werden ersetzt&lt;br /&gt;
* n - Nummer des Values oder Name der Variable, in welche der String geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichenfolge, die beim Zusammenfügen des Textes verwendet wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_act==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_act bearbeitet einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_act bezieht sich auf den ersten Text, #text_act2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text der Zeile, die bei insert eingefügt werden soll; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* cu (&amp;quot;current&amp;quot;) - 0-relative Zeilennummer der Operation; default 0, Funktionen werden ersetzt&lt;br /&gt;
* ne (&amp;quot;new&amp;quot;) - 0-relative Zeilennummer als Ziel bei move; default 0, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt&lt;br /&gt;
** delete - Löscht die Zeile an Position cu (&amp;quot;current&amp;quot;)&lt;br /&gt;
** insert - Fügt den Text c an der Position cu (&amp;quot;current&amp;quot;) ein&lt;br /&gt;
** move - verschiebt die Zeile cu (&amp;quot;current&amp;quot;) nach Zeile ne (&amp;quot;new&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #text_act   y=move   cu=0&lt;br /&gt;
&lt;br /&gt;
==#text_loop==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_loop geht durch die Zeilen eines Textes und ruft für jede Zeile ''er'' auf&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_loop  bezieht sich auf den ersten Text, #text_loop2  bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich ert bezieht&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m - (&amp;quot;maximum&amp;quot;) Es wird maximal für die Anzahl der angegebenen Zeilen das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* n - Name der Variable, in welche die 0-relative Schleifenvariable geschrieben wird. (Es würde auch in einen Value geschrieben, wenn es sich um eine Nummer handelt, das ergibt in der Praxis aber meist nicht viel Sinn) Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear eins&lt;br /&gt;
 #text zwei&lt;br /&gt;
 #text drei&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear #coutl - $TEXT(1,$VAR(eins))&lt;br /&gt;
 #text_loop   er=1   n=eins&lt;br /&gt;
&lt;br /&gt;
==#tvl_add==&lt;br /&gt;
&lt;br /&gt;
Addiert dem Wert in einer Text-Valueliste einen Wert hinzu. Es handelt sich dabei um eine nummerierte Prozedur: #tvl_add arbeitet mit Text 1, #tvl_add2 mit Text 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Zeile, der ein Wert hinzugefügt wird; Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Operation, Funktionen werden ersetzt, default text&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
* z - Der Wert, der hinzugefügt wird&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text eins=1&lt;br /&gt;
 #text zwei=2&lt;br /&gt;
 #text drei=3&lt;br /&gt;
 #tvl_add   y=int   n=zwei   z=1&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==$TEXT()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $TEXT() wird auf den Inhalt des Textes zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# optional Zeile des Textes (0-relativ). Wenn es keinen zweiten Parameter gibt, wird der komplette Text zurück gegeben. Alternativ als zweiter Parameter eine Sonderfunktion:&lt;br /&gt;
## cnt / count - Gibt die Anzahl der Zeilen zurück&lt;br /&gt;
## last - Gibt die letzte Zeile zurück&lt;br /&gt;
## ix - Gibt die Position des Textes im dritten Parameter zurück&lt;br /&gt;
## as_line - Gibt den Text als eine Zeile zurück, Zeilenumbrüche werden durch den dritten Parameter ersetzt&lt;br /&gt;
# optional in abhängigkeit vom zweiten Paremeter&lt;br /&gt;
## wenn zweiter Parameter ix: Textzeile, nach der mit ix gesucht wird&lt;br /&gt;
## wenn zweiter Parameter as_line: Zeichenfolge, mit der die Zeilenumbrüche ersetzt werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Zeile 3&lt;br /&gt;
 #message  c=$TEXT(1)&lt;br /&gt;
&lt;br /&gt;
 #code url=$TEXT(1,as_line,&amp;amp;)&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich gilt in BAL: Eine Prozedur - eine Zeile.&lt;br /&gt;
&lt;br /&gt;
Bei vielen und/oder langen Parametern führt das zu recht langen Code-Zeilen und zu Unübersichtlichkeit. Hier können nun Teile der Parameter mit #code in weitere Zeile ausgelagert werden, deren Inhalt dann mit $CODE$ oder $CODE$ der eigentlichen Code-Zeile hinzugefügt wird.&lt;br /&gt;
&lt;br /&gt;
==#code==&lt;br /&gt;
&lt;br /&gt;
Fügt Text dem Code-Speicher hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#code hat keine benannten Parameter. Die ganze Zeile nach dem #code und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=G:\pics\pic5d68865cdaba62_62767562.jpg&lt;br /&gt;
 #code fn2=G:\pics\pic5d913c48682128_67979256.jpg&lt;br /&gt;
 #email_send   from=test@****.de   to=info@*****************.de   bcc=info@*****.de   subject=Testmail   text=$TEXT(1)   $CODE$&lt;br /&gt;
&lt;br /&gt;
==$CODE$ / $CODEN$==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CODE$ und $CODEN$ sind keine Funktionen, auch wenn sie auf den ersten Blick ähnlich aussehen. Sie haben keine Parameter und auch keine Klammern, dafür ein abschließendes $.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen fügen den Code-Speicher der jeweiligen Zeile hinzu. $CODE$ löscht danach den Code-Speicher, $CODEN$ tut das nicht, so dass dieselben Parameter wiederholt eingefügt werden können (beim letzten Einfügen sollte dann $CODE$ verwendet werden).&lt;br /&gt;
&lt;br /&gt;
=Separierte Zeile=&lt;br /&gt;
&lt;br /&gt;
Eine separierte Zeile ist eine Textzeile, die mehrere gleichartige Werte enthält, die durch Trennzeichen getrennt sind.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 3244,4465,7763,4536,4356,7777&lt;br /&gt;
&lt;br /&gt;
Solche Zeilen können mit #sepline aufgetrennt werden.&lt;br /&gt;
&lt;br /&gt;
==#sepline==&lt;br /&gt;
&lt;br /&gt;
Trennt eine separierte Zeile auf und führt für jeden Wert das mit er angegebene Kommando aus.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur (#sepline, #sepline2...)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y; Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, für welche die Transaktion gestartet wird, wenn ert=Y. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern (&amp;quot;each row no&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Wenn Y, wird für jeden Wert der separierten Zeile eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Es wird maximal für die Anzahl der angegebenen Werte das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten; Funktionen werden ersetzt.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N; Funktionen werden ersetzt.&lt;br /&gt;
* nn (&amp;quot;not null&amp;quot;) - Wenn Y, dann wird er nur für Werte der separierten Zeile aufgerufen, die nicht leer sind. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Das oder die Trennzeichen; default ist das Semikolon, Funktionen werden ersetzt.&lt;br /&gt;
* z - Der Inhalt der separierten Zeile; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(1)&lt;br /&gt;
 #sepline z=3244,4465,7763,4536,4356,7777   sep=,   er=1&lt;br /&gt;
&lt;br /&gt;
==$SEPLINE()==&lt;br /&gt;
&lt;br /&gt;
Greift auf den einzelnen Wert einer mit #sepline getrennten Zeile zu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der separierten Zeile&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(3)&lt;br /&gt;
 #sepline3 z=3244;4465;7763;4536;4356;7777     er=1&lt;br /&gt;
&lt;br /&gt;
=User und Rechte=&lt;br /&gt;
&lt;br /&gt;
Aus Gründen der Übersichtlichkeit ist die Rechtevergabe zweistufig:&lt;br /&gt;
&lt;br /&gt;
# Es werden (meist am Anfang eines Primär-Kommandos) Rechte-Definitionen erstellt, die einer oder mehreren Benutzergruppen Rechte (lesen oder lesen und schreiben) zuweisen. Die Rechte werden dabei implizit auch allen Untergruppen der angegebenen Benutzergruppe erteilt (Zum Beispiel: Rechte der Gruppe ''user'' hat auch implizit die Gruppe ''user.admin'').&lt;br /&gt;
# Dem Parameter r verschiedener Prozeduren kann dann eine Rechte-Definition zugewiesen werden.&lt;br /&gt;
&lt;br /&gt;
Den Parameter r als Rechte-Definition berücksichtigen die folgenden Prozeduren:&lt;br /&gt;
&lt;br /&gt;
* #frm&lt;br /&gt;
* Buttons (#btn, #btns_btn)&lt;br /&gt;
* Alle Segmente (#text_seg, #memo_seg, #btns_seg, vl_seg, #grd_seg, #xgrd_seg)&lt;br /&gt;
* Tree (#tree_add, #tree_fill, #tree_fillsql, Lese-Recht reicht)&lt;br /&gt;
* Grid-Spalten (#grd_col, #xgrd_col)&lt;br /&gt;
* #vl_line (für die komplette Zeile (r) und die einzelne Zelle (r1, r2, r3...))&lt;br /&gt;
&lt;br /&gt;
Wo der Parameter r nicht gesetzt ist, wird die Rechte-Definition der Formulars verwendet.&lt;br /&gt;
&lt;br /&gt;
==#rights==&lt;br /&gt;
&lt;br /&gt;
Setzt eine Rechte-Definition im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Rechte-Definition; default ist ''frm'', also dsa Default-Recht für das Formular.&lt;br /&gt;
* r_ (&amp;quot;right&amp;quot;) - Prefix für die Benutzergruppe. Für die Rechte-Definition sind die folgenden Werte zulässig&lt;br /&gt;
** n (&amp;quot;no&amp;quot;) - kein Recht&lt;br /&gt;
** r (&amp;quot;read&amp;quot;) - nur lesen&lt;br /&gt;
** w (&amp;quot;write&amp;quot;) - lesen und schreiben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights  n=frm   r_user=r   r_user.admin=w&lt;br /&gt;
&lt;br /&gt;
Setzt für alle User das Lese-Recht und für Administratoren das Lese- und Schreibrecht.&lt;br /&gt;
&lt;br /&gt;
==#rights_clear==&lt;br /&gt;
&lt;br /&gt;
Löscht alle Rechte-Definitionen im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
(Wird in der Praxis selten benötigt, weil Kommandos mit leerer Rechte-Definition starten.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights_clear&lt;br /&gt;
&lt;br /&gt;
==$USERID()==&lt;br /&gt;
&lt;br /&gt;
Die ID des angemeldeten Users&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kusr=$USERID()&lt;br /&gt;
&lt;br /&gt;
==$RIGHTUSERID()==&lt;br /&gt;
&lt;br /&gt;
Administratoren können andere User einstellen (Userliste links unten im BAF-Client), vor allem um deren Rechte zu prüfen. Die UserID dieses ausgewählten Users kann mit der Funktion $RIGHTUSERID() ermittelt werden.&lt;br /&gt;
&lt;br /&gt;
In fast allen Fällen gilt der folgende Grundsatz: Lesende Operationen mit $RIGHTUSERID(), schreibende Operationen mit $USERID().&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_open   kusr=$RIGHTUSERID()&lt;br /&gt;
&lt;br /&gt;
==$ADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der angemeldete User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $ADM()&lt;br /&gt;
&lt;br /&gt;
==$RADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der ausgewählte User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $RADM()&lt;br /&gt;
&lt;br /&gt;
=Ausführen=&lt;br /&gt;
&lt;br /&gt;
==#exec==&lt;br /&gt;
&lt;br /&gt;
Führt ein anderes Kommando aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Names des (Primär- oder Sub-) Kommandos, das ausgeführt werden soll.&lt;br /&gt;
* ex (&amp;quot;exception&amp;quot;) - Name oder Nummer des Kommandos, das ausgeführt wird, wenn bei der Ausführung von cmd eine Exception auftritt; siehe Beispiele&lt;br /&gt;
* fin (&amp;quot;finally&amp;quot;) - Name oder Nummer des Kommandos, das nach der Ausführung von cmd ausgeführt wird - egal ob eine Exception aufgetreten ist oder nicht. Wird nur berücksichtigt, wenn der Parameter ex nicht gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel löst das Problem, dass ein neues PDF unter demselben Dateinamen nicht erstellt werden kann, wenn beim vorherigen Versuche der Erstellung eine Exception aufgetreten ist. In einem solchen Fall wurde ein #pdf_start, aber kein #pdf_stop ausgeführt, und die geöffnete Datei sperrt diesen Dateiname, bis der BAF-Client geschlossen wird. Lösung dieses Problems ist es, im Parameter ex ein #pdf stop auszuführen; auf das Öffnen der Datei kann in einem solchen Fall verzichtet werden. Mit der Funktion $DATA() wird hier im Beispiel gezielt eine Exception ausgelöst.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test_pdf&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #pdf_text  c=&amp;quot;Hello World&amp;quot;&lt;br /&gt;
 -- #cmd #pdf_text  c=&amp;quot;Hello World $DATA(dat,test)&amp;quot;&lt;br /&gt;
 #cmd #pdf_stop   o=Y&lt;br /&gt;
 &lt;br /&gt;
 #pdf_start  fn=$DIR(doc)\test.pdf&lt;br /&gt;
 #exec   cmd=1   ex=&amp;quot;#pdf_stop   o=N&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test_pdf executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#batchexec==&lt;br /&gt;
&lt;br /&gt;
Speichert den Text n in der Datei batch.bat und führt diese aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clr (&amp;quot;clear&amp;quot;) - Wenn Y, wird der Text nach Ausführung des Batch-Datei gelöscht; Default Y; Funktionen werden ersetzt;&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes; der mit #text gespeicherte Text hat die Nummer 1 &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #batchexec   n=1&lt;br /&gt;
&lt;br /&gt;
==#file_open==&lt;br /&gt;
&lt;br /&gt;
Öffnet eine Datei (oder auch eine Webseite)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder die URL der Webseite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_open  fn=c:\temp\test.csv&lt;br /&gt;
 #file_open  fn=https://www.google.de&lt;br /&gt;
&lt;br /&gt;
==#loop==&lt;br /&gt;
&lt;br /&gt;
BAL kennt keine Schleifen als Sprachelement. Um Schleifen mit einer fest Schleifenzahl auszuführen, wird die Prozedur #loop verwendet. lf muss nicht kleiner als lt sein, #loop kann auch von oben nach unten zählen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* lf (&amp;quot;loop from&amp;quot;) - Anfangswert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* lt (&amp;quot;loop to&amp;quot;) - Endwert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in der die Schleifenvariable gespeichert wird (damit sie an anderer Stelle gelesen werden kann); Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #loop   lf=42   lt=1337   er=test_line&lt;br /&gt;
&lt;br /&gt;
==#exit==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #exit bricht die Ausführung auf der jeweiligen Code-Ebene (Kommando bzw. Sub-Kommando) ab&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 ~ $EMPTY($PVAL(vl,id))   and   $PVAL(vl,status) &amp;gt; 20&lt;br /&gt;
 #sql select nextval('ausza_id') as id&lt;br /&gt;
 #sql_openval   f_id=1&lt;br /&gt;
 #page_val   i=vl   f=id   z=$VAL(1)&lt;br /&gt;
 #save&lt;br /&gt;
 #exit&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Der Beispiel-Code befindet sich auf der Seite xausza_page_ausza und baut die entsprechende Seite auf. Er prüft, ob bereits eine ID-Gesetzt ist - wenn nicht, wird über eine Datenbank-Sequenz die nächste ID abgefragt, in das VL-Segment geschrieben und die Seite gespeichert. Beim Speichern der Seite wird sie jedoch neu aufgerufen, also komplett neu aufgebaut, was erst einmal kein Problem ist. Danach würde aber die Ausführung auf der Code-Ebene, auf der sich #save befindet, fortgeführt, was zur Folge hat, dass die dann folgenden Segmente doppelt erscheinen (zunächst die aus dem Neu-Aufbau der Seite, dann die, die von der Fortsetzung des Codes her stammen).&lt;br /&gt;
&lt;br /&gt;
Um dies zu vermeiden muss die Ausführung des Codes nach #save abgebrochen werden.&lt;br /&gt;
&lt;br /&gt;
==$EXEC==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando. Im ausgeführten Kommando kann eine Variable gesetzt werden, die dann als Funktionsergebnis von $EXEC zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll&lt;br /&gt;
# optional: Der Name der Variablen, in der das Ergebnis steht; default ist ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;test_funkexec&amp;quot;   y=console&lt;br /&gt;
 #cout   c=$EXEC(test_funkexec_line)&lt;br /&gt;
&lt;br /&gt;
 -- test_funkexec_line&lt;br /&gt;
 #var_set   n=result   z=42&lt;br /&gt;
&lt;br /&gt;
=Dateien und Verzeichnisse=&lt;br /&gt;
&lt;br /&gt;
==#file_op==&lt;br /&gt;
&lt;br /&gt;
Führt eine Operation mit einer Datei oder einem Verzeichnis aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder des Verzeichnisses&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in die/den das Ergebnis der Operation (Y oder N) geschrieben wird.&lt;br /&gt;
* on (&amp;quot;old name) - der bisherige Dateiname bei RenameFile&lt;br /&gt;
* y - Typ der Operation&lt;br /&gt;
** cd / createdir - Erzeugt ein Verzeichnis&lt;br /&gt;
** cf / copyfile - Kopiert eine Datei (von on zu fn)&lt;br /&gt;
** df / deletefile - Löscht eine Datei&lt;br /&gt;
** fd / forcedirectories - Stellt sicher, dass ein Pfad vorhanden ist&lt;br /&gt;
** rd / removedir - Entfernt ein Verzeichnis&lt;br /&gt;
** rf / renamefile - Benennt eine Datei um, kann auch dazu verwendet werden, eine Datei zu verschieben&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #file_op   y=renamefile   on=c:\temp\debug.txt   fn=c:\temp\test\debug.txt   n=1&lt;br /&gt;
 #cout   c=$VAL(1)&lt;br /&gt;
 &lt;br /&gt;
 #file_op   y=fd   fn=c:\eins\zwei\drei\vier&lt;br /&gt;
&lt;br /&gt;
==#file_search==&lt;br /&gt;
&lt;br /&gt;
Sucht Dateien und schreibt die Ergebnisliste in einen Text.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* clr - (&amp;quot;clear&amp;quot;) wenn Y, wird der Text vor der Suche geleert. Default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, in den die Ergebnisliste geschrieben wird; default 1, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_search   fn=c:\*.ini   n=1   y=0   all_=Y&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==#file_wait==&lt;br /&gt;
&lt;br /&gt;
Wartet, bis zumindest eine Datei vorhanden ist, die den Kriterien entspricht, und führt dann cmd aus. Wird nach der in to eingestellten Zeit keine Datei gefunden, dann wird mit dem in cmdto eingestellten Kommando abgebrochen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* cmd - Kommando, das ausgeführt wird, sobald eine Datei gefunden wird; Funktionen werden ersetzt&lt;br /&gt;
* cmdto - Kommando, das ausgeführt wird, sobald die Prozedur wegen eines TimeOuts abgebrochen wird; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* sleep - Zeit in ms zwischen den einzelnen Suchen nach einer Datei, die den Kriterien entspricht; Default 1000, Funktionen werden ersetzt&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in ms, nach der die Ausführung abgebrochen wird; Default 15000, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #cout c=&amp;quot;Gefunden&amp;quot;&lt;br /&gt;
 #cmd_clear2 #cout c=&amp;quot;TimeOut&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #file_wait   fn=C:\temp\test\*.txt   cmd=1   cmdto=2&lt;br /&gt;
&lt;br /&gt;
==#dir_force==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass es den spezifizierten Verzeichnispfad gibt, indem erforderlichenfalls Verzeichnisse angelegt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Names des Pfads&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_force   n=c:\temp\pdf&lt;br /&gt;
&lt;br /&gt;
==#dir_proc==&lt;br /&gt;
&lt;br /&gt;
Durchsucht ein Verzeichnis nach Dateien, die den angegebenen Kriterien entsprechen, und führt für jede gefundene Datei ''cmd'' aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das für jede gefundene Datei ausgeführt wird&lt;br /&gt;
* dn (&amp;quot;DirectoryName&amp;quot;) - Pfad des Verzeichnisses, in dem die Dateien gesucht werden; Funktionen werden ersetzt.&lt;br /&gt;
* done - Verzeichnis, in das die Dateien nach Abarbeitung verschoben werden (sofern der Parameter nicht leer ist). Funktionen werden ersetzt.&lt;br /&gt;
* error- Verzeichnis, in das die Dateien nach Abarbeitung verschoben werden (sofern der Parameter nicht leer ist), wenn der Inhalte der unter ndone angegebenen Variablen E ist. Funktionen werden ersetzt.&lt;br /&gt;
* fn (&amp;quot;filename&amp;quot;) - Suchkriterium für den Dateinamen; Funktionen werden ersetzt; Default *&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in welcher der Dateiname der aktuell zu bearbeitenden Datei inklusive Pfad gespeichert wird; Funktionen werden ersetzt; Default dir_proc&lt;br /&gt;
* ndone(&amp;quot;name done&amp;quot;) - Name der Variablen, die bestimmt, ob eine Datei in das Done-Verzeichnis verschoben wird. Vor jedem Aufruf von cmd wird diese Variable auf 'Y' gesetzt. Sie kann während der Bearbeitung auf N gesetzt werden - damit wird verhindert, dass die Datei in das Done-Verzeichnis verschoben wird. Wir die Variable auf E gesetzt, wird die Datei ins Error-Verzeichnis verschoben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_proc   dn=c:\temp\in   done=c:\temp\done   fn=*.csv   cmd=importcsv_line&lt;br /&gt;
&lt;br /&gt;
==$FILEINFO()==&lt;br /&gt;
&lt;br /&gt;
Liefert Infos über eine Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Dateiname&lt;br /&gt;
# Typ der Information, es stehen dabei folgende Optionen zur Verfügung&lt;br /&gt;
#* size - Dateigröße in Byte&lt;br /&gt;
#* size_point - Dateigröße in Byte, Punkte alle drei Zeichen von rechts&lt;br /&gt;
#* size_auto - Dateigröße in Byte, kB, MB oder GB, je nach Größe; mit Einheit&lt;br /&gt;
#* size_kb - Dateigröße in kB (analog Windows-Explorer)&lt;br /&gt;
#* date - Datum im Format dd.mm.yyyy&lt;br /&gt;
#* date_yyyy - Datum im Format yyyymmdd&lt;br /&gt;
#* datetime - Datum und Uhrzeit im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
#* datetime_yyyy - Datum im Format yyyymmddhhmmss&lt;br /&gt;
#* exists - Y, wenn die Datei existiert, sonst N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=fn   z=&amp;quot;T:\Tools Gruppenrechte\BC3 light\BafClientFM.exe&amp;quot;&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_point)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_auto)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_kb)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),exists)&lt;br /&gt;
&lt;br /&gt;
Ergebnis&lt;br /&gt;
&lt;br /&gt;
 27668480&lt;br /&gt;
 27.668.480&lt;br /&gt;
 26,39 MB&lt;br /&gt;
 27.020 kB&lt;br /&gt;
 02.05.2023&lt;br /&gt;
 20230502&lt;br /&gt;
 02.05.2023 12:20:09&lt;br /&gt;
 20230502122009&lt;br /&gt;
 Y&lt;br /&gt;
&lt;br /&gt;
==$DIR()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Verzeichnisnamen. Trailing Path Delimiter (\ bei Windows) wird immer angehängt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bezeichnung des Verzeichnisses&lt;br /&gt;
## appdata - Verzeichnis für Anwendungsdaten des Users&lt;br /&gt;
## cappdata - gemeinsames Verzeichnis für Anwendungsdaten aller User&lt;br /&gt;
## cdoc - gemeinsames Dokumentenverzeichnis  aller User&lt;br /&gt;
## cfav / cfavorites - gemeinsames Favoritenverzeichnis aller User&lt;br /&gt;
## cmusic - gemeinsames Musikverzeichnis aller User&lt;br /&gt;
## cpic / cpictures - gemeinsames Bilderverzeichnis aller User&lt;br /&gt;
## cvideo - gemeinsames Videoverzeichnis aller User&lt;br /&gt;
## desktop - Desktopverzeichnis des Rechners&lt;br /&gt;
## '''doc''' / docdir - Dokumentenverzeichnis des Users&lt;br /&gt;
## downloads - Downloadsverzeichnis des Users&lt;br /&gt;
## fav / favorites - Favoritenverzeichnis des Users&lt;br /&gt;
## fonts - Fontsverzeichnis des Rechners&lt;br /&gt;
## music - Musikverzeichnis des Users&lt;br /&gt;
## pic / pictures - Bilderverzeichnis des Users&lt;br /&gt;
## prog / program - Programmverzeichnis des Rechners&lt;br /&gt;
## prog86 / program86 - Programm86-Verzeichnis des Rechners&lt;br /&gt;
## '''root''' - Root-Verzeichnis des BAF-Clients bzw. des BAF-Servers&lt;br /&gt;
## '''userroot''' / usrroot - User-Verzeichnis des BAF-Clients&lt;br /&gt;
## video - Videoverzeichnis des Users&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=$DIR(doc)test.txt&lt;br /&gt;
&lt;br /&gt;
==$FILEDIALOG()==&lt;br /&gt;
&lt;br /&gt;
Führt einen Dateiauswahl-Dialog aus und gibt den gewählten Dateinamen zurück. Im Falle des Abbruchs wird ''abort'' zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wenn der erste Parameter ''save'' lautet, wird ein Speichern-Dialog, sonst ein Öffnen-Dialog aufgerufen.&lt;br /&gt;
# Filter-Statement, immer Kombinationen aus Text (Text-Dateien *.txt) und Filter-Statement(*.txt), getrennt durch Pipes.&lt;br /&gt;
# Standard-Dateierweiterung&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=&amp;quot;$FILEDIALOG(save,Text-Dateien *.txt|*.txt|Alle Dateien *.*|*.*,txt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Bitte beachten: Wegen der Leerzeichen im Filter-Statement muss der ganze Parameter in doppelte Anführungszeichen gesetzt werden.)&lt;br /&gt;
&lt;br /&gt;
=ZIP=&lt;br /&gt;
&lt;br /&gt;
==#zip_create==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine ZIP-Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Dateien, die der ZIP-Datei hinzugefügt werden; Funktionen werden ersetzt&lt;br /&gt;
* dir (&amp;quot;directory&amp;quot;) - Verzeichnis, wenn das nicht bei allen fn1, fn2... angegeben werden soll&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Der Dateiname, unter dem die ZIP-Datei gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* fn1, fn2,... (&amp;quot;FileName&amp;quot;) - Die Dateien, die in der ZIP-Datei gespeichert werden; die Anzahl wird mit dem Parameter cnt bestimmt; Funktionen werden ersetzt&lt;br /&gt;
* list - Nummer eines Textes (#text, #text2...), in dem die Dateien gelistet sind, die der ZIP-Datei hinzugefügt werden sollen. Wenn list ein Wert größer 0 hat, werden cnt und fn1, fn2... ignoriert. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* pw (&amp;quot;PassWord&amp;quot;) - Password der erzeugten ZIP-Datei; Funktionen werden ersetzt.&lt;br /&gt;
* pwc (&amp;quot;PassWordCrypted&amp;quot;) - Wenn Y, dann ist das Passwort mit der Verschlüsselungsfunktion auf der Seite Tools des Code-Dialogs verschlüsselt. Hinweis: Mit dieser Verschlüsselung verhindert man lediglich, dass das Passwort direkt aus dem Code ausgelesen werden kann. Wird der BAF-Client mit dem Delphi-Debugger ausgeführt, lässt sich leicht an die betreffende Stelle ein Breakpoint setzen und das Passwort dann im Klartext auslesen (dieselbe Unit uBafCrypt vorausgesetzt).&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #zip_create   fn=$VAR(root).zip   list=1&lt;br /&gt;
 &lt;br /&gt;
 #var_set   n=fn_zip   z=tt_mail_$VAR(reise)-$VAR(reisename)_$PAD($VAR(lfdnr),4,L,0)_$NOWFMT(yyyymmdd).zip&lt;br /&gt;
 #file_op   y=df   fn=$VAR(path)\$VAR(fn_zip)&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=$VAR(filename).txt&lt;br /&gt;
 #code fn2=$VAR(filename).sab&lt;br /&gt;
 #zip_create   dir=$VAR(path)   fn=$VAR(path)\$VAR(fn_zip)    pw=$VAR(pw)   $CODE$&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #zip_create ersetzt nicht vorherige Dateien. Von daher im Zweifelsfall wie im zweiten Beispiel vorher eine Datei dieses Namens löschen.&lt;br /&gt;
&lt;br /&gt;
=Ini-Dateien=&lt;br /&gt;
&lt;br /&gt;
Der BAF-Client verwendet eine Ini-Datei im Root-Verzeichnis (vor allem für die Datenbankverbindungen) und eine Ini-Datei ''BafClientFM.ini'' im User-Anwendungsverzeichnis (vor allem für die Formularpositionen). Es können aber auch weitere Ini-Dateien verwendet werden.&lt;br /&gt;
&lt;br /&gt;
==#ini_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Ini-Datei. #ini_val ist eine nummerierte Prozedur: #ini_val schreibt in die erste Ini-Datei, #ini_val2 in die zweite Ini-Datei und so weiter. Diese Ini-Dateien werden zunächst nur im Speicher gehalten und müssen explizit aus einer Datei geladen oder in eine Datei gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;item&amp;quot; / &amp;quot;ident&amp;quot;) - Name des Eintrags in der Ini-Datei; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Wenn der Parameter n den Wert ''usr'' oder ''user'' hat, dann bleibt die Nummer der Ini-Datei unberücksichtigt und der Wert wird in die Datei ''BafClientFM.ini'' im im User-Anwendungsverzeichnis geschrieben.&lt;br /&gt;
* sec (&amp;quot;section&amp;quot;) - Abschnitt in der Ini-Datei; Funktionen werden ersetzt; default ''values''&lt;br /&gt;
* z - Wert, der in die Ini-Datei geschrieben wird; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_val  i=date_last   z=$NOW()&lt;br /&gt;
&lt;br /&gt;
==#ini_load==&lt;br /&gt;
&lt;br /&gt;
Lädt eine Ini-Datei aus einer Datei. Es handelt sich um eine nummerierte Prozedur: #ini_load lädt die Ini-Datei 1, #ini_load2 lädt die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, die geladen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_load   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==#ini_save==&lt;br /&gt;
&lt;br /&gt;
Speichert eine Ini-Datei ineine Datei. Es handelt sich um eine nummerierte Prozedur: #ini_save speichert die Ini-Datei 1, #ini_save2 speichert die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, in die gespeichert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_save   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==$INI()==&lt;br /&gt;
&lt;br /&gt;
Liest einen Wert aus einer Ini-Datei.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
# Item (Ident)&lt;br /&gt;
# optional: Sektion; wenn nicht vorhanden, dann ''values''. Wenn ''db!'', dann wird als Sektion die aktuell gewählte Datenbankverbindung verwendet (in diesem Fall sollte als erster Parameter ''root'' verwendet werden).&lt;br /&gt;
# optional: Default-Wert; wenn nicht vorhanden, dann ein leerer String&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum)&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum,bearbeitung,$TODAY())&lt;br /&gt;
&lt;br /&gt;
==$INITEXT()==&lt;br /&gt;
&lt;br /&gt;
Gibt die komplette Ini-Datei zurück. Wird vor allem beim Debugging verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $INITEXT(usr)&lt;br /&gt;
&lt;br /&gt;
=Zwischenablage=&lt;br /&gt;
&lt;br /&gt;
Das BAF-Framework unterstützt die Zwischenablage nur für Text.&lt;br /&gt;
&lt;br /&gt;
==#clipboard==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Text in die Zwischenablage&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* z - Wert, der in der Zwischenablage gespeichert werden soll; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #clipboard   z=$TEXT()&lt;br /&gt;
 #clipboard   z=$CHR(dquote)$PVAL(test,zahl,allsel,$CHR(crlf))$CHR(dquote)&lt;br /&gt;
&lt;br /&gt;
==$CLIPBOARD()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Text aus der Zwischenablage zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setvar   n=clp   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
=String-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben einen String zurück.&lt;br /&gt;
&lt;br /&gt;
==$BASE64()==&lt;br /&gt;
&lt;br /&gt;
En- oder Decodiert einen Text im Base64-Code&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Encoding oder Decoding:&lt;br /&gt;
## e - Encoding&lt;br /&gt;
## d - Decoding&lt;br /&gt;
# Text, der en-oder decodet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $BASE64(e,Dies ist ein Test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$CHR()==&lt;br /&gt;
&lt;br /&gt;
Gibt ein Zeichen (ggf zwei Zeichen) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Ansi-Zeichennummer oder eine der folgenden Bezeichnungen:&lt;br /&gt;
## crlf - Zeilenumbruch #13#10&lt;br /&gt;
## cr - Zeichen #13&lt;br /&gt;
## lf - Zeichen #10&lt;br /&gt;
## tab - Tabulator&lt;br /&gt;
## quote - ' (einfache Anführungszeichen)&lt;br /&gt;
## dquote - &amp;quot; (doppelte Anführungszeichen)&lt;br /&gt;
## space / leer - Leerzeichen&lt;br /&gt;
## comma / komma - , (Komma)&lt;br /&gt;
## questionmark / qmark / frage / fragezeichen - ?&lt;br /&gt;
## bro / bracket_open - (&lt;br /&gt;
## brc / bracket_close - )&lt;br /&gt;
## dollar - $&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CONVERT()==&lt;br /&gt;
&lt;br /&gt;
Konvertiert einen String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Konvertierungsfunktion&lt;br /&gt;
## isodate&lt;br /&gt;
## isodatetime&lt;br /&gt;
## truefalse&lt;br /&gt;
## pointfloat&lt;br /&gt;
## urlcode&lt;br /&gt;
## utf8&lt;br /&gt;
# String, der konvertiert werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $CONVERT(isodate,2025-03-12)&lt;br /&gt;
 #coutl $CONVERT(isodatetime,2025-03-12 12:03:17)&lt;br /&gt;
 #coutl $CONVERT(truefalse,true)&lt;br /&gt;
 #coutl $CONVERT(pointfloat,12.3)&lt;br /&gt;
 #coutl $CONVERT(urlcode,Für schönen Ärger)&lt;br /&gt;
 #coutl $CONVERT(utf8,Für schönen Ärger)&lt;br /&gt;
&lt;br /&gt;
(Ergebnis)&lt;br /&gt;
 12.03.2025&lt;br /&gt;
 12.03.2025 12:03:17&lt;br /&gt;
 Y&lt;br /&gt;
 12,3&lt;br /&gt;
 F%C3%BCr%20sch%C3%B6nen%20%C3%84rger&lt;br /&gt;
 Für schönen Ärger&lt;br /&gt;
&lt;br /&gt;
==$COPY()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$COPY($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$EXEC()==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando aus und gibt ein Funktionsergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll.&lt;br /&gt;
# optional: Name der Variable, die als Funktionsergebnis zurück gegeben werden soll; default ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=test   z=$EXEC(testkommando)&lt;br /&gt;
&lt;br /&gt;
==$GUID()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine GUID und gibt sie zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# optional: Name einer Variablen, in welcher die GUID zusätzlich gespeichert wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kid=$GUID()&lt;br /&gt;
&lt;br /&gt;
==$HASH()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt einen Hash-Wert vom String im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, von welchem der Hash gebildet werden soll.&lt;br /&gt;
# zu verwendender Hash-Algorithmus:&lt;br /&gt;
## sha512&lt;br /&gt;
## sha512_256&lt;br /&gt;
## sha512_224&lt;br /&gt;
## sha384&lt;br /&gt;
## sha256&lt;br /&gt;
## sha224&lt;br /&gt;
## sha1&lt;br /&gt;
## md5 (Hinweis: MD5 gilt seit Längerem als nicht mehr sicher. Verwenden Sie ihn nur, wenn dies aus Gründen der Abwärts-Kompatbilität zwingend ist.)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$HASH($PVAL(vl,1,2),sha512)&lt;br /&gt;
&lt;br /&gt;
==$INCLUDE()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass der als dritter Parameter übergebene Text am Anfang oder am Ende steht, gegebenenfalls wird er dort eingefügt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## lead(oder leading) - Text muss am Anfang stehen&lt;br /&gt;
## leadci(oder leadingci oder leadingcaseinsensitive) - Text muss am Anfang stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
## trail(oder trailing) - Text muss am Ende stehen&lt;br /&gt;
## trailci(oder trailci oder trailingcaseinsensitive) - Text muss am Ende stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
# Text, in den gegebenenfalls eingefügt wird&lt;br /&gt;
# Text, der gegebenenfalls eingefügt wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCLUDE(trailci,test.PDF,.pdf)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$INVLOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Key aus einer Nachschlageliste bei Übergabe des Values.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Value des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$INVLOOKUP(general_status,aktiv,Wert nicht vorhanden)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus einer Nachschlageliste.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Key des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$LOOKUP(general_status,1,Status nicht gesetzt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOW()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Kleinbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Kleinbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LOW($EDT(edt1)) = bus&lt;br /&gt;
&lt;br /&gt;
==$LOWNOSPACE()==&lt;br /&gt;
&lt;br /&gt;
Wandelt einen String in Kleinbuchstaben und ersetzt alle Leerzeichen durch Unterstriche.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der gewandelt werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$LOWNOSPACE($PVAL(vl,1,2))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$NOCRLF()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Zeilenumbrüche&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem die Zeilenumbrüche entfernt werden sollen&lt;br /&gt;
# optional: Zeichenfolge, die an Stelle der Zeilenumbrüche eingefügt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=2   z=$NOCRLF($VAL(1),;)&lt;br /&gt;
&lt;br /&gt;
==$NVL()==&lt;br /&gt;
&lt;br /&gt;
Liefert einen Ersatzwert, wenn der Wert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird, wenn der erste Parameter leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   where ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0)&lt;br /&gt;
&lt;br /&gt;
Liefert $PVAL einen leeren Wert zurück (z.B., weil die Gridzeile neu angelegt wurde und daher noch keine Nummer eingetragen ist), so wird statt dessen 0 verwendet, damit die WHERE-Klausel syntaktisch korrekt ist.&lt;br /&gt;
&lt;br /&gt;
==$ONLYCHAR()==&lt;br /&gt;
&lt;br /&gt;
Entfernt unerwünschte Zeichen aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# optional: Typ der Funktion&lt;br /&gt;
## (leer) - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z', 'ä', 'ö', 'ü', 'Ä','Ö', 'Ü', 'ß']) sind&lt;br /&gt;
## charnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind&lt;br /&gt;
## low - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## upp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## charnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## charnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## uml - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z') sind, Umlaute werden konvertiert (ä -&amp;gt; ae, ö -&amp;gt; oe, ü -&amp;gt; ue, Ä -&amp;gt; Ae, Ö -&amp;gt; Oe, Ü -&amp;gt; Ue, ß -&amp;gt; ss)&lt;br /&gt;
## umlcharnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Umlaute werden konvertiert&lt;br /&gt;
## umllow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## no191 / not191 - Es werden alle Zeichen mit der ANSI-Nummer 191 (¿) entfernt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg)&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg,umllow)&lt;br /&gt;
&lt;br /&gt;
==$PAD()==&lt;br /&gt;
&lt;br /&gt;
Füllt links oder rechts bis zur vorgegebenen Länge mit Zeichen auf.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# Soll-Länge. Ist der ursprüngliche String bereits länger, wird er nicht gekürzt, es werden aber auch keine weiteren Zeichen hinzugefügt&lt;br /&gt;
# Wenn L, werden die Zeichen vorne hinzugefügt, andernfalls hinten&lt;br /&gt;
# Zeichen, die soweit und so oft hinzugefügt werden, bis die Soll-Länge erreicht ist. Umfasst der Parameter mehrere Zeichen, werden diese ggf. nicht alle hinzugefügt.&lt;br /&gt;
# optional: Länge, auf die der ursprüngliche String vor der weiteren Verarbeitung gekürzt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   text1 = '$PAD($VAR(text1),70,R, )'&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ des Ergebnisses&lt;br /&gt;
## curr - Zahl mit zwei Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## curr4 - Zahl mit vier Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## date - Datum in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## int - ganze Zahl  in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## ld - Key einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ldv - Value einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ls - Key eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## lsv - Value eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## text, text2, text3... - Zeile eines Textes&lt;br /&gt;
# untere Grenze bzw. Name der Nachschlageliste oder des Specials&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $RANDOM(date,01.01.2022,31.12.2022)&lt;br /&gt;
 #coutl $RANDOM(text2)&lt;br /&gt;
&lt;br /&gt;
==$SUBSTR()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Selbe Funktionalität wie $COPY())&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$SUBSTR($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$STREP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string replace&amp;quot;) Ersetzt Zeichen im String durch andere Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, in welchen Zeichen ersetzt werden sollen.&lt;br /&gt;
# Zeichen, die ersetzt werden sollen&lt;br /&gt;
# Zeichen, die an deren Stelle treten sollen&lt;br /&gt;
# optional: Optionen (kombinierbar)&lt;br /&gt;
## i - Groß- und Kleinschreibung ignorieren &lt;br /&gt;
## a - Alle Vorkommen ersetzen (andernfalls wird nur das erste Vorkommen ersetzt)&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=&amp;quot;$STREP($PVAL(vl,1,2), ,_,a)&amp;quot;&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$STREP($PVAL(vl,1,2),$CHR(space),_,a)&lt;br /&gt;
&lt;br /&gt;
Hinweis: Beide Beispiele haben exakt dieselbe Funktion. Im oberen Beispiel steht das Leerzeichen direkt im Text, dafür muss der komplette Parameter in doppelte Anführungszeichen, im unteren Beispiel wird das Leerzeichen durch $CHR(space) eingefügt, dafür können die Leerzeichen unterbleiben.&lt;br /&gt;
&lt;br /&gt;
==$STROP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string operation&amp;quot;) Sammelsurium von String-Operationen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## trim - entfernt führende und folgende Leerzeichen&lt;br /&gt;
## trimleft - entfernt führende Leerzeichen&lt;br /&gt;
## trimright - entferne folgende Leerzeichen&lt;br /&gt;
## quote - setzt den String in einfache Anführungszeichen&lt;br /&gt;
## unquote - entfernt einschließende einfache Anführungszeichen&lt;br /&gt;
## dquote - setzt den String in doppelte Anführungszeichen&lt;br /&gt;
## unqduote - entfernt einschließende doppelte Anführungszeichen&lt;br /&gt;
## ex_filepath - entspricht der Delphi-Funktion ExtractFilePath&lt;br /&gt;
## ex_filedir - entspricht der Delphi-Funktion ExtractFileDir&lt;br /&gt;
## ex_filedrive - entspricht der Delphi-Funktion ExtractFileDrive&lt;br /&gt;
## ex_filename - entspricht der Delphi-Funktion ExtractFileName&lt;br /&gt;
## ex_fileext - entspricht der Delphi-Funktion ExtractFileExt&lt;br /&gt;
# String, der bearbeitet werden soll&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$STROP(quote,Test)&lt;br /&gt;
&lt;br /&gt;
==$STREXTR()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string extract&amp;quot;) Extrahiert einen Teil aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem extrahiert werden soll&lt;br /&gt;
# Extraktionstyp&lt;br /&gt;
## ffe (&amp;quot;from first exclude&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## ffi (&amp;quot;from first include&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tfe (&amp;quot;to first exclude&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tfi (&amp;quot;to first include&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## fle (&amp;quot;from last exclude&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## fli (&amp;quot;from last include&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tle (&amp;quot;to last  exclude&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tli (&amp;quot;to last include&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Trennzeichen&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffe,;)&amp;quot;    -- Ergebnis: test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffi,;)&amp;quot;    -- Ergebnis: ;test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfe,;)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfi,;)&amp;quot;    -- Ergebnis: test;&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;!§§test2,tfe,;!§§)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
&lt;br /&gt;
==$TRIM()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Leerzeichen und Zeilenumbrüche am Rand des Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der getrimmt werden soll&lt;br /&gt;
# optional&lt;br /&gt;
## L - trimmt nur auf der linken Seite&lt;br /&gt;
## R - trimmt nur auf der rechten Seite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$TRIM($VAL(1),R)&lt;br /&gt;
&lt;br /&gt;
==$UPP()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Großbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Großbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $UPP($EDT(edt1)) = BUS&lt;br /&gt;
&lt;br /&gt;
==$VT()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VT (&amp;quot;Value Translate&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Vergleichswert 1&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 1 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 2&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 2 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 3&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 3 dem ersten Parameter entspricht &lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VT(Frau,1,Herr,2,Frau,3)&lt;br /&gt;
 -- Frau -&amp;gt; 3&lt;br /&gt;
 -- Herr -&amp;gt; 2&lt;br /&gt;
 -- Test -&amp;gt; 1&lt;br /&gt;
 -- Firma -&amp;gt; 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$VTRDB()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VTRDB (&amp;quot;Value Translate Root Database&amp;quot;) gibt eine String zurück, der von einem Wert im Datenbank-Segment der Root-Ini abhängt. Diese Ini-Datei (BafClientFM.ini im selben Verzeichnis wie die BafClientFM.exe) enthält die Datenbank-Zugangsdaten. Diese könnte den folgenden Block (Auszug) enthalten:&lt;br /&gt;
&lt;br /&gt;
 [DB_PGPROD]&lt;br /&gt;
 prefix=prod&lt;br /&gt;
 Name=Postgres PROD&lt;br /&gt;
 DriverName=Postgres&lt;br /&gt;
 Database=postgres&lt;br /&gt;
 User=ttbaf3prodadmin&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Der Wert in ''prefix'' spezifiziert, ob es sich um das Produktiv- oder das Test-System handelt. In Abhängigkeit davon gibt diese Funktion dann unterschiedliche Werte zurück. Es wird immer die Sektion der gerade ausgewählten Datenbank verwendet. &lt;br /&gt;
&lt;br /&gt;
Der Hauptanwendungsfall dieser Funktion, die Notwendigkeit einer Änderung des Codes bei der Migration vom Test- in das Produktiv-System oder umgekehrt zu vermeiden. Statt dessen ermittelt die Funktion, ob sie gerade im Test- oder Produktiv-System ausgeführt wird und gibt den passenden Wert (Verzeichnis-Name, URL, ...) zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Item (Ident) in der Root-Ini (die Sektion ist immer die der aktuell ausgewählten Datenbank)&lt;br /&gt;
# Vergleichswert 1&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 1 dem Wert in der Ini-Datei entspricht&lt;br /&gt;
# Vergleichswert 2&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 2 dem Wert in der Ini-Datei entspricht&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$VTRDB(prefix,test,Test-System,prod,Produktiv-System)&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$VTRDB(prefix,test,C:\temp\export\busdaten,prod,T:\files\export\busdaten)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$VTVL()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VTVL (&amp;quot;Value Translate ValueList&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu $VT werden die zu prüfenden Werte und deren Entsprechungen nicht über Parameter übergeben, sondern aus einer Werte-Liste geholt, die in einem Text gespeichert sein muss.&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich wie folgt aufbauen&lt;br /&gt;
&lt;br /&gt;
 key1=value1&lt;br /&gt;
 key2=value2&lt;br /&gt;
 key3=value3&lt;br /&gt;
 key4=value4&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich auch mit #sql_opentvl erzeugen, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Nummer des Textes, in dem sich die Werteliste befindet.&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select userid as ckey, shortname as cvalue from user_user&lt;br /&gt;
 #sql_opentvl n=1&lt;br /&gt;
 #coutl $VTVL(591,(nicht gefunden),1)&lt;br /&gt;
&lt;br /&gt;
==$XR()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $XR (&amp;quot;XmlReplace&amp;quot;) ersetzt in XML nicht zulässige Zeichen:&lt;br /&gt;
* aus &amp;amp; wird $amp ;&lt;br /&gt;
* aus &amp;lt; wird &amp;amp;lt ;&lt;br /&gt;
* aus &amp;gt; wird &amp;amp;gt ;&lt;br /&gt;
* aus &amp;quot; wird &amp;amp;quot ;&lt;br /&gt;
* aus ' wird &amp;amp;apos ;&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Das Leerzeichen vor dem Semikolon soll verhindern, dass die Zeichen hier in der Darstellung ersetzt werden und wird nicht eingefügt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text &amp;lt;firmenname&amp;gt;$XR($DATA(dat,firmenname))&amp;lt;/firmenname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==$XRR()==&lt;br /&gt;
&lt;br /&gt;
Umkehrfunktion von $XR()&lt;br /&gt;
* aus $amp ; wird &amp;amp;&lt;br /&gt;
* aus &amp;amp;lt ; wird &amp;lt;&lt;br /&gt;
* aus &amp;amp;gt ; wird &amp;gt;&lt;br /&gt;
* aus &amp;amp;quot ; wird &amp;quot;&lt;br /&gt;
* aus &amp;amp;apos ; wird '&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
=Integer-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben eine ganze Zahl zurück&lt;br /&gt;
&lt;br /&gt;
==$DEC()==&lt;br /&gt;
&lt;br /&gt;
Verringert die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die verringert werden soll.&lt;br /&gt;
# optional: Zahl, um die verringert werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$DEC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ICALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit ganzzahligen Werten durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator, es stehen zur Verfügung&lt;br /&gt;
## +&lt;br /&gt;
## -&lt;br /&gt;
## *&lt;br /&gt;
## div&lt;br /&gt;
## mod&lt;br /&gt;
# Erste Zahl&lt;br /&gt;
# Zweite Zahl&lt;br /&gt;
# optional beim Operator +: weitere Summanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$ICALC(mod,17,5)&lt;br /&gt;
&lt;br /&gt;
==$INC()==&lt;br /&gt;
&lt;br /&gt;
Erhöht die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die erhöht werden soll.&lt;br /&gt;
# optional: Zahl, um die erhöht werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$INC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$INTLEN()==&lt;br /&gt;
&lt;br /&gt;
Ist der String im Parameter eine ganz Zahl, dann wird deren Länge in Zeichen zurückgegeben, andernfalls -1; ein leerer String im ersten Parameter ergibt 0.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, deren Länge ermittelt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTLEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Länge eines Strings in Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Länge ermittelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEVENSHTEIN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Levenshtein-Distanz (https://de.wikipedia.org/wiki/Levenshtein-Distanz) der beiden übergebenen Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# erster String&lt;br /&gt;
# zweiter String&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $LEVENSHTEIN(alpha,beta)&lt;br /&gt;
&lt;br /&gt;
==$POS()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Position des Substrings in einem String. Das Funktionsergebnis ist die Position, das erste Zeichen ist 1. 0 wird zurück gegeben, wenn der Substring im String nicht vorkommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Substring (nach dem gesucht wird)&lt;br /&gt;
# String (in dem gesucht wird)&lt;br /&gt;
# optional: Wenn ic (ignore case), dann wird bei der Suche die Groß- und Kleinschreibung nicht beachtet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $POS($EDT(edt1),$VAR(1),ic) &amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert zwischen der oberen und unteren Grenze&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ&lt;br /&gt;
## int - zufällige Ganzzahl &lt;br /&gt;
## date - zufälliges Datum &lt;br /&gt;
## curr - zufällige Zahl mit zwei Nachkommastellen&lt;br /&gt;
## curr4 - zufällige Zahl mit vier Nachkommastellen&lt;br /&gt;
## text1, text2, text3... - zufällige Zeile aus dem jeweiligen Text; text ist text1; untere und obere Grenze bleiben unberücksichtigt&lt;br /&gt;
## ld - zufälliger Schlüssel-Wert aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ldv - zufälliger Text aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ls - zufälliger Schlüssel-Wert aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## lsv - zufälliger Text aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
# untere Grenze&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $RANDOM(int,1,6)&lt;br /&gt;
&lt;br /&gt;
=Datumsfunktionen=&lt;br /&gt;
&lt;br /&gt;
==$INCDATE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktione  $INCDATE() verändert das Datum im ersten Parameter um die Anzahl Tage im zweiten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das verändert werden soll&lt;br /&gt;
# optional: Die Tage, um die verändert werden soll; wenn leer, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCDATE($NOW(),-3)   clr=Y&lt;br /&gt;
&lt;br /&gt;
==$INT2TIME()==&lt;br /&gt;
&lt;br /&gt;
Macht aus z.B. 1130 die Zeit 11:30&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zeit im Integer-Format&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_time=$INT2TIME($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$NOW()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit im Format dd.mm.yyyy hh:mm:ss zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #execsql   k_datechg=$NOW()&lt;br /&gt;
&lt;br /&gt;
==$NOWFMT()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und/oder die aktuelle Uhrzeit im angegebenen Format zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Formatierungsstring (Syntax wie FormatDateTime in Delphi)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$NOWFMT(yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$NOWMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit ohne Sekunden (also dd.mm.yyyy hh:mm) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$NOWMIN()&lt;br /&gt;
&lt;br /&gt;
==$TODAY()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum im Format dd.mm.yyyy zurück.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Wenn das Datum in einem anderen Format benötigt wird, ist $NOWFMT() das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$TODAY()&lt;br /&gt;
&lt;br /&gt;
==$DFMT()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;date formated&amp;quot;) Formatiert das übergebene Datum. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, ggf. mit Uhrzeit, das formatiert werden soll.&lt;br /&gt;
# Formatierungsstring wie in Delphi&lt;br /&gt;
# optional: Wenn hn (&amp;quot;hide null&amp;quot;), dann wird ein leerer String zurück gegeben, wenn das Datum kleiner/gleich 1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$DFMT($NOW(),yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Bool'sche Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
==$BFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert einen bool'schen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'scher Wert&lt;br /&gt;
# optional: Ergebnis, wenn Wert Y ('y', 'J', 'j', '1') ist, default Y&lt;br /&gt;
# optional: Ergebnis, wenn Wert N (also nicht 'Y', 'y', 'J', 'j', '1') ist, default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cout   c=$BFMT($VAR(test),x,)&lt;br /&gt;
&lt;br /&gt;
==$BOOL()==&lt;br /&gt;
&lt;br /&gt;
Wertet das bool'sche Statement im Parameter aus.&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
* = gleich&lt;br /&gt;
* == gleich ohne Berücksichtigung der Groß- und Kleinschreibung&lt;br /&gt;
* &amp;lt;&amp;gt; ungleich&lt;br /&gt;
* != ungleich&lt;br /&gt;
* &amp;gt; größer&lt;br /&gt;
* &amp;gt;= größer gleich&lt;br /&gt;
* &amp;lt; kleiner&lt;br /&gt;
* &amp;lt;= kleiner gleich &lt;br /&gt;
* and Und-Verknüpfung&lt;br /&gt;
* or ODER-Verknüpfung&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Statements werden von links nach rechts ausgewertet, and und or sind gleichwetig, gegebenenfalls müssen Klammern eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'sches Statement, das ausgewertet wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL((17 &amp;gt; 22) or (5 &amp;gt; 3))&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL(17 &amp;gt; 22 or 5 &amp;gt; 3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATECOMP()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn Datum 2 Operator Datum 1 zutreffend ist. Ansonsten wird N zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Wird kein Operator angegeben, dann wird die Anzahl der Tage Datum 2 - Datum 1 als Zahl zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum 1&lt;br /&gt;
# Datum 2&lt;br /&gt;
# Operator&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024,&amp;lt;)&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATEMINREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMINREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEMAXREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMAXREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in ein Datum wandeln lassen, werden zu 0 (30.12.1899) konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter diesem Datum entspricht. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;Test $DATEBETWEEN($TODAY(),1.1.2020,2.2.2022)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$EMPTY()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Parameter ein leerer String ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTY($DATE(n,grpname))&lt;br /&gt;
&lt;br /&gt;
==$EMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable ein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTYVAR(buchungsnr)&lt;br /&gt;
&lt;br /&gt;
==$IN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INIC() beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die erste Anweisung gibt Y und die zweite N zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INIC()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $IN() nicht beachtet beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen geben Y zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich die Variable, deren Namen im ersten Parameter steht, in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INICVAR() beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable, die geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die erste Anweisung gibt Y und die zweite N zurück&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=beta&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INICVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich die Variable, deren Namen im ersten Parameter steht, in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INVAR() nicht beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable, die geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen geben Y zurück&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=beta&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$ISCURR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen Currency-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISCURR($DATA(n,rechnungssumme))&lt;br /&gt;
&lt;br /&gt;
==$ISDATE()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in ein Datums- oder DatumsZeit-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Prüfoperation, default ist date&lt;br /&gt;
## date - prüft, ob in ein Datum gewandelt werden kann&lt;br /&gt;
## datetime - prüft, ob in ein Datums-Zeit-Wert gewandelt werden kann&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISDATE($DATA(n,beginn))&lt;br /&gt;
&lt;br /&gt;
==$ISINT()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen ganzzahligen Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISINT($DATA(n,tage))&lt;br /&gt;
&lt;br /&gt;
==$INTMAX()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMAX($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$INTMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMIN($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$NEMPTY()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;not empty&amp;quot;) Gibt Y zurück, wenn der Parameter nicht leer ist. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalt geprüft wird. Leerzeichen gelten als leerer String.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 &lt;br /&gt;
 ~ $NEMPTY($EDT(edt1))&lt;br /&gt;
&lt;br /&gt;
==$NEMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable kein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $NEMPTYVAR(kundennr)&lt;br /&gt;
&lt;br /&gt;
==$NOT==&lt;br /&gt;
&lt;br /&gt;
Invertiert einen bool'schen Wert. Aus Y (y, J, j, 1) wird N und aus N wird Y.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der invertiert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $NOT(2)&lt;br /&gt;
&lt;br /&gt;
==$NUMBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in eine Zahl wandeln lassen, werden zu 0 konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter dieser Zahl entspricht. Siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56,)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die beiden Beispiele unterscheiden sich auf den ersten Blick kaum. Bei der ersten Zeile muss jedoch eine Schuhgröße eingegeben werden. Bleibt das Feld im VL-Segment leer, so wird dieser fehlende Wert nach 0 konvertiert und liegt nicht zwischen 28 und 56.&lt;br /&gt;
&lt;br /&gt;
Anders bei der zweiten Zeile: Das Komma vor der schließenden Klammer sorgt für einen vierten Parameter, der ebenfalls leer ist und damit nach 0 gewandelt wird. Auf diese Weise werden die leere Eingaben (und die Eingabe von 0) gültig.&lt;br /&gt;
&lt;br /&gt;
==$REGEX()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $REGEX() (&amp;quot;regular expressions&amp;quot;) prüft, ob der String in Parameter 1 den Anforderungen von Parameter 2 entspricht (Ergebnis Y) oder nicht (Ergebnis N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft werden soll&lt;br /&gt;
# Regulärer Ausdruck, mit dem der String in Parameter 2 geprüft wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $REGEX($VAR(med),^[A-Z]{3}$)&lt;br /&gt;
&lt;br /&gt;
==$TEXT_HASLINE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $TEXT_HASLINE() prüft, ob die als Parameter 2 übergebene Textzeile in einem Text vorkommt. Es wird nur auf komplette Textzeilen geprüft. Wird zum Beispiel verwendet, um eine Liste von Kundennummern zu erstellen, und dann auf einzelne Nummern zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# Textzeile, deren Vorkommen geprüft wird&lt;br /&gt;
# Ergebnis, wenn die Textzeile vorkommt; default Y&lt;br /&gt;
# Ergebnis, wenn die Textzeile nicht vorkommt; default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $TEXT_HASLINE(1,990000018,1,0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$VIBAN()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VIBAN() (&amp;quot;validate IBAN&amp;quot;) prüft eine IBAN anhand der Prüfziffern (3. und 4. Stelle).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# IBAN, die geprüft werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VIBAN(DE12345)&lt;br /&gt;
&lt;br /&gt;
=Currency-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==$CCALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit Festkommawerten durch&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
** + - Addition&lt;br /&gt;
** - - Subtraktion&lt;br /&gt;
** * - Multiplikation&lt;br /&gt;
** / - Division&lt;br /&gt;
** % - Division und Multiplikation des Ergebnisses mit 100&lt;br /&gt;
** +4 - Addition und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** -4 - Subtraktion und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** *4 - Multiplikation und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** /4 - Division und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** %4 - Division, Multiplikation des Ergebnisses mit 100 und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
** B, b, B4, b4 - Bruttobetrag, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** E, e, E4, e4 - Enthaltene MWSt, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** M, m, M4, m4 - MWSt, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** N, n, N4, n4 - Nettobetrag, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator&lt;br /&gt;
# und weitere: Operanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 10&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(+,1,2,3,4)&amp;quot;&lt;br /&gt;
 -- Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #val_set   n=1   z=1038,87&lt;br /&gt;
 #coutl $CCALC(N,$VAL(1),19)  -  $CCALC(E,$VAL(1),19)  -&lt;br /&gt;
&lt;br /&gt;
==$CURR()==&lt;br /&gt;
&lt;br /&gt;
Currency-Werte müssen in Funktionen mit einem Punkt als Dezimaltrennzeichen eingegeben werden, da das Komma die Parameter trennt. Sofern Konstanten verwendet werden, lässt sich das einfach so eingeben, sobald aber die Werte aus anderen Funktionen kommen (zum Beispiel $DATA()), müssen sie dann mit $CURR() in dieses Format umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Vorkommastellen&lt;br /&gt;
# Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 43,48&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,$CURR(2,3))&amp;quot;&lt;br /&gt;
 -- zum Vergleich; Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert Curreny-Werte&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert&lt;br /&gt;
# optional: Formatierungsstring, default 0.00&lt;br /&gt;
# optional: wenn hn (&amp;quot;hide null&amp;quot;), dann werden leere Strings als Wert auch als leerer String ausgegeben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=###,###,###,##0.00&lt;br /&gt;
 #val_set   n=2   z=1337,42&lt;br /&gt;
 #cout   c=$CFMT($VAL(2),$VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ONLYNUM()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass in einem String nur Zahlen (ggf. auch Kommas oder Punkte) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl&lt;br /&gt;
# Art der Operation; default numkomma&lt;br /&gt;
## flnnc (&amp;quot;from last not numeric character&amp;quot;) - Ab dem letzten Zeichen, das keine Ziffer ist&lt;br /&gt;
## num - Nur Ziffern, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numkomma - Nur Ziffern und Kommata, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numpoint - Nur Ziffern und Punkte, alle anderen Zeichen werden entfernt&lt;br /&gt;
## ufnnc (&amp;quot;until first not numeric character&amp;quot;) - vom Anfang bis zum ersten Zeichen, das keine Ziffer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 -- Ergebnis 123456&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,num)&lt;br /&gt;
 -- Ergebnis 123&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,ufnnc)&lt;br /&gt;
 -- Ergebnis 456 &lt;br /&gt;
 #coutl   $ONLYNUM(123-456,flnnc)&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22536</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22536"/>
		<updated>2025-07-17T12:26:42Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #vl_line */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* rof1, rof2... (&amp;quot;read only field&amp;quot;) - Feldname der Spalte, aus dem die Read-Only-Funktion bezogen wird; Funktionen werden ersetzt&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, aus dem die Daten bei q=text bezogen werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** text - die Daten werden aus dem mit dem Parameter n spezifizierten Text bezogen. Mögliche Werte für den Parameter f sind ''text'' (ganze Zeile), ''key'' (vor dem Gleichheitszeichen) und ''value'' (nach dem Gleichheitszeichen)&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Kategorie, Funktionen werden ersetzt. Nur bei y=kat&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer der Kategorie-Valueliste; default 1, Funktionen werden ersetzt&lt;br /&gt;
* y - Type. Default sql, Funktionen werden ersetzt&lt;br /&gt;
** kat - die Werte kommen aus einer Kategorie-Valueliste.&lt;br /&gt;
** sql - die Werte kommen aus einem SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Kategorie-Valueliste'''&lt;br /&gt;
&lt;br /&gt;
 #sql select t.tournr as ckat, s.bus_haltestelle_id as ckey, s.land || ' ' || s.plz || ' ' || s.ort || ' - ' || s.beschreibung as cvalue, h.position&lt;br /&gt;
 #sql   from bus_touren t&lt;br /&gt;
 #sql     inner join bus_tour_hs h   on h.bus_touren_id = t.bus_touren_id   and h.status &amp;lt; 7   and (h.position &amp;lt; 99   or t.tournr between 30000 and 40000)&lt;br /&gt;
 #sql     inner join bus_haltestelle s   on s.bus_haltestelle_id = h.haltestelle   and s.status = 1   and s.land &amp;lt;&amp;gt; &lt;br /&gt;
 #sql   where t.kuerzel = '$FND(s,kuerzel)'   and t.datum = to_date('$FND(s,datum)', 'dd.mm.yyyy') &lt;br /&gt;
 #sql   order by 1, 4&lt;br /&gt;
 #sql_openkvl   n=1&lt;br /&gt;
&lt;br /&gt;
Für die Nachschlageliste wird dann wie folgt formuliert:&lt;br /&gt;
&lt;br /&gt;
 #grd_lookuplivefill   y=kat   n=1   k=$PVAL(pl,tournr,lookuplive)&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$GRD_REGEX==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_REGEX prüft ein Grid-Segment die die Einhaltung eines Regex-Staements in einer bestimmten Spalte. Eignet sich insbesondere für #page_check, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Regex-Statement&lt;br /&gt;
# Optionen&lt;br /&gt;
## e (&amp;quot;allow empty&amp;quot;) - $GRD_REGEX gibt auch Y zurück, wenn der Zellenwert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Aktionscode entspricht nicht den Formatvorgaben&amp;quot;   chk=$GRD_REGEX(reisen,aktionscode,all,[A-Z]{3}\d{4},e)&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22535</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22535"/>
		<updated>2025-07-16T09:46:58Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #grd_lookuplivefill */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, aus dem die Daten bei q=text bezogen werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** text - die Daten werden aus dem mit dem Parameter n spezifizierten Text bezogen. Mögliche Werte für den Parameter f sind ''text'' (ganze Zeile), ''key'' (vor dem Gleichheitszeichen) und ''value'' (nach dem Gleichheitszeichen)&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Kategorie, Funktionen werden ersetzt. Nur bei y=kat&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer der Kategorie-Valueliste; default 1, Funktionen werden ersetzt&lt;br /&gt;
* y - Type. Default sql, Funktionen werden ersetzt&lt;br /&gt;
** kat - die Werte kommen aus einer Kategorie-Valueliste.&lt;br /&gt;
** sql - die Werte kommen aus einem SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Kategorie-Valueliste'''&lt;br /&gt;
&lt;br /&gt;
 #sql select t.tournr as ckat, s.bus_haltestelle_id as ckey, s.land || ' ' || s.plz || ' ' || s.ort || ' - ' || s.beschreibung as cvalue, h.position&lt;br /&gt;
 #sql   from bus_touren t&lt;br /&gt;
 #sql     inner join bus_tour_hs h   on h.bus_touren_id = t.bus_touren_id   and h.status &amp;lt; 7   and (h.position &amp;lt; 99   or t.tournr between 30000 and 40000)&lt;br /&gt;
 #sql     inner join bus_haltestelle s   on s.bus_haltestelle_id = h.haltestelle   and s.status = 1   and s.land &amp;lt;&amp;gt; &lt;br /&gt;
 #sql   where t.kuerzel = '$FND(s,kuerzel)'   and t.datum = to_date('$FND(s,datum)', 'dd.mm.yyyy') &lt;br /&gt;
 #sql   order by 1, 4&lt;br /&gt;
 #sql_openkvl   n=1&lt;br /&gt;
&lt;br /&gt;
Für die Nachschlageliste wird dann wie folgt formuliert:&lt;br /&gt;
&lt;br /&gt;
 #grd_lookuplivefill   y=kat   n=1   k=$PVAL(pl,tournr,lookuplive)&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$GRD_REGEX==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_REGEX prüft ein Grid-Segment die die Einhaltung eines Regex-Staements in einer bestimmten Spalte. Eignet sich insbesondere für #page_check, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Regex-Statement&lt;br /&gt;
# Optionen&lt;br /&gt;
## e (&amp;quot;allow empty&amp;quot;) - $GRD_REGEX gibt auch Y zurück, wenn der Zellenwert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Aktionscode entspricht nicht den Formatvorgaben&amp;quot;   chk=$GRD_REGEX(reisen,aktionscode,all,[A-Z]{3}\d{4},e)&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22534</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22534"/>
		<updated>2025-07-16T09:46:05Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #grd_lookuplivefill */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, aus dem die Daten bei q=text bezogen werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** text - die Daten werden aus dem mit dem Parameter n spezifizierten Text bezogen. Mögliche Werte für den Parameter f sind ''text'' (ganze Zeile), ''key'' (vor dem Gleichheitszeichen) und ''value'' (nach dem Gleichheitszeichen)&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Kategorie, Funktionen werden ersetzt. Nur bei y=kat&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer der Kategorie-Valueliste; default 1, Funktionen werden ersetzt&lt;br /&gt;
* y - Type. Default sql, Funktionen werden ersetzt&lt;br /&gt;
** kat - die Werte kommen aus einer Kategorie-Valueliste.&lt;br /&gt;
** sql - die Werte kommen aus einem SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$GRD_REGEX==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_REGEX prüft ein Grid-Segment die die Einhaltung eines Regex-Staements in einer bestimmten Spalte. Eignet sich insbesondere für #page_check, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Regex-Statement&lt;br /&gt;
# Optionen&lt;br /&gt;
## e (&amp;quot;allow empty&amp;quot;) - $GRD_REGEX gibt auch Y zurück, wenn der Zellenwert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Aktionscode entspricht nicht den Formatvorgaben&amp;quot;   chk=$GRD_REGEX(reisen,aktionscode,all,[A-Z]{3}\d{4},e)&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_DB&amp;diff=22533</id>
		<title>Modul DB</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_DB&amp;diff=22533"/>
		<updated>2025-07-16T09:42:36Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #sql_opentvl */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=DB=&lt;br /&gt;
&lt;br /&gt;
Im Modul DB werden die Datenbank-Routinen zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
* '''#sql''' fügt dem SQL-Statement eine Zeile hinzu&lt;br /&gt;
* '''#sql_clear''' löscht das SQL-Statement&lt;br /&gt;
* '''#sql_exec''' führt SQL-Statement aus&lt;br /&gt;
* '''#sql_open''' führt ein select-Statement aus und ruft für jede Zeile der Datenmenge das angegebene Kommando aus.&lt;br /&gt;
* '''#sql_openval''' führt eine select-Statement aus und schreibt das Ergebnis der ersten (ind er Regel der einzigen) Datenzeile in lokale oder globale Variable&lt;br /&gt;
* '''#sql_openvalrows''' führt eine select-Statement aus und schreibt das Ergebnis in lokale oder globale Variablen. Die Werte der verschiedenen Datenzeilen werden durch ein Trennzeichen getrennt.&lt;br /&gt;
* '''#sql_intransaction''' führt ein Kommando in einer eigens gestarteten Transaktion aus.&lt;br /&gt;
* '''#sql_upsert''' schreibt eine Zeile in eine Datenbanktabelle.&lt;br /&gt;
&lt;br /&gt;
* '''$SQL()''' führt eine SQL-Anweisung aus und gibt die erste Spalte der ersten Datenreihe als Ergebnis zurück.&lt;br /&gt;
* '''$SQLTEXT()''' gibt den Inhalt eines SQL-Statements zurück.&lt;br /&gt;
* '''$DATA()''' gibt den Inhalt eines Felder der aktuellen Datenzeile einer mit #sql_open geöffneten Datenmenge zurück.&lt;br /&gt;
* '''$ISNULL()''' gibt Y zurück, wenn der Inhalt des Feldes NULL ist oder das Feld nicht existiert.&lt;br /&gt;
&lt;br /&gt;
==#sql==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql fügt dem SQL-Statement eine Zeile hinzu.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #sql fügt dem ersten SQL-Statement eine Zeile hinzu, #sql2 fügt dem zweiten SQL-Statement eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#sql hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Hinweis'''&lt;br /&gt;
&lt;br /&gt;
Durch den Aufruf einer der folgenden Prozeduren wird das SQL-Statement (nach der Ausführung) wieder geleert:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #sql_openval&lt;br /&gt;
* #sql_openvalrows&lt;br /&gt;
* #sql_exec&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select count(*) as cnt&lt;br /&gt;
 #sql    from user_user&lt;br /&gt;
 #opensqlval   f_cnt=1&lt;br /&gt;
&lt;br /&gt;
==#sql_line==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql fügt dem SQL-Statement den Text im Parameter z als Zeile hinzu.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #sql_line fügt dem ersten SQL-Statement eine Zeile hinzu, #sql_line2 fügt dem zweiten SQL-Statement eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Name des Eintrags in den Entwicklertexten, üblicherweise unterhalb von SQL; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_line z=&amp;quot;    and status = 51&amp;quot; cnd=$ICP(0,rü)&lt;br /&gt;
&lt;br /&gt;
==#sql_text==&lt;br /&gt;
&lt;br /&gt;
Holt ein SQL-Statement aus den Entwicklertexten (xdevtext). Diese Möglichkeit wird gerne für SQL-Statements verwendet, die auf verschiedene Datenbanksysteme angepasst werden müssen (zum Beispiel wegen des Einsatzes von NVL/ifnull/coalesce).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Eintrags in den Entwicklertexten, üblicherweise unterhalb von SQL; Funktionen werden ersetzt.&lt;br /&gt;
* d (&amp;quot;driver&amp;quot;) - Name des Datenbanktreibers. Wird in der Baumhierarchie direkt unter dem mit n bezeichneten Statement ein Eintrag mit dem Name des Datenbanktreibers gefunden, so wird dieses SQL-Statement statt dem mit n bezeichneten Statements verwendet. Auf diese Weise lassen sich übersichtlich Statements für alle eingesetzten Datenbanktreiber in der Datenbank speichern. Bleibt d leer (was üblicherweise der Fall ist), so wird der Treibername der aktuellen Primärdatenbank verwendet. Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sqltext   n=_system_lookup_202  &lt;br /&gt;
 #cout   c=$SQLTEXT(1)&lt;br /&gt;
&lt;br /&gt;
 #sqltext   n=_system_lookup_202   d=firebird&lt;br /&gt;
 #cout   c=$SQLTEXT(1)&lt;br /&gt;
&lt;br /&gt;
==#sql_clear==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_clear löscht das SQL-Statement.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #sql_clear löscht das erste SQL-Statement, #sql_clear2 löscht das zweite SQL-Statement, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Hinweis'''&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von #sql_clear ist im Regelfall nicht erforderlich, da durch den Aufruf einer der folgenden Prozeduren das SQL-Statement (nach der Ausführung) wieder geleert wird:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #sql_openval&lt;br /&gt;
* #sql_openvalrows&lt;br /&gt;
* #sql_exec&lt;br /&gt;
&lt;br /&gt;
Allerdings kann es bei einem Fehler vorkommen, dass das SQL-Statement nicht geleert wird und beim Aufbau eines neuen Statements Zeilen der vorherigen Statements zurückgeblieben sind. Das kann mit #sql_clear verhindert werden. Die Prozedur wird üblicherweise vor den Beginn eines neuen Statements gesetzt, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_clear&lt;br /&gt;
 #sql  select count(*) as cnt&lt;br /&gt;
 #sql    from user_user&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
&lt;br /&gt;
==#sql_exec==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_exec führt ein SQL-Statement.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #sql_exec führt das erste SQL-Statement aus, #sql_exec2 führt das zweite SQL-Statement aus, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y.&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Abfrage bezieht&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Um Namenskonflikte zu vermeiden, beginnen Parameter im SQL-Statement entsprechend den Konventionen mit einem k. Bei allen Parametern werden Funktionen ersetzt. Siehe auch das Beispiel.&lt;br /&gt;
* srv_ops (&amp;quot;Server Operations&amp;quot;) - Wenn Y, wird die Zahl der betroffenen Datensätze den Server Operations hinzugefügt. Wird im Server-Betrieb verwendet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* z - Nummer des Values, in das die Zahl der betroffenen Datensätze gespeichert werden kann&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql update tbl_test set status = 7 where tbl_test_id = :kid&lt;br /&gt;
 #sql_exec  :kid=$FND(s,tbl_test_id)   z=1&lt;br /&gt;
 #message   c=&amp;quot;Es wurden $VAR(1) Datensätze deaktiviert.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#sql_open==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_open führt ein select-Statement aus und ruft für jede Zeile der Datenmenge das angegebene Kommando aus.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #sql_open ruft das erste SQL-Statement auf, #sql_open2 ruft das zweite SQL-Statement auf, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acnd - (&amp;quot;abort condition&amp;quot;) wenn Y, wird die Verarbeitung abgebrochen; wird nach jedem Aufruf von er geprüft; Default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y; Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Abfrage bezieht; Funktionen werden ersetzt&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen; Funktionen werden ersetzt&lt;br /&gt;
* k - (&amp;quot;key&amp;quot;) Um Namenskonflikte zu vermeiden, beginnen Parameter im SQL-Statement entsprechend den Konventionen mit einem k. Bei allen Parametern werden Funktionen ersetzt. Siehe auch das Beispiel.&lt;br /&gt;
* m - (&amp;quot;maximum&amp;quot;) Es wird maximal für die Anzahl der angegebenen Zeilen das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten; Funktionen werden ersetzt&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N; Funktionen werden ersetzt.&lt;br /&gt;
* n - Name der Datenmenge, wird benötigt, um mit $DATA() auf die einzelnen Felder zugreifen zu können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select * &lt;br /&gt;
 #sql    from user_user&lt;br /&gt;
 #sql    where upper(lastname) like upper(:kname)&lt;br /&gt;
 #sql_open  n=test  er=test_line  kname=$EDT(edt1)%&lt;br /&gt;
&lt;br /&gt;
==#sql_openval==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_openval führt eine select-Statement aus und schreibt das Ergebnis der ersten (ind er Regel der einzigen) Datenzeile in lokale oder globale Variable.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #sql_openval ruft das erste SQL-Statement auf, #sql_openval2 ruft das zweite SQL-Statement auf, und so weiter.&lt;br /&gt;
 &lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* af (&amp;quot;all fields&amp;quot;) - Legt alle Felder der Abfrage in einer gleichnamigen Variablen ab, die f_-Definitionen können dann entfallen; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt - (&amp;quot;count&amp;quot;) Ermittelt die Anzahl der Datensätze, die das SQL-Statement zurück gibt, und schreibt diese in die mit diesem Parameter bezeichneten Variablen oder Value&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Abfrage bezieht&lt;br /&gt;
* de - (&amp;quot;do empty&amp;quot;) Wenn Y, werden die mit f_ bezeichneten Variablen und Values geleert, wenn die Abfrage kein Ergebnis bringt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* f_ - (&amp;quot;Field&amp;quot;) Alle Felder der Datenmenge, die in lokale oder globale Variable geschrieben werden sollen, werden mit einem Prefix aufgeführt. Nach dem Gleichheitszeichen folgt die Nummer der lokalen Variable (&amp;quot;Value&amp;quot;) oder der Name der globalen Variable. Mit einem Ausrufezeichen ist der Name der globalen Variablen gleich dem Feldnamen.&lt;br /&gt;
* k - (&amp;quot;key&amp;quot;) Um Namenskonflikte zu vermeiden, beginnen Parameter im SQL-Statement entsprechend den Konventionen mit einem k. Bei allen Parametern werden Funktionen ersetzt. Siehe auch das Beispiel.&lt;br /&gt;
* row - 0-relativer Index der Reihe, von der die Daten zurückgegeben werden; Default 0, Funktionen werden ersetzt; ist row größer als die Anzahl der Datenreihen, dann werden die Daten der letzten Reihe zurückgegeben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql2  select * &lt;br /&gt;
 #sql2    from user_user  &lt;br /&gt;
 #sql2    where user_user_id = :kid &lt;br /&gt;
 #sql_openval2  kid=$FND(s,user_user_id)   f_firstname=1   f_lastname=2   f_ldap=ldap&lt;br /&gt;
 &lt;br /&gt;
Die Felder firstname und lastname werden in die lokalen Variable (&amp;quot;Values&amp;quot;) 1 und 2 geschrieben, das Feld ldap in die globale Variable ldap.&lt;br /&gt;
&lt;br /&gt;
==#sql_openvalrows==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_openval führt eine select-Statement aus und schreibt das Ergebnis in lokale oder globale Variablen. Die Werte der verschiedenen Datenzeilen werden durch ein Trennzeichen getrennt.&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_openval wird häufig dazu verwendet, um das Ergebnis mit dem IN-Operator in einer WHERE-Klausel zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #sql_openvalrows ruft das erste SQL-Statement auf, #sql_openvalrows2 ruft das zweite SQL-Statement auf, und so weiter.&lt;br /&gt;
 &lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Abfrage bezieht&lt;br /&gt;
* f_ - (&amp;quot;Field&amp;quot;) Alle Felder der Datenmenge, die in lokale oder globale Variable geschrieben werden sollen, werden mit einem Prefix aufgeführt. Nach dem Gleichheitszeichen folgt die Nummer der globalen Variable (&amp;quot;Value&amp;quot;) oder der Name der globalen Variable. Wenn ein Ausrufezeichen folgt, dann wird das Ergebnis in eine Variable geschrieben, deren Namen gleich dem Feldnamen ist. &lt;br /&gt;
* k - (&amp;quot;key&amp;quot;) Um Namenskonflikte zu vermeiden, beginnen Parameter im SQL-Statement entsprechend den Konventionen mit einem k. Bei allen Parametern werden Funktionen ersetzt. Siehe auch das Beispiel.&lt;br /&gt;
* sep - (&amp;quot;separator&amp;quot;) Trennzeichen, default ist ein Komma.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql2  select * &lt;br /&gt;
 #sql2    from user_user  &lt;br /&gt;
 #sql2    where status = 7&lt;br /&gt;
 #sql_openvalrows2  f_login=!&lt;br /&gt;
 #cout   c=$VAR(login)&lt;br /&gt;
&lt;br /&gt;
==#sql_openvallist==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_openvallist führt eine select-Statement aus und ergänzt den mit n angegebenen Text als Liste mit den Werten aus der Spalte f&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Wenn Y, wird das Statement ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Abfrage bezieht&lt;br /&gt;
* f - (&amp;quot;Field&amp;quot;) Der Name des Feldes, dessen Werte hinzugefügt werden sollen&lt;br /&gt;
* k - (&amp;quot;key&amp;quot;) Um Namenskonflikte zu vermeiden, beginnen Parameter im SQL-Statement entsprechend den Konventionen mit einem k. Bei allen Parametern werden Funktionen ersetzt. &lt;br /&gt;
* n - (&amp;quot;nummer&amp;quot;) Nummer des Textes, der als Liste ergänzt wird; default 1, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#sql_openkvl==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_openkvl macht aus dem Ergebnis eine SQL-Abfrage eine Kategory-ValueListe (das kann für Lookup-Live-Nachschlagelisten verwendet werden). Die Abfrage benötigt die Spalten ckat, ckey und cvalue.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clr - (&amp;quot;clear&amp;quot;) Wenn Y wird der Text am Anfang geleert; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Wenn Y, wird das Statement ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Abfrage bezieht&lt;br /&gt;
* n - (&amp;quot;nummer&amp;quot;) Nummer des Kategorie-Valueliste, in den die Daten geschrieben werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select t.tournr as ckat, s.bus_haltestelle_id as ckey, s.land || ' ' || s.plz || ' ' || s.ort || ' - ' || s.beschreibung as cvalue, h.position&lt;br /&gt;
 #sql   from bus_touren t&lt;br /&gt;
 #sql     inner join bus_tour_hs h   on h.bus_touren_id = t.bus_touren_id   and h.status &amp;lt; 7   and (h.position &amp;lt; 99   or t.tournr between 30000 and 40000)&lt;br /&gt;
 #sql     inner join bus_haltestelle s   on s.bus_haltestelle_id = h.haltestelle   and s.status = 1   and s.land &amp;lt;&amp;gt; ''&lt;br /&gt;
 #sql   where t.kuerzel = '$FND(s,kuerzel)'   and t.datum = to_date('$FND(s,datum)', 'dd.mm.yyyy') &lt;br /&gt;
 #sql   order by 1, 4&lt;br /&gt;
 #sql_openkvl   n=1&lt;br /&gt;
&lt;br /&gt;
Für die Nachschlageliste wird dann wie folgt formuliert:&lt;br /&gt;
&lt;br /&gt;
 #grd_lookuplivefill   y=kat   n=1   k=$PVAL(pl,tournr,lookuplive) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==#sql_opentvl==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_opentvl macht aus dem Ergebnis eine SQL-Abfrage eine Text-ValueList (das kann für Nachschlagelisten verwendet wqerden). Die Abfrage benötigt die Spalten ckey und cvalue.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clr - (&amp;quot;clear&amp;quot;) Wenn Y wird der Text am Anfang geleert; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Wenn Y, wird das Statement ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Abfrage bezieht&lt;br /&gt;
* n - (&amp;quot;nummer&amp;quot;) Nummer des Textes, in den die Daten geschrieben werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select nrdv as ckey, name as cvalue from neuland.stamm_laender order by 2&lt;br /&gt;
 #sql_opentvl   n=2   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#sql_intransaction==&lt;br /&gt;
&lt;br /&gt;
Führt das Kommando in einer eigens gestarteten Transaktion aus, die beim Auftreten eines Fehlers mit Rollback zurückgenommen wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Bei allen Parameters werden die Funktionen ersetzt.&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der Meldung, wenn die Transaktion zurückgenommen wird&lt;br /&gt;
* cmd (&amp;quot;Command&amp;quot;) - Kommando, das innerhalb der Transaktion ausgeführt wird.&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y.&lt;br /&gt;
* ex (&amp;quot;Exception&amp;quot;) - Kommando, das im Falle eines Fehlers nach dem Rollback ausgeführt wird.&lt;br /&gt;
* nex (&amp;quot;NoException&amp;quot;) - Wenn Y, wird nach einem Fehler die Ausführung des Kommandos fortgesetzt; default N.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_intransaction   cmd=test_line   c=&amp;quot;Fehler beim Schreiben der Daten&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#sql_upsert==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_upsert schreibt einen Datensatz in eine Datenbanktabelle. Je nach Parameter y wird ein UPDATE- oder ein INSERT-Statement ausgeführt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y. Funktionen werden ersetzt.&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Abfrage bezieht&lt;br /&gt;
* f_ (&amp;quot;fields&amp;quot;) - Die Werte für die einzelnen Spalten werden mit f_-Parametern gesetzt, dem f_ wird jeweils der Spaltenbezeichner angefügt. Funktionen werden ersetzt. Siehe Beispiel.&lt;br /&gt;
* hst (&amp;quot;history&amp;quot;) - Wenn Y,  wird auch ein Datensatz in die History-Tabelle geschrieben. In den meisten Fällen bedeutungslos, da die History-Tabellen über einen Datenbanktrigger geschrieben werden. Default ist Y.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Primärschlüsselspalte der Tabelle. Per default wird der Wert aus dem Tabellennamen abgeleitet. Funktionen werden ersetzt.&lt;br /&gt;
* n (&amp;quot;name / number&amp;quot;) - Name der Variable oder Nummer des Values, in welche(n) die Anzahl der geänderten Datensätze geschrieben wird&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle, in die geschrieben wird. Funktionen werden ersetzt.&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - je nach Existenz eines Datensatzes mit dem entsprechenden Primärschlüssel wird UPDATE oder INSERT ausgeführt. Default i. Funktionen werden ersetzt.&lt;br /&gt;
** a - automatic: es wird geprüft, ob bereits ein Datensatz mit diesem Primätschlüsselwert vorhanden ist; wenn ja, UPDATE, ansonsten INSERT&lt;br /&gt;
** c - check: es wird geprüft, ob bereits ein Datensatz mit allen übergebenen Feldern vorhanden ist; wenn ja, passiert nichts, ansonsten UPDATE&lt;br /&gt;
** i - INSERT&lt;br /&gt;
** u - UPDATE&lt;br /&gt;
&lt;br /&gt;
'''Hinweise''' &lt;br /&gt;
* die Prozedur #sql_upsert braucht zwingend einen Wert für die Primärschlüsselspalte; gegebenenfalls einen Dummy-Wert einfügen.&lt;br /&gt;
* Beim Typ a (automatic) wird erst per SELECT-Statement geprüft, ob ein Datensatz mit dem entsprechenden Primärschlüsselwert vorhanden ist. Dies verlangsamt die Ausführung. Setzen Sie diesen Typ nur dann ein, wenn es erforderlich ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #upsert  y=i   t=user_group   f_user_group_id=$GUID()   f_type=I   f_path=&amp;quot;ig.$DATA(igs,login)&amp;quot;   f_user_user_id=$DATA(igs,user_user_id)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#sql_upsert2==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_upsert2 stellt sich, dass der übergebene Datensatz anschließend in der Datenbank ist. Wenn es ihn noch nicht gibt, wird ein INSERT gemacht, wenn die Daten abweichen, wird ein UPDATE durchgeführt, andernfalls wird nichts weiter unternommen.&lt;br /&gt;
&lt;br /&gt;
Die Prüfung, ob es einen Datensatz bereits gibt, erfolgt mittelt der Parameter kf1..kf9. Der Primärschlüssel des Datensatzes (egal, ob neu angelegt oder geändert oder unverändert) wird nach nk geschrieben.&lt;br /&gt;
&lt;br /&gt;
Hinweis: #sql_upsert2 nicht innerhalb von Transaktionen einsetzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y. Funktionen werden ersetzt.&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Abfrage bezieht&lt;br /&gt;
* f_ (&amp;quot;fields&amp;quot;) - Die Werte für die einzelnen Spalten werden mit f_-Parametern gesetzt, dem f_ wird jeweils der Spaltenbezeichner angefügt. Funktionen werden ersetzt. Siehe Beispiel.&lt;br /&gt;
* hst (&amp;quot;history&amp;quot;) - Wenn Y,  wird auch ein Datensatz in die History-Tabelle geschrieben. In den meisten Fällen bedeutungslos, da die History-Tabellen über einen Datenbanktrigger geschrieben werden. Default ist Y.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Primärschlüsselspalte der Tabelle. Per default wird der Wert aus dem Tabellennamen abgeleitet. Funktionen werden ersetzt.&lt;br /&gt;
* kf1, kf2... (key field) - Satz von Spalten, anhand derer geprüft wird, ob es bereits einen Datensatz gibt oder nicht&lt;br /&gt;
* ky1, ky2... (key type) - Typ der dazugehörenden Schlüsselspalte kf1, kf2...; default ist text&lt;br /&gt;
** int - ganze Zahlen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** text - Text&lt;br /&gt;
* n (&amp;quot;name / number&amp;quot;) - Name der Variable oder Nummer des Values, in welche(n) die Anzahl der geänderten Datensätze geschrieben wird&lt;br /&gt;
* nk (&amp;quot;name / numer key&amp;quot;) - Name der Variable oder Nummer des Values, in welche(n) der Primärschlüssel eines neu angelegten Datensatzes geschrieben wird&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle, in die geschrieben wird. Funktionen werden ersetzt.&lt;br /&gt;
* yk (&amp;quot;type key&amp;quot;) - Spezifiziert, was die Primärschlüsselspalte geschrieben wird, wenn der Datensatz neu angelegt wird. Dies wird speziell bei Datenbanktabellen gebraucht, welche den Primärschlüssel selbst anlegen. Default guid, Funktionen werden ersetzt.&lt;br /&gt;
** guid - es wird eine GUID erzeugt und geschrieben&lt;br /&gt;
** null - die Primärschlüsselspalte bleibt leer&lt;br /&gt;
** 0 - in die Primärschlüsselspalte wird die Zahl 0 geschrieben&lt;br /&gt;
** value - der Wert, der in die Primärschlüsselspalte geschrieben wird, wird mittels f_ übergeben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Mittels kf1 wird geprüft, ob es den ServiceCode bereits gibt. Wenn nein, wird der Datensatz neu angelegt.&lt;br /&gt;
&lt;br /&gt;
 #code   f_extType=$XML_DATA(xml,extType)&lt;br /&gt;
 #code   f_serviceDataID=$XML_DATA(xml,serviceDataID)&lt;br /&gt;
 #code   f_serviceCode=$XML_DATA(xml,serviceCode)&lt;br /&gt;
 #code   f_serviceDescription=$XRR($XML_DATA(xml,serviceDescription))&lt;br /&gt;
 #code   f_destination=$XML_DATA(xml,destination)&lt;br /&gt;
 #code   f_buchbar=$VAL(3)&lt;br /&gt;
 #code   f_status=$VAL(4)&lt;br /&gt;
 #upsert2   t=cache_reisen   kf1=serviceCode   nk=cache_reisen_id   $CODE$&lt;br /&gt;
&lt;br /&gt;
==#sql_migrate==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_migrate dient dazu, das Ergebnis eines Select-Statements in einer Tabelle zu migrieren, häufig auch in einer anderen Datenbank.&lt;br /&gt;
&lt;br /&gt;
HINWEIS: Für Parameter wie t_dest oder k_dest keine Command-Parameter verwenden, sondern ggf. die Command-Parameter in Variable speichern und diese verwenden. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y. Funktionen werden ersetzt.&lt;br /&gt;
* db (&amp;quot;database&amp;quot;) - Die Datenbank, für die das SQL-Statement ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* db_dest (&amp;quot;database destination&amp;quot;) - Die Datenbank, in welche die Daten migriert werden&lt;br /&gt;
* hst_dest (&amp;quot;history destination&amp;quot;) - Wenn Y, werden die History-Felder ergänzt. Default Y, Funktionen werden ersetzt&lt;br /&gt;
* k_dest (&amp;quot;key destination&amp;quot;) - Der Name der Primärschlüsselspalte; sofern nicht gesetzt, wird sie aus dem Tabellennamen t_dest abgeleitet; Funktionen werden ersetzt  (Funktionen $VAL und $CP() nicht verwenden).&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen, die in die Zieltabelle eingefügt werden; Funktionen werden ersetzt&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird im Falle einer Exception die Bearbeitung nicht abgebrochen, sondern lediglich Warnungen geloggt; Default N, Funktionen werden ersetzt&lt;br /&gt;
* t_dest (&amp;quot;table destination&amp;quot;) - Name der Tabelle, in der die Daten eingefügt werden; Funktionen werden ersetzt (Funktionen $VAL und $CP() nicht verwenden).&lt;br /&gt;
* y_dest (&amp;quot;type destination&amp;quot;) - i - INSERT, u - UPDATE, a - automatic, je nach Existenz eines Datensatzes mit dem entsprechenden Primärschlüssel wird UPDATE oder INSERT ausgeführt. Default i. Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select translate_word_id as translate_word2_id, word, datechg, usrchg, progchg from translate_word&lt;br /&gt;
 #sql_migrate   t_dest=translate_word2   nex=Y   db=test&lt;br /&gt;
&lt;br /&gt;
==$SQL()==&lt;br /&gt;
&lt;br /&gt;
Führt eine SQL-Anweisung aus und gibt die erste Spalte der ersten Datenreihe als Ergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des SQL-Statements oder SQL-Statement, siehe Beispiele&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #message c=&amp;quot;$SQL(select count from user_user)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #sql3 select count from user_user&lt;br /&gt;
 #message c=$SQL(3)&lt;br /&gt;
&lt;br /&gt;
==$SQL_CONCAT()==&lt;br /&gt;
&lt;br /&gt;
Die unterschiedlichen SQL-Dialekte kennen unterschiedliche Methoden, Strings zusammenzufügen. Das kann bei SQL-Anweisungen, die auf unterschiedlichen Datenbanksystemen verwendet werden soll, zu Problemen führen. In einem solchen Fall wird $SQL_CONCAT() eingesetzt, was dann in das SQL-Statement die korrekte Concatenation-Anweisung einfügt.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Kommata und Klammern dürfen in den Statements nicht direkt eingesetzt werden, sondern müssen mit $CHR-Funktionen eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Concatenation-Anweisungen'''&lt;br /&gt;
&lt;br /&gt;
* sqlite: ||&lt;br /&gt;
* firebird: ||&lt;br /&gt;
* postgres: ||&lt;br /&gt;
* oracle: ||&lt;br /&gt;
* mysql: concat&lt;br /&gt;
* mssql: +&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Datenbanktreibers oder ''default'' (also der Treiber des aktuellen Datenbanksystems)&lt;br /&gt;
# und weitere: Strings, die zusammengefügt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 select user_user_id as ckey, $SQL_CONCAT(default,login,' $CHR(bro)',firstname,' ',lastname,'$CHR(brc)') as cvalue   &lt;br /&gt;
   from user_user   &lt;br /&gt;
   order by login&lt;br /&gt;
&lt;br /&gt;
==$SQL_NVL()==&lt;br /&gt;
&lt;br /&gt;
Die unterschiedlichen SQL-Dialekte kennen unterschiedliche Methoden, um leere Werte zu ersetzen. Das kann bei SQL-Anweisungen, die auf unterschiedlichen Datenbanksystemen verwendet werden soll, zu Problemen führen. In einem solchen Fall wird $SQL_NVL() eingesetzt, was dann in das SQL-Statement die korrekte Ersetzungs-Anweisung einfügt.&lt;br /&gt;
&lt;br /&gt;
$SQL_NVL-Funktionen können geschachtelt werden, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Kommata und Klammern dürfen in den Statements nicht direkt eingesetzt werden, sondern müssen mit $CHR-Funktionen eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Ersetzungs-Anweisungen'''&lt;br /&gt;
&lt;br /&gt;
* sqlite: ifnull&lt;br /&gt;
* firebird: coalesce&lt;br /&gt;
* postgres: coalesce&lt;br /&gt;
* oracle: NVL&lt;br /&gt;
* mysql: ifnull&lt;br /&gt;
* mssql: isnull&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Datenbanktreibers oder ''default'' (also der Treiber des aktuellen Datenbanksystems)&lt;br /&gt;
# Wert, der ersetzt werden soll, wenn er leer ist&lt;br /&gt;
# Wert, mit dem ersetzt wird, wenn der Wert des 2. Parameters leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 select i.ckey, $SQL_NVL(default,t.cvalue, $SQL_NVL(default,t2.cvalue, i.cvalue)) as cvalue &lt;br /&gt;
   from data_list l &lt;br /&gt;
     inner join data_list_item i on i.data_list_id = l.data_list_id  and i.status &amp;lt; 7 &lt;br /&gt;
     left outer join translate_list_item t on t.data_list_item_id = i.data_list_item_id and t.translate_language_id = :klangid&lt;br /&gt;
     left outer join translate_list_item t2 on t2.data_list_item_id = i.data_list_item_id and t2.translate_language_id = :klangid2&lt;br /&gt;
   where l.name = :kname &lt;br /&gt;
   order by i.csort, i.ckey&lt;br /&gt;
&lt;br /&gt;
==$SQLTEXT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Inhalt eines SQL-Statements zurück. Kann mal beim Debuggen hilfreich sein, mit den Debug-Tools sollte es einfacher gehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des SQL-Statements&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #clipboard   z=$SQLTEXT(3)&lt;br /&gt;
&lt;br /&gt;
==$DATA()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Inhalt eines Felder der aktuellen Datenzeile einer mit #sql_open geöffneten Datenmenge zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Datenmenge (muss als Parameter n in #sql_open angegeben sein)&lt;br /&gt;
# Feldname in der Datenmenge&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
# optional: Wenn der vierte Prameter auf accnd (&amp;quot;accept no data&amp;quot;), dann kommt es zu keinem Fehler, wenn es das Feld und/oder die Datenmenge nicht gibt. In einem solchen Fall wird dann der NULL-Value-Wert ausgegeben; siehe das zweite Beispiel.&lt;br /&gt;
# optional: Name der Datenbankverbindung, wenn nicht default&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text $DATA(test,firstname) $DATA(test,lastname)&lt;br /&gt;
 #cout  c=&amp;quot;$DATA(dat,test,this default is displayd without any dataset,accnd)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$ISNULL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Inhalt des Feldes NULL ist oder das Feld nicht existiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Datenmenge (muss als Parameter n in #sql_open angegeben sein)&lt;br /&gt;
# Feldname in der Datenmenge&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $ISNULL(test,firstname)&lt;br /&gt;
&lt;br /&gt;
==$DATAXML()==&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$DDEF()==&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_DB&amp;diff=22532</id>
		<title>Modul DB</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_DB&amp;diff=22532"/>
		<updated>2025-07-14T09:44:15Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #sql_openvalrows */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=DB=&lt;br /&gt;
&lt;br /&gt;
Im Modul DB werden die Datenbank-Routinen zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
* '''#sql''' fügt dem SQL-Statement eine Zeile hinzu&lt;br /&gt;
* '''#sql_clear''' löscht das SQL-Statement&lt;br /&gt;
* '''#sql_exec''' führt SQL-Statement aus&lt;br /&gt;
* '''#sql_open''' führt ein select-Statement aus und ruft für jede Zeile der Datenmenge das angegebene Kommando aus.&lt;br /&gt;
* '''#sql_openval''' führt eine select-Statement aus und schreibt das Ergebnis der ersten (ind er Regel der einzigen) Datenzeile in lokale oder globale Variable&lt;br /&gt;
* '''#sql_openvalrows''' führt eine select-Statement aus und schreibt das Ergebnis in lokale oder globale Variablen. Die Werte der verschiedenen Datenzeilen werden durch ein Trennzeichen getrennt.&lt;br /&gt;
* '''#sql_intransaction''' führt ein Kommando in einer eigens gestarteten Transaktion aus.&lt;br /&gt;
* '''#sql_upsert''' schreibt eine Zeile in eine Datenbanktabelle.&lt;br /&gt;
&lt;br /&gt;
* '''$SQL()''' führt eine SQL-Anweisung aus und gibt die erste Spalte der ersten Datenreihe als Ergebnis zurück.&lt;br /&gt;
* '''$SQLTEXT()''' gibt den Inhalt eines SQL-Statements zurück.&lt;br /&gt;
* '''$DATA()''' gibt den Inhalt eines Felder der aktuellen Datenzeile einer mit #sql_open geöffneten Datenmenge zurück.&lt;br /&gt;
* '''$ISNULL()''' gibt Y zurück, wenn der Inhalt des Feldes NULL ist oder das Feld nicht existiert.&lt;br /&gt;
&lt;br /&gt;
==#sql==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql fügt dem SQL-Statement eine Zeile hinzu.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #sql fügt dem ersten SQL-Statement eine Zeile hinzu, #sql2 fügt dem zweiten SQL-Statement eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#sql hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Hinweis'''&lt;br /&gt;
&lt;br /&gt;
Durch den Aufruf einer der folgenden Prozeduren wird das SQL-Statement (nach der Ausführung) wieder geleert:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #sql_openval&lt;br /&gt;
* #sql_openvalrows&lt;br /&gt;
* #sql_exec&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select count(*) as cnt&lt;br /&gt;
 #sql    from user_user&lt;br /&gt;
 #opensqlval   f_cnt=1&lt;br /&gt;
&lt;br /&gt;
==#sql_line==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql fügt dem SQL-Statement den Text im Parameter z als Zeile hinzu.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #sql_line fügt dem ersten SQL-Statement eine Zeile hinzu, #sql_line2 fügt dem zweiten SQL-Statement eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Name des Eintrags in den Entwicklertexten, üblicherweise unterhalb von SQL; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_line z=&amp;quot;    and status = 51&amp;quot; cnd=$ICP(0,rü)&lt;br /&gt;
&lt;br /&gt;
==#sql_text==&lt;br /&gt;
&lt;br /&gt;
Holt ein SQL-Statement aus den Entwicklertexten (xdevtext). Diese Möglichkeit wird gerne für SQL-Statements verwendet, die auf verschiedene Datenbanksysteme angepasst werden müssen (zum Beispiel wegen des Einsatzes von NVL/ifnull/coalesce).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Eintrags in den Entwicklertexten, üblicherweise unterhalb von SQL; Funktionen werden ersetzt.&lt;br /&gt;
* d (&amp;quot;driver&amp;quot;) - Name des Datenbanktreibers. Wird in der Baumhierarchie direkt unter dem mit n bezeichneten Statement ein Eintrag mit dem Name des Datenbanktreibers gefunden, so wird dieses SQL-Statement statt dem mit n bezeichneten Statements verwendet. Auf diese Weise lassen sich übersichtlich Statements für alle eingesetzten Datenbanktreiber in der Datenbank speichern. Bleibt d leer (was üblicherweise der Fall ist), so wird der Treibername der aktuellen Primärdatenbank verwendet. Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sqltext   n=_system_lookup_202  &lt;br /&gt;
 #cout   c=$SQLTEXT(1)&lt;br /&gt;
&lt;br /&gt;
 #sqltext   n=_system_lookup_202   d=firebird&lt;br /&gt;
 #cout   c=$SQLTEXT(1)&lt;br /&gt;
&lt;br /&gt;
==#sql_clear==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_clear löscht das SQL-Statement.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #sql_clear löscht das erste SQL-Statement, #sql_clear2 löscht das zweite SQL-Statement, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Hinweis'''&lt;br /&gt;
&lt;br /&gt;
Der Aufruf von #sql_clear ist im Regelfall nicht erforderlich, da durch den Aufruf einer der folgenden Prozeduren das SQL-Statement (nach der Ausführung) wieder geleert wird:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #sql_openval&lt;br /&gt;
* #sql_openvalrows&lt;br /&gt;
* #sql_exec&lt;br /&gt;
&lt;br /&gt;
Allerdings kann es bei einem Fehler vorkommen, dass das SQL-Statement nicht geleert wird und beim Aufbau eines neuen Statements Zeilen der vorherigen Statements zurückgeblieben sind. Das kann mit #sql_clear verhindert werden. Die Prozedur wird üblicherweise vor den Beginn eines neuen Statements gesetzt, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_clear&lt;br /&gt;
 #sql  select count(*) as cnt&lt;br /&gt;
 #sql    from user_user&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
&lt;br /&gt;
==#sql_exec==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_exec führt ein SQL-Statement.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #sql_exec führt das erste SQL-Statement aus, #sql_exec2 führt das zweite SQL-Statement aus, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y.&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Abfrage bezieht&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Um Namenskonflikte zu vermeiden, beginnen Parameter im SQL-Statement entsprechend den Konventionen mit einem k. Bei allen Parametern werden Funktionen ersetzt. Siehe auch das Beispiel.&lt;br /&gt;
* srv_ops (&amp;quot;Server Operations&amp;quot;) - Wenn Y, wird die Zahl der betroffenen Datensätze den Server Operations hinzugefügt. Wird im Server-Betrieb verwendet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* z - Nummer des Values, in das die Zahl der betroffenen Datensätze gespeichert werden kann&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql update tbl_test set status = 7 where tbl_test_id = :kid&lt;br /&gt;
 #sql_exec  :kid=$FND(s,tbl_test_id)   z=1&lt;br /&gt;
 #message   c=&amp;quot;Es wurden $VAR(1) Datensätze deaktiviert.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#sql_open==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_open führt ein select-Statement aus und ruft für jede Zeile der Datenmenge das angegebene Kommando aus.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #sql_open ruft das erste SQL-Statement auf, #sql_open2 ruft das zweite SQL-Statement auf, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acnd - (&amp;quot;abort condition&amp;quot;) wenn Y, wird die Verarbeitung abgebrochen; wird nach jedem Aufruf von er geprüft; Default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y; Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Abfrage bezieht; Funktionen werden ersetzt&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen; Funktionen werden ersetzt&lt;br /&gt;
* k - (&amp;quot;key&amp;quot;) Um Namenskonflikte zu vermeiden, beginnen Parameter im SQL-Statement entsprechend den Konventionen mit einem k. Bei allen Parametern werden Funktionen ersetzt. Siehe auch das Beispiel.&lt;br /&gt;
* m - (&amp;quot;maximum&amp;quot;) Es wird maximal für die Anzahl der angegebenen Zeilen das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten; Funktionen werden ersetzt&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N; Funktionen werden ersetzt.&lt;br /&gt;
* n - Name der Datenmenge, wird benötigt, um mit $DATA() auf die einzelnen Felder zugreifen zu können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select * &lt;br /&gt;
 #sql    from user_user&lt;br /&gt;
 #sql    where upper(lastname) like upper(:kname)&lt;br /&gt;
 #sql_open  n=test  er=test_line  kname=$EDT(edt1)%&lt;br /&gt;
&lt;br /&gt;
==#sql_openval==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_openval führt eine select-Statement aus und schreibt das Ergebnis der ersten (ind er Regel der einzigen) Datenzeile in lokale oder globale Variable.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #sql_openval ruft das erste SQL-Statement auf, #sql_openval2 ruft das zweite SQL-Statement auf, und so weiter.&lt;br /&gt;
 &lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* af (&amp;quot;all fields&amp;quot;) - Legt alle Felder der Abfrage in einer gleichnamigen Variablen ab, die f_-Definitionen können dann entfallen; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt - (&amp;quot;count&amp;quot;) Ermittelt die Anzahl der Datensätze, die das SQL-Statement zurück gibt, und schreibt diese in die mit diesem Parameter bezeichneten Variablen oder Value&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Abfrage bezieht&lt;br /&gt;
* de - (&amp;quot;do empty&amp;quot;) Wenn Y, werden die mit f_ bezeichneten Variablen und Values geleert, wenn die Abfrage kein Ergebnis bringt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* f_ - (&amp;quot;Field&amp;quot;) Alle Felder der Datenmenge, die in lokale oder globale Variable geschrieben werden sollen, werden mit einem Prefix aufgeführt. Nach dem Gleichheitszeichen folgt die Nummer der lokalen Variable (&amp;quot;Value&amp;quot;) oder der Name der globalen Variable. Mit einem Ausrufezeichen ist der Name der globalen Variablen gleich dem Feldnamen.&lt;br /&gt;
* k - (&amp;quot;key&amp;quot;) Um Namenskonflikte zu vermeiden, beginnen Parameter im SQL-Statement entsprechend den Konventionen mit einem k. Bei allen Parametern werden Funktionen ersetzt. Siehe auch das Beispiel.&lt;br /&gt;
* row - 0-relativer Index der Reihe, von der die Daten zurückgegeben werden; Default 0, Funktionen werden ersetzt; ist row größer als die Anzahl der Datenreihen, dann werden die Daten der letzten Reihe zurückgegeben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql2  select * &lt;br /&gt;
 #sql2    from user_user  &lt;br /&gt;
 #sql2    where user_user_id = :kid &lt;br /&gt;
 #sql_openval2  kid=$FND(s,user_user_id)   f_firstname=1   f_lastname=2   f_ldap=ldap&lt;br /&gt;
 &lt;br /&gt;
Die Felder firstname und lastname werden in die lokalen Variable (&amp;quot;Values&amp;quot;) 1 und 2 geschrieben, das Feld ldap in die globale Variable ldap.&lt;br /&gt;
&lt;br /&gt;
==#sql_openvalrows==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_openval führt eine select-Statement aus und schreibt das Ergebnis in lokale oder globale Variablen. Die Werte der verschiedenen Datenzeilen werden durch ein Trennzeichen getrennt.&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_openval wird häufig dazu verwendet, um das Ergebnis mit dem IN-Operator in einer WHERE-Klausel zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #sql_openvalrows ruft das erste SQL-Statement auf, #sql_openvalrows2 ruft das zweite SQL-Statement auf, und so weiter.&lt;br /&gt;
 &lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Abfrage bezieht&lt;br /&gt;
* f_ - (&amp;quot;Field&amp;quot;) Alle Felder der Datenmenge, die in lokale oder globale Variable geschrieben werden sollen, werden mit einem Prefix aufgeführt. Nach dem Gleichheitszeichen folgt die Nummer der globalen Variable (&amp;quot;Value&amp;quot;) oder der Name der globalen Variable. Wenn ein Ausrufezeichen folgt, dann wird das Ergebnis in eine Variable geschrieben, deren Namen gleich dem Feldnamen ist. &lt;br /&gt;
* k - (&amp;quot;key&amp;quot;) Um Namenskonflikte zu vermeiden, beginnen Parameter im SQL-Statement entsprechend den Konventionen mit einem k. Bei allen Parametern werden Funktionen ersetzt. Siehe auch das Beispiel.&lt;br /&gt;
* sep - (&amp;quot;separator&amp;quot;) Trennzeichen, default ist ein Komma.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql2  select * &lt;br /&gt;
 #sql2    from user_user  &lt;br /&gt;
 #sql2    where status = 7&lt;br /&gt;
 #sql_openvalrows2  f_login=!&lt;br /&gt;
 #cout   c=$VAR(login)&lt;br /&gt;
&lt;br /&gt;
==#sql_openvallist==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_openvallist führt eine select-Statement aus und ergänzt den mit n angegebenen Text als Liste mit den Werten aus der Spalte f&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Wenn Y, wird das Statement ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Abfrage bezieht&lt;br /&gt;
* f - (&amp;quot;Field&amp;quot;) Der Name des Feldes, dessen Werte hinzugefügt werden sollen&lt;br /&gt;
* k - (&amp;quot;key&amp;quot;) Um Namenskonflikte zu vermeiden, beginnen Parameter im SQL-Statement entsprechend den Konventionen mit einem k. Bei allen Parametern werden Funktionen ersetzt. &lt;br /&gt;
* n - (&amp;quot;nummer&amp;quot;) Nummer des Textes, der als Liste ergänzt wird; default 1, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#sql_opentvl==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_opentvl macht aus dem Ergebnis eine SQL-Abfrage eine Text-ValueList (das kann für Nachschlagelisten verwendet wqerden). Die Abfrage benötigt die Spalten ckey und cvalue.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clr - (&amp;quot;clear&amp;quot;) Wenn Y wird der Text am Anfang geleert; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Wenn Y, wird das Statement ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Abfrage bezieht&lt;br /&gt;
* n - (&amp;quot;nummer&amp;quot;) Nummer des Textes, in den die Daten geschrieben werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select nrdv as ckey, name as cvalue from neuland.stamm_laender order by 2&lt;br /&gt;
 #sql_opentvl   n=2   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#sql_intransaction==&lt;br /&gt;
&lt;br /&gt;
Führt das Kommando in einer eigens gestarteten Transaktion aus, die beim Auftreten eines Fehlers mit Rollback zurückgenommen wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Bei allen Parameters werden die Funktionen ersetzt.&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der Meldung, wenn die Transaktion zurückgenommen wird&lt;br /&gt;
* cmd (&amp;quot;Command&amp;quot;) - Kommando, das innerhalb der Transaktion ausgeführt wird.&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y.&lt;br /&gt;
* ex (&amp;quot;Exception&amp;quot;) - Kommando, das im Falle eines Fehlers nach dem Rollback ausgeführt wird.&lt;br /&gt;
* nex (&amp;quot;NoException&amp;quot;) - Wenn Y, wird nach einem Fehler die Ausführung des Kommandos fortgesetzt; default N.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_intransaction   cmd=test_line   c=&amp;quot;Fehler beim Schreiben der Daten&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#sql_upsert==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_upsert schreibt einen Datensatz in eine Datenbanktabelle. Je nach Parameter y wird ein UPDATE- oder ein INSERT-Statement ausgeführt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y. Funktionen werden ersetzt.&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Abfrage bezieht&lt;br /&gt;
* f_ (&amp;quot;fields&amp;quot;) - Die Werte für die einzelnen Spalten werden mit f_-Parametern gesetzt, dem f_ wird jeweils der Spaltenbezeichner angefügt. Funktionen werden ersetzt. Siehe Beispiel.&lt;br /&gt;
* hst (&amp;quot;history&amp;quot;) - Wenn Y,  wird auch ein Datensatz in die History-Tabelle geschrieben. In den meisten Fällen bedeutungslos, da die History-Tabellen über einen Datenbanktrigger geschrieben werden. Default ist Y.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Primärschlüsselspalte der Tabelle. Per default wird der Wert aus dem Tabellennamen abgeleitet. Funktionen werden ersetzt.&lt;br /&gt;
* n (&amp;quot;name / number&amp;quot;) - Name der Variable oder Nummer des Values, in welche(n) die Anzahl der geänderten Datensätze geschrieben wird&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle, in die geschrieben wird. Funktionen werden ersetzt.&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - je nach Existenz eines Datensatzes mit dem entsprechenden Primärschlüssel wird UPDATE oder INSERT ausgeführt. Default i. Funktionen werden ersetzt.&lt;br /&gt;
** a - automatic: es wird geprüft, ob bereits ein Datensatz mit diesem Primätschlüsselwert vorhanden ist; wenn ja, UPDATE, ansonsten INSERT&lt;br /&gt;
** c - check: es wird geprüft, ob bereits ein Datensatz mit allen übergebenen Feldern vorhanden ist; wenn ja, passiert nichts, ansonsten UPDATE&lt;br /&gt;
** i - INSERT&lt;br /&gt;
** u - UPDATE&lt;br /&gt;
&lt;br /&gt;
'''Hinweise''' &lt;br /&gt;
* die Prozedur #sql_upsert braucht zwingend einen Wert für die Primärschlüsselspalte; gegebenenfalls einen Dummy-Wert einfügen.&lt;br /&gt;
* Beim Typ a (automatic) wird erst per SELECT-Statement geprüft, ob ein Datensatz mit dem entsprechenden Primärschlüsselwert vorhanden ist. Dies verlangsamt die Ausführung. Setzen Sie diesen Typ nur dann ein, wenn es erforderlich ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #upsert  y=i   t=user_group   f_user_group_id=$GUID()   f_type=I   f_path=&amp;quot;ig.$DATA(igs,login)&amp;quot;   f_user_user_id=$DATA(igs,user_user_id)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#sql_upsert2==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_upsert2 stellt sich, dass der übergebene Datensatz anschließend in der Datenbank ist. Wenn es ihn noch nicht gibt, wird ein INSERT gemacht, wenn die Daten abweichen, wird ein UPDATE durchgeführt, andernfalls wird nichts weiter unternommen.&lt;br /&gt;
&lt;br /&gt;
Die Prüfung, ob es einen Datensatz bereits gibt, erfolgt mittelt der Parameter kf1..kf9. Der Primärschlüssel des Datensatzes (egal, ob neu angelegt oder geändert oder unverändert) wird nach nk geschrieben.&lt;br /&gt;
&lt;br /&gt;
Hinweis: #sql_upsert2 nicht innerhalb von Transaktionen einsetzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y. Funktionen werden ersetzt.&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich die Abfrage bezieht&lt;br /&gt;
* f_ (&amp;quot;fields&amp;quot;) - Die Werte für die einzelnen Spalten werden mit f_-Parametern gesetzt, dem f_ wird jeweils der Spaltenbezeichner angefügt. Funktionen werden ersetzt. Siehe Beispiel.&lt;br /&gt;
* hst (&amp;quot;history&amp;quot;) - Wenn Y,  wird auch ein Datensatz in die History-Tabelle geschrieben. In den meisten Fällen bedeutungslos, da die History-Tabellen über einen Datenbanktrigger geschrieben werden. Default ist Y.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Primärschlüsselspalte der Tabelle. Per default wird der Wert aus dem Tabellennamen abgeleitet. Funktionen werden ersetzt.&lt;br /&gt;
* kf1, kf2... (key field) - Satz von Spalten, anhand derer geprüft wird, ob es bereits einen Datensatz gibt oder nicht&lt;br /&gt;
* ky1, ky2... (key type) - Typ der dazugehörenden Schlüsselspalte kf1, kf2...; default ist text&lt;br /&gt;
** int - ganze Zahlen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** text - Text&lt;br /&gt;
* n (&amp;quot;name / number&amp;quot;) - Name der Variable oder Nummer des Values, in welche(n) die Anzahl der geänderten Datensätze geschrieben wird&lt;br /&gt;
* nk (&amp;quot;name / numer key&amp;quot;) - Name der Variable oder Nummer des Values, in welche(n) der Primärschlüssel eines neu angelegten Datensatzes geschrieben wird&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle, in die geschrieben wird. Funktionen werden ersetzt.&lt;br /&gt;
* yk (&amp;quot;type key&amp;quot;) - Spezifiziert, was die Primärschlüsselspalte geschrieben wird, wenn der Datensatz neu angelegt wird. Dies wird speziell bei Datenbanktabellen gebraucht, welche den Primärschlüssel selbst anlegen. Default guid, Funktionen werden ersetzt.&lt;br /&gt;
** guid - es wird eine GUID erzeugt und geschrieben&lt;br /&gt;
** null - die Primärschlüsselspalte bleibt leer&lt;br /&gt;
** 0 - in die Primärschlüsselspalte wird die Zahl 0 geschrieben&lt;br /&gt;
** value - der Wert, der in die Primärschlüsselspalte geschrieben wird, wird mittels f_ übergeben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Mittels kf1 wird geprüft, ob es den ServiceCode bereits gibt. Wenn nein, wird der Datensatz neu angelegt.&lt;br /&gt;
&lt;br /&gt;
 #code   f_extType=$XML_DATA(xml,extType)&lt;br /&gt;
 #code   f_serviceDataID=$XML_DATA(xml,serviceDataID)&lt;br /&gt;
 #code   f_serviceCode=$XML_DATA(xml,serviceCode)&lt;br /&gt;
 #code   f_serviceDescription=$XRR($XML_DATA(xml,serviceDescription))&lt;br /&gt;
 #code   f_destination=$XML_DATA(xml,destination)&lt;br /&gt;
 #code   f_buchbar=$VAL(3)&lt;br /&gt;
 #code   f_status=$VAL(4)&lt;br /&gt;
 #upsert2   t=cache_reisen   kf1=serviceCode   nk=cache_reisen_id   $CODE$&lt;br /&gt;
&lt;br /&gt;
==#sql_migrate==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sql_migrate dient dazu, das Ergebnis eines Select-Statements in einer Tabelle zu migrieren, häufig auch in einer anderen Datenbank.&lt;br /&gt;
&lt;br /&gt;
HINWEIS: Für Parameter wie t_dest oder k_dest keine Command-Parameter verwenden, sondern ggf. die Command-Parameter in Variable speichern und diese verwenden. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y. Funktionen werden ersetzt.&lt;br /&gt;
* db (&amp;quot;database&amp;quot;) - Die Datenbank, für die das SQL-Statement ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* db_dest (&amp;quot;database destination&amp;quot;) - Die Datenbank, in welche die Daten migriert werden&lt;br /&gt;
* hst_dest (&amp;quot;history destination&amp;quot;) - Wenn Y, werden die History-Felder ergänzt. Default Y, Funktionen werden ersetzt&lt;br /&gt;
* k_dest (&amp;quot;key destination&amp;quot;) - Der Name der Primärschlüsselspalte; sofern nicht gesetzt, wird sie aus dem Tabellennamen t_dest abgeleitet; Funktionen werden ersetzt  (Funktionen $VAL und $CP() nicht verwenden).&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen, die in die Zieltabelle eingefügt werden; Funktionen werden ersetzt&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird im Falle einer Exception die Bearbeitung nicht abgebrochen, sondern lediglich Warnungen geloggt; Default N, Funktionen werden ersetzt&lt;br /&gt;
* t_dest (&amp;quot;table destination&amp;quot;) - Name der Tabelle, in der die Daten eingefügt werden; Funktionen werden ersetzt (Funktionen $VAL und $CP() nicht verwenden).&lt;br /&gt;
* y_dest (&amp;quot;type destination&amp;quot;) - i - INSERT, u - UPDATE, a - automatic, je nach Existenz eines Datensatzes mit dem entsprechenden Primärschlüssel wird UPDATE oder INSERT ausgeführt. Default i. Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select translate_word_id as translate_word2_id, word, datechg, usrchg, progchg from translate_word&lt;br /&gt;
 #sql_migrate   t_dest=translate_word2   nex=Y   db=test&lt;br /&gt;
&lt;br /&gt;
==$SQL()==&lt;br /&gt;
&lt;br /&gt;
Führt eine SQL-Anweisung aus und gibt die erste Spalte der ersten Datenreihe als Ergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des SQL-Statements oder SQL-Statement, siehe Beispiele&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #message c=&amp;quot;$SQL(select count from user_user)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #sql3 select count from user_user&lt;br /&gt;
 #message c=$SQL(3)&lt;br /&gt;
&lt;br /&gt;
==$SQL_CONCAT()==&lt;br /&gt;
&lt;br /&gt;
Die unterschiedlichen SQL-Dialekte kennen unterschiedliche Methoden, Strings zusammenzufügen. Das kann bei SQL-Anweisungen, die auf unterschiedlichen Datenbanksystemen verwendet werden soll, zu Problemen führen. In einem solchen Fall wird $SQL_CONCAT() eingesetzt, was dann in das SQL-Statement die korrekte Concatenation-Anweisung einfügt.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Kommata und Klammern dürfen in den Statements nicht direkt eingesetzt werden, sondern müssen mit $CHR-Funktionen eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Concatenation-Anweisungen'''&lt;br /&gt;
&lt;br /&gt;
* sqlite: ||&lt;br /&gt;
* firebird: ||&lt;br /&gt;
* postgres: ||&lt;br /&gt;
* oracle: ||&lt;br /&gt;
* mysql: concat&lt;br /&gt;
* mssql: +&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Datenbanktreibers oder ''default'' (also der Treiber des aktuellen Datenbanksystems)&lt;br /&gt;
# und weitere: Strings, die zusammengefügt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 select user_user_id as ckey, $SQL_CONCAT(default,login,' $CHR(bro)',firstname,' ',lastname,'$CHR(brc)') as cvalue   &lt;br /&gt;
   from user_user   &lt;br /&gt;
   order by login&lt;br /&gt;
&lt;br /&gt;
==$SQL_NVL()==&lt;br /&gt;
&lt;br /&gt;
Die unterschiedlichen SQL-Dialekte kennen unterschiedliche Methoden, um leere Werte zu ersetzen. Das kann bei SQL-Anweisungen, die auf unterschiedlichen Datenbanksystemen verwendet werden soll, zu Problemen führen. In einem solchen Fall wird $SQL_NVL() eingesetzt, was dann in das SQL-Statement die korrekte Ersetzungs-Anweisung einfügt.&lt;br /&gt;
&lt;br /&gt;
$SQL_NVL-Funktionen können geschachtelt werden, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Kommata und Klammern dürfen in den Statements nicht direkt eingesetzt werden, sondern müssen mit $CHR-Funktionen eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Ersetzungs-Anweisungen'''&lt;br /&gt;
&lt;br /&gt;
* sqlite: ifnull&lt;br /&gt;
* firebird: coalesce&lt;br /&gt;
* postgres: coalesce&lt;br /&gt;
* oracle: NVL&lt;br /&gt;
* mysql: ifnull&lt;br /&gt;
* mssql: isnull&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Datenbanktreibers oder ''default'' (also der Treiber des aktuellen Datenbanksystems)&lt;br /&gt;
# Wert, der ersetzt werden soll, wenn er leer ist&lt;br /&gt;
# Wert, mit dem ersetzt wird, wenn der Wert des 2. Parameters leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 select i.ckey, $SQL_NVL(default,t.cvalue, $SQL_NVL(default,t2.cvalue, i.cvalue)) as cvalue &lt;br /&gt;
   from data_list l &lt;br /&gt;
     inner join data_list_item i on i.data_list_id = l.data_list_id  and i.status &amp;lt; 7 &lt;br /&gt;
     left outer join translate_list_item t on t.data_list_item_id = i.data_list_item_id and t.translate_language_id = :klangid&lt;br /&gt;
     left outer join translate_list_item t2 on t2.data_list_item_id = i.data_list_item_id and t2.translate_language_id = :klangid2&lt;br /&gt;
   where l.name = :kname &lt;br /&gt;
   order by i.csort, i.ckey&lt;br /&gt;
&lt;br /&gt;
==$SQLTEXT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Inhalt eines SQL-Statements zurück. Kann mal beim Debuggen hilfreich sein, mit den Debug-Tools sollte es einfacher gehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des SQL-Statements&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #clipboard   z=$SQLTEXT(3)&lt;br /&gt;
&lt;br /&gt;
==$DATA()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Inhalt eines Felder der aktuellen Datenzeile einer mit #sql_open geöffneten Datenmenge zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Datenmenge (muss als Parameter n in #sql_open angegeben sein)&lt;br /&gt;
# Feldname in der Datenmenge&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
# optional: Wenn der vierte Prameter auf accnd (&amp;quot;accept no data&amp;quot;), dann kommt es zu keinem Fehler, wenn es das Feld und/oder die Datenmenge nicht gibt. In einem solchen Fall wird dann der NULL-Value-Wert ausgegeben; siehe das zweite Beispiel.&lt;br /&gt;
# optional: Name der Datenbankverbindung, wenn nicht default&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text $DATA(test,firstname) $DATA(test,lastname)&lt;br /&gt;
 #cout  c=&amp;quot;$DATA(dat,test,this default is displayd without any dataset,accnd)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$ISNULL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Inhalt des Feldes NULL ist oder das Feld nicht existiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Datenmenge (muss als Parameter n in #sql_open angegeben sein)&lt;br /&gt;
# Feldname in der Datenmenge&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $ISNULL(test,firstname)&lt;br /&gt;
&lt;br /&gt;
==$DATAXML()==&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$DDEF()==&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Versionen_Server&amp;diff=22531</id>
		<title>Versionen Server</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Versionen_Server&amp;diff=22531"/>
		<updated>2025-07-13T16:37:16Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=BAF-Server Download=&lt;br /&gt;
&lt;br /&gt;
* Einfach die ZIP-Datei entpacken &lt;br /&gt;
* Datenbank in der Ini passend zum Client einrichten&lt;br /&gt;
* Tabellen und xserver im BAF-Client ergänzen&lt;br /&gt;
* Den BAF-Server einfach mit der Datei pBafServer.exe starten&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Video [https://www.youtube.com/watch?v=95NUxGX6R1k| BAF-Server einrichten (13:01)]&lt;br /&gt;
&lt;br /&gt;
==BAF-Server 0.1 mit SrvProc 1.03==&lt;br /&gt;
&lt;br /&gt;
Download (bs_v1_03.zip, 26.420 KB)[[https://bafbal.de/downloads/bs_v1_03.zip]]&lt;br /&gt;
&lt;br /&gt;
==BAF-Server 0.1 mit SrvProc 1.02==&lt;br /&gt;
&lt;br /&gt;
Download (bs_v1_02.zip, 25.071 KB)[[https://bafbal.de/downloads/bs_v1_02.zip]]&lt;br /&gt;
&lt;br /&gt;
==BAF-Server 0.1 mit SrvProc 0.98==&lt;br /&gt;
&lt;br /&gt;
Download (bs_v0_98.zip, 24.577 KB)[[https://bafbal.de/downloads/bs_v0_98.zip]]&lt;br /&gt;
&lt;br /&gt;
==BAF-Server 0.1 mit SrvProc 0.97==&lt;br /&gt;
&lt;br /&gt;
Download (bs_v0_97.zip, 24.572 KB)[[https://bafbal.de/downloads/bs_v0_97.zip]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==BAF-Server 0.1 mit SrvProc 0.96==&lt;br /&gt;
&lt;br /&gt;
Download (bs_v0_96.zip, 24.569 KB)[[https://bafbal.de/downloads/bs_v0_96.zip]]&lt;br /&gt;
&lt;br /&gt;
==BAF-Server 0.1 mit SrvProc 0.95==&lt;br /&gt;
&lt;br /&gt;
Download (bs_v0_95.zip, 24.518 KB)[[https://bafbal.de/downloads/bs_v0_95.zip]]&lt;br /&gt;
&lt;br /&gt;
==BAF-Server 0.1 mit SrvProc 0.9==&lt;br /&gt;
&lt;br /&gt;
Download (bs_v0_9.zip, 24,5 MB)[[https://bafbal.de/downloads/bs_v0_9.zip]]&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Archiv&amp;diff=22530</id>
		<title>Archiv</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Archiv&amp;diff=22530"/>
		<updated>2025-07-13T16:35:40Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===31.12.2023===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 1.00]]&lt;br /&gt;
* Youtube-Video: [https://www.youtube.com/watch?v=tCAL7MmKO6c| Version 1.00 (19:24)]&lt;br /&gt;
&lt;br /&gt;
===23.7.2023===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.99]]&lt;br /&gt;
&lt;br /&gt;
===26.03.2023===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.98]]&lt;br /&gt;
&lt;br /&gt;
===26.02.2023===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.97]]&lt;br /&gt;
* [https://www.youtube.com/watch?v=HKDW09g7ikc| Video Version 0.97 (5:51)]&lt;br /&gt;
&lt;br /&gt;
===29.01.2023===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.96]]&lt;br /&gt;
&lt;br /&gt;
===31.12.2022===&lt;br /&gt;
*[[beispiele_rest_json|Neues Beispiel: Daten von einem REST-Server holen, anzeigen und bearbeiten (längeres Tutorial)]]&lt;br /&gt;
&lt;br /&gt;
===24.12.2022===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.95]]&lt;br /&gt;
&lt;br /&gt;
===03.12.2022===&lt;br /&gt;
&lt;br /&gt;
* Video [https://youtu.be/gdUh9S_KEAQ| BIC ergänzen (10:11)]&lt;br /&gt;
* Video [https://youtu.be/XenPgo0OTn8| Version 0.91 (4:45)]&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.91]]&lt;br /&gt;
&lt;br /&gt;
===27.11.2022===&lt;br /&gt;
&lt;br /&gt;
* Video [https://www.youtube.com/watch?v=95NUxGX6R1k| BAF-Server einrichten (13:01)]&lt;br /&gt;
* [[Versionen_Server| Erste Version: BAF-Server 0.1 / SerProc 0.9]]&lt;br /&gt;
&lt;br /&gt;
===26.11.2022===&lt;br /&gt;
&lt;br /&gt;
* Video [https://www.youtube.com/watch?v=iarhXOJJVuA| Version 0.9 (7:28)]&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.9]]&lt;br /&gt;
&lt;br /&gt;
===25.11.2022===&lt;br /&gt;
&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=6_Ngk-EJmuY| Threads (8:53)]&lt;br /&gt;
&lt;br /&gt;
===19.11.2022===&lt;br /&gt;
&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=u7JVPvnB0es| Dialoge erstellen (15:53)]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=5yXkC2B0jQM| Länderkürzel anlegen (11:32)]&lt;br /&gt;
&lt;br /&gt;
===19.11.2022===&lt;br /&gt;
&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=tUtmq1l11ls| Version 0.8 (13:54)]&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.8]]&lt;br /&gt;
&lt;br /&gt;
===13.11.2022===&lt;br /&gt;
&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=iJxdU6A9NrE| User und Rechte (21:49)]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=c1NYgMhP1F8| User importieren (28:11)]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=PrENFgNIwpY| Testdaten und $RANDOM (16:14)]&lt;br /&gt;
&lt;br /&gt;
===12.11.2022===&lt;br /&gt;
&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=P8aK_vkmlcI| Text (10:51)]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=cWvvcC8QVZo| INI verwenden (4:11)]&lt;br /&gt;
&lt;br /&gt;
===29.10.2022===&lt;br /&gt;
&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=_HGqS9_R_Xc| xsql - ein simples SQL-Tool (21:29)]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=83sqJmoC068| Zusaätzliche Datenbank einbinden (5:35)]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=u-71YXZlcRk| Variable und Values (9.30)]&lt;br /&gt;
&lt;br /&gt;
===23.10.2022===&lt;br /&gt;
&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 0.7]]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=St3fj1WB098| Die Sprache BAL (7:20)]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=R2ceP0UYgoY| PDFs erstellen (8:11)]&lt;br /&gt;
* Video: [https://www.youtube.com/watch?v=RDJBGeG1xsA| BAF-Client 0.7 (3:21)]&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Hauptseite&amp;diff=22529</id>
		<title>Hauptseite</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Hauptseite&amp;diff=22529"/>
		<updated>2025-07-13T16:35:17Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* Aktuelles */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=BAF/BAL=&lt;br /&gt;
&lt;br /&gt;
BAF steht für ''Business Applications Framework''&lt;br /&gt;
&lt;br /&gt;
BAL steht für ''Business Applications Language''&lt;br /&gt;
&lt;br /&gt;
==Aktuelles==&lt;br /&gt;
&lt;br /&gt;
===13.07.2025===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 1.03]]&lt;br /&gt;
&lt;br /&gt;
===25.12.2024===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 1.02]]&lt;br /&gt;
&lt;br /&gt;
===30.06.2024===&lt;br /&gt;
* [[Versionen| Neue Version: BAF-Client 1.01]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Archiv]]&lt;br /&gt;
&lt;br /&gt;
==Was ?==&lt;br /&gt;
&lt;br /&gt;
BAF ist eine Framework zur schnellen Entwicklung von Datenbankanwendungen im Business-Umfeld.&lt;br /&gt;
&lt;br /&gt;
==Warum?==&lt;br /&gt;
&lt;br /&gt;
Kurzfassung: Für schnelle Entwicklung&lt;br /&gt;
&lt;br /&gt;
[[Gruende|Langfassung: Gründe für die Entwiklung von BAF/BAL]]&lt;br /&gt;
&lt;br /&gt;
==Wo ?==&lt;br /&gt;
&lt;br /&gt;
[[Versionen|BAF-Client Download-Seite]]&lt;br /&gt;
&lt;br /&gt;
[[Videos|Videos]]&lt;br /&gt;
&lt;br /&gt;
==Lizenz==&lt;br /&gt;
&lt;br /&gt;
Das Framework steht unter der [[bful|BAF fair use license]], einer unkomplizierten OpenSource-Lizenz.&lt;br /&gt;
&lt;br /&gt;
==BAF Client==&lt;br /&gt;
&lt;br /&gt;
Der BAF-Client ist sowohl IDE als auch Benutzeroberfläche für den Endanwender.&lt;br /&gt;
&lt;br /&gt;
*[[BC_Login|Der Login-Dialog]]&lt;br /&gt;
*[[BC_Programmfenster|Programmfenster]]&lt;br /&gt;
*[[BC_Typisch|typisches Formular]]&lt;br /&gt;
*[[BC_Code_|Code]]&lt;br /&gt;
*[[BC_SGWizard|Code - Simple Grid Wizard]]&lt;br /&gt;
*[[BC_SqlOpen|Code - SQL Open / SQL Open 2]]&lt;br /&gt;
*[[BC_SqlExec|Code - SQL Exec]]&lt;br /&gt;
*[[BC_Tools|Code - Tools]]&lt;br /&gt;
*[[BC_Lists|Code - Lists]]&lt;br /&gt;
*[[BC_Debug|Debug]]&lt;br /&gt;
*[[BC_Migration|Migration]]&lt;br /&gt;
&lt;br /&gt;
==BAF Server==&lt;br /&gt;
&lt;br /&gt;
[[Versionen_Server|BAF-Server Download-Seite]]&lt;br /&gt;
&lt;br /&gt;
[[Videos|Videos]]&lt;br /&gt;
&lt;br /&gt;
==Datenbanken==&lt;br /&gt;
&lt;br /&gt;
*[[BafClientFmIni|Datenbanken einbinden mit der BafClientFM.ini]]&lt;br /&gt;
*[[DbBesonderheiten|Besonderheiten der unterstützten Datenbanksysteme]]&lt;br /&gt;
&lt;br /&gt;
==Sprache und Bibliotheken==&lt;br /&gt;
&lt;br /&gt;
*[[BAL|Die Sprache BAL]]&lt;br /&gt;
*[[Interpreter|Interpreter]]&lt;br /&gt;
*[[Modul VAR neu|Modul VAR]]&lt;br /&gt;
*[[Modul DB|Modul DB]]&lt;br /&gt;
*[[Modul Form|Modul Form]]&lt;br /&gt;
*[[Modul Translation|Modul Translation]]&lt;br /&gt;
*[[Modul Web|Modul Web]]&lt;br /&gt;
*[[Modul XML|Modul XML]]&lt;br /&gt;
*[[Modul JSON|Modul JSON]]&lt;br /&gt;
*[[Modul PDF|Modul PDF]]&lt;br /&gt;
*[[Modul XLS|Modul XLS]]&lt;br /&gt;
*[[beispiele|Beispiele]]&lt;br /&gt;
&lt;br /&gt;
==Die Standard-Module==&lt;br /&gt;
&lt;br /&gt;
Mit den Standard-Modulen werden die Standard-Aufgaben in einer Datenbankanwendung abgedeckt.&lt;br /&gt;
&lt;br /&gt;
*[[xuser|xuser - Benutzerverwaltung]]&lt;br /&gt;
*[[xlookup|xlookup - Nachschlagelisten]]&lt;br /&gt;
*[[xspecial|xspecial - Nachschlagelisten aus SQL-Abfragen]]&lt;br /&gt;
*[[xdevtext|xdevtext - Entwicklertexte]]&lt;br /&gt;
*[[xmenu|xmenu - Das Menü]]&lt;br /&gt;
*[[xtranslation|xtranslation - Übersetzung]]&lt;br /&gt;
*[[xsettings|xsettings - Benutzereinstellungen]]&lt;br /&gt;
*[[xtodo|xtodo - Aufgabenliste]]&lt;br /&gt;
&lt;br /&gt;
==[[Impressum|Impressum]]==&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Versionen&amp;diff=22528</id>
		<title>Versionen</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Versionen&amp;diff=22528"/>
		<updated>2025-07-13T16:33:36Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* Version 1.03 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=BAF-Client Download=&lt;br /&gt;
&lt;br /&gt;
* Einfach die ZIP-Datei entpacken und dann erst mal die beiliegenden Fonts installieren (recht Maustaste, &amp;quot;Installieren&amp;quot;)&lt;br /&gt;
* Den BAF-Client einfach mit der Datei BafCLientFM.exe starten&lt;br /&gt;
* Username und Passwort (admin/admin) kommen aus der Ini-Datei. Vor dem Produktivbetrieb das Passwort dort löschen und in der Userverwaltung abändern.&lt;br /&gt;
&lt;br /&gt;
==Version 1.03==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren sowie wesentliche Parameterergänzungen. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Die Suche kann nun auf die Kommandos in den Favoriten beschränkt werden.&lt;br /&gt;
* Int: $EMPTYVAL(), $NEMPTYVAL()&lt;br /&gt;
* Var: $CONVERT(), $DATECOMP(), $EMPTYVAR(), $NEMPTYVAR()&lt;br /&gt;
* DB: #sql_openval hat nun die Parameter af und de&lt;br /&gt;
* Form: #tree_node hat nun den Parameter iek, $GRD_REGEX(), S-Grid (#sgrd_seg, #sgrd_node, #sgrd_hf, #sgrd_data), #grd_data kennt nun auch q=text&lt;br /&gt;
* Web: #email_init hat nun den Parameter sasl, #email_send hat nun den Parameter fn_list&lt;br /&gt;
* JSON: $JSON_ARRAY_VALUE(), $JSON_LFR()&lt;br /&gt;
* PDF: #pdf_text hat nun den Parameter d&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_03.zip, 25.880 KB)[[https://bafbal.de/downloads/bc3_v1_03.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_03.zip, 26.420 KB)[[https://bafbal.de/downloads/bs_v1_03.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.02==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Var: #file_wait, $BFMT(), $CFMT()&lt;br /&gt;
* Form: #dlg, #dlg_close&lt;br /&gt;
* XML: $XML_VALEX()&lt;br /&gt;
* Code-Dialog: Es wurde die Seite ''Fav'' und die entsprechende Checkbox auf der Seite ''Code'' hinzugefügt. Um dies nutzen zu können, muss die folgende Tabelle existieren:&lt;br /&gt;
&lt;br /&gt;
 create table sys_userfav(&lt;br /&gt;
   name varchar(80) not null,&lt;br /&gt;
   user_user_id varchar(40) not null&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_02.zip, 23.627 KB)[[https://bafbal.de/downloads/bc3_v1_02.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_02.zip, 25.071 KB)[[https://bafbal.de/downloads/bs_v1_02.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.01==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Interpreter: Funktion $INCP() ergänzt (if not command parameter)&lt;br /&gt;
* DB: #sql_upsert2 (gibt es den Datensatz noch nicht, wird er angelegt, haben sich die Daten geändert, werden sie geschrieben)&lt;br /&gt;
* Form: $DLG_YESNO() (Dialog mit Yes/No)&lt;br /&gt;
* Form: #tree_clearnode (Entfernt einen Zweig, damit er neu aufgebaut werden kann)&lt;br /&gt;
* Form: #grd_dub (ermittelt Dubletten in einem Grid)&lt;br /&gt;
* XML: $XML_DATATEXT (ermittelt ein XML in einer Schleife)&lt;br /&gt;
* XML: $XML_LFR (loop first regex)&lt;br /&gt;
* XLS: #xls_load (öffnet eine XLS-Datei)&lt;br /&gt;
* XLS: #xls_looprows (loop über die Zeilen einer XLS-Datei)&lt;br /&gt;
* XLS: $XLS_COUNT() (ermittelt die Anzahl von Sheets, Zeilen oder Zellen)&lt;br /&gt;
* XLS: $XLS_CELL() (Gibt der Wert einer Zelle aus)&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_01.zip, 23.620 KB)[[https://bafbal.de/downloads/bc3_v1_01.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_01.zip, 25.067 KB)[[https://bafbal.de/downloads/bs_v1_01.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.00==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Im Code-Dialog wurde die Seite ''Open SQL'' überarbeitet und auf drei solche Seiten erweitert&lt;br /&gt;
*[[Modul_VAR_neu#.23csv_check|#csv_check]] Prüft eine CSV-Datei&lt;br /&gt;
*[[Modul_VAR_neu#.24CSV_LINE.28.29|$CSV_LINE()]] Gibt eine ganze Zeile einer CSV-Datei zurück &lt;br /&gt;
*[[Modul_VAR_neu#.23tvl_add|#tvl_add]] Addiert einem Wert in einer Text-Value-Liste einen Wert hinzu &lt;br /&gt;
*[[Modul_VAR_neu#.23exit|#exit]] Bricht die Ausführung eines (Sub-)Kommandos ab&lt;br /&gt;
*[[Modul_VAR_neu#.24STROP.28.29|$STROP()]] Verschiedene String-Bearbeitungen wie Trim, Quote oder Unquote&lt;br /&gt;
*[[Modul_Form#.24CCI.28.29|$CCI()]] Ermittelt die zu setzende Zellen-Farbe&lt;br /&gt;
*[[Modul_Form#.23grd_sort|#grd_sort]] Sortiert ein Grid&lt;br /&gt;
*[[Modul_Form#.23grd_pos|#grd_pos]] Ermittelt das erste Vorkommen einer Zeile, deren Zelleninhalte den Kriterien entsprechen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_00.zip, 23.476 KB)[[https://bafbal.de/downloads/bc3_v1_00.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_00.zip, 25.040 KB)[[https://bafbal.de/downloads/bs_v1_00.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.99==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Vereinzelt wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier meist nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
*[[Modul_VAR_neu#.23text_act|#text_act]] Bearbeitet einen Text&lt;br /&gt;
*[[Modul_VAR_neu#.24FILEINFO.28.29|$FILEINFO()]] Liefert Infos zu einer Datei&lt;br /&gt;
*[[Modul_VAR_neu#.23zip_create|#zip_create]] Erzeugt eine ZIP-Datei&lt;br /&gt;
*[[Modul_VAR_neu#.24LEVENSHTEIN.28.29|$LEVENSHTEIN()]] Ermittelt die Levensthein-Distanz (Größe bei einem String-Vergleich)&lt;br /&gt;
*[[Modul_VAR_neu#.24RANDOM.28.29_2|$RANDOM()]] Erzeugt eine Zufalls-Zahl&lt;br /&gt;
* Bei Konsolen-Programmen kann nun auf den Bestätigungsdialog verzichtet werden, siehe [[Modul_Form#.23frm|#frm]]&lt;br /&gt;
* Bei [[Modul_Form#.23tree_sel|#tree_sel]] können nun auch Unterknoten durchsucht werden.&lt;br /&gt;
*[[Modul_Form#.23tree_fillthread|#tree_fillthread]] - Ergänzt den Baum in einem Thread (meist, um Daten aus einer Datenbank zu ergänzen)&lt;br /&gt;
*[[Modul_Form#.23vl_thread|#vl_thread]] Ergänzt die Daten in einem VL-Segment (meist, um Daten aus einer Datenbank zu ergänzen)&lt;br /&gt;
*[[Modul_Form#.23xgrd_calc|#xgrd_calc]] Berechnet einen Wert in einem XGrid-Segment&lt;br /&gt;
*[[Modul_Form#.24XGRD_CALC|$XGRD_CALC()]] Berechnet einen Wert in einem XGrid-Segment, aber als Funktion&lt;br /&gt;
*[[Modul_Form#XXGrid-Segmente|XX-Grid-Segmente]] (mehrere Prozeduren)&lt;br /&gt;
*[[Modul_XML#.23xml_gav|#xml_gav]] Holt die Array-Werte aus einem XML&lt;br /&gt;
* In [[Modul_JSON#.24JSON_DATA|$JSON_DATA()]] können nun auch Namen ausgelesen werden&lt;br /&gt;
* In [[Modul_XLS#.23xls_cell|#xls_cell]] kann nun auch die vertikale Ausrichtung in einer Zelle spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_99.zip, 23.345 KB)[[https://bafbal.de/downloads/bc3_v0_99.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_99.zip, 24.935 KB)[[https://bafbal.de/downloads/bs_v0_99.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.98==&lt;br /&gt;
&lt;br /&gt;
* Im GridWizard funktioniert nun der Hint der Spaltenüberschriften&lt;br /&gt;
* Links funktionieren nun im VL-Segment&lt;br /&gt;
* #tree_sel erweitert&lt;br /&gt;
* #sql_opentvl&lt;br /&gt;
* #sql_line &lt;br /&gt;
* Lookups, Specials und Kommandos cachen nun&lt;br /&gt;
* XGrid und XXGrid stretchen nun&lt;br /&gt;
* grd_thread y=gridlist&lt;br /&gt;
* #grd_seg und #vl_seg - whs&lt;br /&gt;
* Werte werden nun nur vom Grid in den Baum zurück geschrieben, wenn sie tatsächlich geändert wurden&lt;br /&gt;
* #tree_fillthread&lt;br /&gt;
* Prozessabbruch beim Fortschrittsdialog wird nun resettet&lt;br /&gt;
* cmd no_crlf&lt;br /&gt;
* Verbesserung von dateMin und dateSek&lt;br /&gt;
* $INCP&lt;br /&gt;
* Pos1 und End im Grid&lt;br /&gt;
* Wizzard für csv und xlsx&lt;br /&gt;
* Beim Debug-Fenster Select werden nun nicht mehr die Selects angezeigt, die Commands holen&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_98.zip, 20.246 KB)[[https://bafbal.de/downloads/bc3_v0_98.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_98.zip, 24.577 KB)[[https://bafbal.de/downloads/bs_v0_98.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.97==&lt;br /&gt;
&lt;br /&gt;
* #grd_ac ergänzt&lt;br /&gt;
* $INCLUDE() ergänzt&lt;br /&gt;
* $ONLYNUM() ergänzt&lt;br /&gt;
* Fehler beim Parsen von XML behoben&lt;br /&gt;
* UserIni wird nun beim ServerProzess beim Ende gespeichert&lt;br /&gt;
* Cursor beim Login-Dialog&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_97.zip, 20.236 KB)[[https://bafbal.de/downloads/bc3_v0_97.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_97.zip, 24.572 KB)[[https://bafbal.de/downloads/bs_v0_97.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.96==&lt;br /&gt;
&lt;br /&gt;
* TBafTree Scrollbar bei langen Listen gleich&lt;br /&gt;
* #ftp_connect Parameter isc&lt;br /&gt;
* #email_init Parameter port, isc und to&lt;br /&gt;
* Menu scrollt nun richtig&lt;br /&gt;
* PDF Grid (#pdf_gdef, #pdf_grow, #pdf_gend)&lt;br /&gt;
* #upsert, y=c und n&lt;br /&gt;
* Performance Log&lt;br /&gt;
* Debug, Request and Response&lt;br /&gt;
* History Statement bei anderen DB&lt;br /&gt;
* PG, AlterTable, AlterHistory, Leerzeilen in CREATE TABLE kein Problem mehr bei Funktionen&lt;br /&gt;
* Vorbelegung Username aus INI beim Login-Dialog&lt;br /&gt;
* Baum kann mit Tasten gesteuert werden&lt;br /&gt;
* Page, kleinere Bugs behoben, TAB nun auch bei VL-Segment&lt;br /&gt;
* $ISDATE ergänzt&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_96.zip, 20.232 KB)[[https://bafbal.de/downloads/bc3_v0_96.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_96.zip, 24.569 KB)[[https://bafbal.de/downloads/bs_v0_96.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.95==&lt;br /&gt;
&lt;br /&gt;
* REST und JSON&lt;br /&gt;
* Bilder&lt;br /&gt;
* ein wenig XML&lt;br /&gt;
* tvl bei Nachschlagelisten&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_95.zip, 24.541 KB)[[https://bafbal.de/downloads/bc3_v0_95.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_95.zip, 24.518 KB)[[https://bafbal.de/downloads/bs_v0_95.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.91==&lt;br /&gt;
&lt;br /&gt;
* TBafTree&lt;br /&gt;
* uServer und uServer2&lt;br /&gt;
* Parameter isc bei #http_request&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_91.zip, 19,7 MB)[[https://bafbal.de/downloads/bc3_v0_91.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.9==&lt;br /&gt;
&lt;br /&gt;
* Werden Texte in Nachschlagelisten geladen, werden nun Funktionen (z.B. Übersetzungen) ersetzt&lt;br /&gt;
* Werden nach einer Änderung im Tree Werte in den Baum zurückgeschrieben, wird nicht nur - wie bisher - c1 und c2 geschrieben, sondern auch k. Zudem werden nun Funktionen ersetzt&lt;br /&gt;
* Wurde bei VL-Wizard nachgebessert&lt;br /&gt;
* lookuptext&lt;br /&gt;
* Die Listen im Code-Dialog wurden erweitert&lt;br /&gt;
* Funktion $BASE64&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_9.zip, 19,7 MB)[[https://bafbal.de/downloads/bc3_v0_9.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.8==&lt;br /&gt;
&lt;br /&gt;
* Grid- und VL-Wizard&lt;br /&gt;
* SQL-Creator&lt;br /&gt;
* Dialoge&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_8.zip, 19,87 MB)[[https://bafbal.de/downloads/bc3_v0_8.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.7==&lt;br /&gt;
&lt;br /&gt;
Download nicht mehr verfügbar&lt;br /&gt;
&lt;br /&gt;
==Version 0.3 &amp;quot;Public Preview&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Hinweise:&lt;br /&gt;
&lt;br /&gt;
Download (copy_303.zip, 9,39 MB)[[https://bafbal.de/downloads/copy_303.zip]]&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Versionen&amp;diff=22527</id>
		<title>Versionen</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Versionen&amp;diff=22527"/>
		<updated>2025-07-13T16:13:34Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* BAF-Client Download */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=BAF-Client Download=&lt;br /&gt;
&lt;br /&gt;
* Einfach die ZIP-Datei entpacken und dann erst mal die beiliegenden Fonts installieren (recht Maustaste, &amp;quot;Installieren&amp;quot;)&lt;br /&gt;
* Den BAF-Client einfach mit der Datei BafCLientFM.exe starten&lt;br /&gt;
* Username und Passwort (admin/admin) kommen aus der Ini-Datei. Vor dem Produktivbetrieb das Passwort dort löschen und in der Userverwaltung abändern.&lt;br /&gt;
&lt;br /&gt;
==Version 1.03==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
*&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_03.zip, 25.880 KB)[[https://bafbal.de/downloads/bc3_v1_03.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_03.zip, 26.420 KB)[[https://bafbal.de/downloads/bs_v1_03.zip]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Version 1.02==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Var: #file_wait, $BFMT(), $CFMT()&lt;br /&gt;
* Form: #dlg, #dlg_close&lt;br /&gt;
* XML: $XML_VALEX()&lt;br /&gt;
* Code-Dialog: Es wurde die Seite ''Fav'' und die entsprechende Checkbox auf der Seite ''Code'' hinzugefügt. Um dies nutzen zu können, muss die folgende Tabelle existieren:&lt;br /&gt;
&lt;br /&gt;
 create table sys_userfav(&lt;br /&gt;
   name varchar(80) not null,&lt;br /&gt;
   user_user_id varchar(40) not null&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_02.zip, 23.627 KB)[[https://bafbal.de/downloads/bc3_v1_02.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_02.zip, 25.071 KB)[[https://bafbal.de/downloads/bs_v1_02.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.01==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Interpreter: Funktion $INCP() ergänzt (if not command parameter)&lt;br /&gt;
* DB: #sql_upsert2 (gibt es den Datensatz noch nicht, wird er angelegt, haben sich die Daten geändert, werden sie geschrieben)&lt;br /&gt;
* Form: $DLG_YESNO() (Dialog mit Yes/No)&lt;br /&gt;
* Form: #tree_clearnode (Entfernt einen Zweig, damit er neu aufgebaut werden kann)&lt;br /&gt;
* Form: #grd_dub (ermittelt Dubletten in einem Grid)&lt;br /&gt;
* XML: $XML_DATATEXT (ermittelt ein XML in einer Schleife)&lt;br /&gt;
* XML: $XML_LFR (loop first regex)&lt;br /&gt;
* XLS: #xls_load (öffnet eine XLS-Datei)&lt;br /&gt;
* XLS: #xls_looprows (loop über die Zeilen einer XLS-Datei)&lt;br /&gt;
* XLS: $XLS_COUNT() (ermittelt die Anzahl von Sheets, Zeilen oder Zellen)&lt;br /&gt;
* XLS: $XLS_CELL() (Gibt der Wert einer Zelle aus)&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_01.zip, 23.620 KB)[[https://bafbal.de/downloads/bc3_v1_01.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_01.zip, 25.067 KB)[[https://bafbal.de/downloads/bs_v1_01.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 1.00==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Es wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
* Im Code-Dialog wurde die Seite ''Open SQL'' überarbeitet und auf drei solche Seiten erweitert&lt;br /&gt;
*[[Modul_VAR_neu#.23csv_check|#csv_check]] Prüft eine CSV-Datei&lt;br /&gt;
*[[Modul_VAR_neu#.24CSV_LINE.28.29|$CSV_LINE()]] Gibt eine ganze Zeile einer CSV-Datei zurück &lt;br /&gt;
*[[Modul_VAR_neu#.23tvl_add|#tvl_add]] Addiert einem Wert in einer Text-Value-Liste einen Wert hinzu &lt;br /&gt;
*[[Modul_VAR_neu#.23exit|#exit]] Bricht die Ausführung eines (Sub-)Kommandos ab&lt;br /&gt;
*[[Modul_VAR_neu#.24STROP.28.29|$STROP()]] Verschiedene String-Bearbeitungen wie Trim, Quote oder Unquote&lt;br /&gt;
*[[Modul_Form#.24CCI.28.29|$CCI()]] Ermittelt die zu setzende Zellen-Farbe&lt;br /&gt;
*[[Modul_Form#.23grd_sort|#grd_sort]] Sortiert ein Grid&lt;br /&gt;
*[[Modul_Form#.23grd_pos|#grd_pos]] Ermittelt das erste Vorkommen einer Zeile, deren Zelleninhalte den Kriterien entsprechen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v1_00.zip, 23.476 KB)[[https://bafbal.de/downloads/bc3_v1_00.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v1_00.zip, 25.040 KB)[[https://bafbal.de/downloads/bs_v1_00.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.99==&lt;br /&gt;
&lt;br /&gt;
(In der Liste der Neuerungen sind nur ergänzte Funktionen und Prozeduren. Vereinzelt wurden auch bei bestehenden Prozeduren und Funktionen Parameter ergänzt, die hier meist nicht aufgeführt sind)&lt;br /&gt;
&lt;br /&gt;
*[[Modul_VAR_neu#.23text_act|#text_act]] Bearbeitet einen Text&lt;br /&gt;
*[[Modul_VAR_neu#.24FILEINFO.28.29|$FILEINFO()]] Liefert Infos zu einer Datei&lt;br /&gt;
*[[Modul_VAR_neu#.23zip_create|#zip_create]] Erzeugt eine ZIP-Datei&lt;br /&gt;
*[[Modul_VAR_neu#.24LEVENSHTEIN.28.29|$LEVENSHTEIN()]] Ermittelt die Levensthein-Distanz (Größe bei einem String-Vergleich)&lt;br /&gt;
*[[Modul_VAR_neu#.24RANDOM.28.29_2|$RANDOM()]] Erzeugt eine Zufalls-Zahl&lt;br /&gt;
* Bei Konsolen-Programmen kann nun auf den Bestätigungsdialog verzichtet werden, siehe [[Modul_Form#.23frm|#frm]]&lt;br /&gt;
* Bei [[Modul_Form#.23tree_sel|#tree_sel]] können nun auch Unterknoten durchsucht werden.&lt;br /&gt;
*[[Modul_Form#.23tree_fillthread|#tree_fillthread]] - Ergänzt den Baum in einem Thread (meist, um Daten aus einer Datenbank zu ergänzen)&lt;br /&gt;
*[[Modul_Form#.23vl_thread|#vl_thread]] Ergänzt die Daten in einem VL-Segment (meist, um Daten aus einer Datenbank zu ergänzen)&lt;br /&gt;
*[[Modul_Form#.23xgrd_calc|#xgrd_calc]] Berechnet einen Wert in einem XGrid-Segment&lt;br /&gt;
*[[Modul_Form#.24XGRD_CALC|$XGRD_CALC()]] Berechnet einen Wert in einem XGrid-Segment, aber als Funktion&lt;br /&gt;
*[[Modul_Form#XXGrid-Segmente|XX-Grid-Segmente]] (mehrere Prozeduren)&lt;br /&gt;
*[[Modul_XML#.23xml_gav|#xml_gav]] Holt die Array-Werte aus einem XML&lt;br /&gt;
* In [[Modul_JSON#.24JSON_DATA|$JSON_DATA()]] können nun auch Namen ausgelesen werden&lt;br /&gt;
* In [[Modul_XLS#.23xls_cell|#xls_cell]] kann nun auch die vertikale Ausrichtung in einer Zelle spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_99.zip, 23.345 KB)[[https://bafbal.de/downloads/bc3_v0_99.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_99.zip, 24.935 KB)[[https://bafbal.de/downloads/bs_v0_99.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.98==&lt;br /&gt;
&lt;br /&gt;
* Im GridWizard funktioniert nun der Hint der Spaltenüberschriften&lt;br /&gt;
* Links funktionieren nun im VL-Segment&lt;br /&gt;
* #tree_sel erweitert&lt;br /&gt;
* #sql_opentvl&lt;br /&gt;
* #sql_line &lt;br /&gt;
* Lookups, Specials und Kommandos cachen nun&lt;br /&gt;
* XGrid und XXGrid stretchen nun&lt;br /&gt;
* grd_thread y=gridlist&lt;br /&gt;
* #grd_seg und #vl_seg - whs&lt;br /&gt;
* Werte werden nun nur vom Grid in den Baum zurück geschrieben, wenn sie tatsächlich geändert wurden&lt;br /&gt;
* #tree_fillthread&lt;br /&gt;
* Prozessabbruch beim Fortschrittsdialog wird nun resettet&lt;br /&gt;
* cmd no_crlf&lt;br /&gt;
* Verbesserung von dateMin und dateSek&lt;br /&gt;
* $INCP&lt;br /&gt;
* Pos1 und End im Grid&lt;br /&gt;
* Wizzard für csv und xlsx&lt;br /&gt;
* Beim Debug-Fenster Select werden nun nicht mehr die Selects angezeigt, die Commands holen&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_98.zip, 20.246 KB)[[https://bafbal.de/downloads/bc3_v0_98.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_98.zip, 24.577 KB)[[https://bafbal.de/downloads/bs_v0_98.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.97==&lt;br /&gt;
&lt;br /&gt;
* #grd_ac ergänzt&lt;br /&gt;
* $INCLUDE() ergänzt&lt;br /&gt;
* $ONLYNUM() ergänzt&lt;br /&gt;
* Fehler beim Parsen von XML behoben&lt;br /&gt;
* UserIni wird nun beim ServerProzess beim Ende gespeichert&lt;br /&gt;
* Cursor beim Login-Dialog&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_97.zip, 20.236 KB)[[https://bafbal.de/downloads/bc3_v0_97.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_97.zip, 24.572 KB)[[https://bafbal.de/downloads/bs_v0_97.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.96==&lt;br /&gt;
&lt;br /&gt;
* TBafTree Scrollbar bei langen Listen gleich&lt;br /&gt;
* #ftp_connect Parameter isc&lt;br /&gt;
* #email_init Parameter port, isc und to&lt;br /&gt;
* Menu scrollt nun richtig&lt;br /&gt;
* PDF Grid (#pdf_gdef, #pdf_grow, #pdf_gend)&lt;br /&gt;
* #upsert, y=c und n&lt;br /&gt;
* Performance Log&lt;br /&gt;
* Debug, Request and Response&lt;br /&gt;
* History Statement bei anderen DB&lt;br /&gt;
* PG, AlterTable, AlterHistory, Leerzeilen in CREATE TABLE kein Problem mehr bei Funktionen&lt;br /&gt;
* Vorbelegung Username aus INI beim Login-Dialog&lt;br /&gt;
* Baum kann mit Tasten gesteuert werden&lt;br /&gt;
* Page, kleinere Bugs behoben, TAB nun auch bei VL-Segment&lt;br /&gt;
* $ISDATE ergänzt&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_96.zip, 20.232 KB)[[https://bafbal.de/downloads/bc3_v0_96.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_96.zip, 24.569 KB)[[https://bafbal.de/downloads/bs_v0_96.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.95==&lt;br /&gt;
&lt;br /&gt;
* REST und JSON&lt;br /&gt;
* Bilder&lt;br /&gt;
* ein wenig XML&lt;br /&gt;
* tvl bei Nachschlagelisten&lt;br /&gt;
&lt;br /&gt;
Download Client (bc3_v0_95.zip, 24.541 KB)[[https://bafbal.de/downloads/bc3_v0_95.zip]]&lt;br /&gt;
&lt;br /&gt;
Download Server (bs_v0_95.zip, 24.518 KB)[[https://bafbal.de/downloads/bs_v0_95.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.91==&lt;br /&gt;
&lt;br /&gt;
* TBafTree&lt;br /&gt;
* uServer und uServer2&lt;br /&gt;
* Parameter isc bei #http_request&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_91.zip, 19,7 MB)[[https://bafbal.de/downloads/bc3_v0_91.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.9==&lt;br /&gt;
&lt;br /&gt;
* Werden Texte in Nachschlagelisten geladen, werden nun Funktionen (z.B. Übersetzungen) ersetzt&lt;br /&gt;
* Werden nach einer Änderung im Tree Werte in den Baum zurückgeschrieben, wird nicht nur - wie bisher - c1 und c2 geschrieben, sondern auch k. Zudem werden nun Funktionen ersetzt&lt;br /&gt;
* Wurde bei VL-Wizard nachgebessert&lt;br /&gt;
* lookuptext&lt;br /&gt;
* Die Listen im Code-Dialog wurden erweitert&lt;br /&gt;
* Funktion $BASE64&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_9.zip, 19,7 MB)[[https://bafbal.de/downloads/bc3_v0_9.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.8==&lt;br /&gt;
&lt;br /&gt;
* Grid- und VL-Wizard&lt;br /&gt;
* SQL-Creator&lt;br /&gt;
* Dialoge&lt;br /&gt;
&lt;br /&gt;
Download (bc3_v0_8.zip, 19,87 MB)[[https://bafbal.de/downloads/bc3_v0_8.zip]]&lt;br /&gt;
&lt;br /&gt;
==Version 0.7==&lt;br /&gt;
&lt;br /&gt;
Download nicht mehr verfügbar&lt;br /&gt;
&lt;br /&gt;
==Version 0.3 &amp;quot;Public Preview&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Hinweise:&lt;br /&gt;
&lt;br /&gt;
Download (copy_303.zip, 9,39 MB)[[https://bafbal.de/downloads/copy_303.zip]]&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22526</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22526"/>
		<updated>2025-07-08T06:42:04Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #grd_data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, aus dem die Daten bei q=text bezogen werden; default 1, Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** text - die Daten werden aus dem mit dem Parameter n spezifizierten Text bezogen. Mögliche Werte für den Parameter f sind ''text'' (ganze Zeile), ''key'' (vor dem Gleichheitszeichen) und ''value'' (nach dem Gleichheitszeichen)&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$GRD_REGEX==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_REGEX prüft ein Grid-Segment die die Einhaltung eines Regex-Staements in einer bestimmten Spalte. Eignet sich insbesondere für #page_check, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Regex-Statement&lt;br /&gt;
# Optionen&lt;br /&gt;
## e (&amp;quot;allow empty&amp;quot;) - $GRD_REGEX gibt auch Y zurück, wenn der Zellenwert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Aktionscode entspricht nicht den Formatvorgaben&amp;quot;   chk=$GRD_REGEX(reisen,aktionscode,all,[A-Z]{3}\d{4},e)&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Web&amp;diff=22525</id>
		<title>Modul Web</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Web&amp;diff=22525"/>
		<updated>2025-07-07T13:38:59Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #email_send */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E-Mail=&lt;br /&gt;
&lt;br /&gt;
Das BAF-Framework kann E-Mails (über einen Mailserver) versenden, auch mit Anhängen, auch mit TLS.&lt;br /&gt;
&lt;br /&gt;
Siehe Beispiel [[beispiele_email|E-Mail versenden]]&lt;br /&gt;
&lt;br /&gt;
==#email_init==&lt;br /&gt;
&lt;br /&gt;
Setzt die Parameter zur Verbindung mit dem Mail-Server.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* at - AuthenticationType, Default ist default&lt;br /&gt;
** default&lt;br /&gt;
** none&lt;br /&gt;
** saslmechanism&lt;br /&gt;
* host - Hostname des Mailservers; Funktionen werden ersetzt.&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf Mail-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* port - Port der Verbindung; Funktionen werden ersetzt, default ist der nach tls voreingestellte Port&lt;br /&gt;
* pw (&amp;quot;PassWord&amp;quot;) - Password des Users auf dem Mailserver; Funktionen werden ersetzt.&lt;br /&gt;
* pwc (&amp;quot;PassWordCrypted&amp;quot;) - Wenn Y, dann ist das Passwort mit der Verschlüsselungsfunktion auf der Seite Tools des Code-Dialogs verschlüsselt. Hinweis: Mit dieser Verschlüsselung verhindert man lediglich, dass das Passwort direkt aus dem Code ausgelesen werden kann. Wird der BAF-Client mit dem Delphi-Debugger ausgeführt, lässt sich leicht an die betreffende Stelle ein Breakpoint setzen und das Passwort dann im Klartext auslesen (dieselbe Unit uBafCrypt vorausgesetzt).&lt;br /&gt;
* sasl - Wenn Y, wird der SASL-Mechanismus zur Authentifizierung genutzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* tls - Transport Layer Security; default itls&lt;br /&gt;
** aetls - Allow Explicit TLS&lt;br /&gt;
** dtls - Disable TLS&lt;br /&gt;
** itls - Implicit TLS&lt;br /&gt;
** retls - Require Explicit TLS&lt;br /&gt;
* to - TimeOut in Sekunden, Funktionen werden ersetzt, default 15&lt;br /&gt;
* usr (&amp;quot;user&amp;quot;) - User auf dem Mailserver; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #email_init   host=mailhost.my   usr=myusername   pw=mypassword&lt;br /&gt;
 #email_init   host=mailhost.my   usr=myusername   pwc=Y   pw=333w6t7wqDClip4eB02wrE=&lt;br /&gt;
&lt;br /&gt;
siehe auch [[beispiele_email|E-Mail versenden]]&lt;br /&gt;
&lt;br /&gt;
==#email_send==&lt;br /&gt;
&lt;br /&gt;
Versendet eine E-Mail.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* bcc (&amp;quot;blind carbon copy&amp;quot;) - E-Mail-Adresse(n), die als zusätzliche verdeckte Empfänger eingetragen wird; Funktionen werden ersetzt.&lt;br /&gt;
* cc (&amp;quot;carbon copy&amp;quot;) - E-Mail-Adresse(n), die als zusätzliche Empfänger eingetragen wird; Funktionen werden ersetzt.&lt;br /&gt;
* ccs (&amp;quot;content charset&amp;quot;) - Zeichensatz, zum Beispiel us-ascii, utf-8 oder utf-16; default ist us-ascii; Funktionen werden ersetzt; bei utf-8 und utf-16 sollte cte=base64 verwendet werden&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Anhänge&lt;br /&gt;
* cte (&amp;quot;content transfer encoding&amp;quot;) - Übertragungsencoding (7bit, 8bit, binary, base64, binhex40, quoted-printable, xxe, uue); Funktionen werden ersetzt&lt;br /&gt;
* fn1, fn2... (&amp;quot;FileName&amp;quot;) - Dateinamen der Dateien, die als Anhang mitgeschickt werden sollen.&lt;br /&gt;
* fn_list (&amp;quot;Filename List&amp;quot;) - Nummer des Textes, der als Liste alle Dateinamen auflistet, welche der E-Mail angehängt werden sollen. Wenn fn_list verwendet wird (also eine Nummer größer 0 enthält), dann werden die Parameter fn1, fn2... ignoriert. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* from - E-Mail-Adresse, die als Absender eingetragen wird; Funktionen werden ersetzt.&lt;br /&gt;
* headers2clipboard - Wenn Y, werden direkt vor dem Versand die Headers in die Zwischenanblage geschrieben; kann zum debuggen helfen. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* reply - E-Mail-Adresse(n), die als Antwort-Adresse eingetragen wird; Funktionen werden ersetzt.&lt;br /&gt;
* subject - Betreff der E-Mail&lt;br /&gt;
* text - Text des Mail-Bodys; Funktionen werden ersetzt.&lt;br /&gt;
* to - E-Mail-Adresse(n), die als Empfänger eingetragen wird; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Sollen bei einem Parameter mehrere E-Mail-Adressen angegeben werden, so sind diese durch Semikola zu trennen, siehe Beispiel (to).&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #email_send   from=test@host.my   to=info@adr1.de;info@adr3.de   bcc=info@adr2.de   subject=Testmail   text=$TEXT(1)   ccs=utf-16   cte=base64&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
siehe auch [[beispiele_email|E-Mail versenden]]&lt;br /&gt;
&lt;br /&gt;
==#email_disconnect==&lt;br /&gt;
&lt;br /&gt;
Trennt die Verbindung zum Mailserver. Sollte nach dem Versenden der E-Mail (beim Versenden mehrerer E-Mails nach dem Versenden der letzten E-Mail) aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe [[beispiele_email|E-Mail versenden]]&lt;br /&gt;
&lt;br /&gt;
=FTP / SFTP=&lt;br /&gt;
&lt;br /&gt;
Die Befehle für die Verbindung zu FTP- und SFTP-Server gleichen sich weitgehend, so dass sie gemeinsam besprochen werden.&lt;br /&gt;
&lt;br /&gt;
==#ftp_connect/#sftp_connect==&lt;br /&gt;
&lt;br /&gt;
Stellt die Verbindung zu einem FTP-Server her.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* host - Hostname des Servers; Funktionen werden ersetzt.&lt;br /&gt;
* pw (&amp;quot;PassWord&amp;quot;) - Password des Users auf dem Server; Funktionen werden ersetzt.&lt;br /&gt;
* pwc (&amp;quot;PassWordCrypted&amp;quot;) - Wenn Y, dann ist das Passwort mit der Verschlüsselungsfunktion auf der Seite Tools des Code-Dialogs verschlüsselt. Hinweis: Mit dieser Verschlüsselung verhindert man lediglich, dass das Passwort direkt aus dem Code ausgelesen werden kann. Wird der BAF-Client mit dem Delphi-Debugger ausgeführt, lässt sich leicht an die betreffende Stelle ein Breakpoint setzen und das Passwort dann im Klartext auslesen (dieselbe Unit uBafCrypt vorausgesetzt).&lt;br /&gt;
* prt (&amp;quot;Port&amp;quot;) - Funktionen werden ersetzt. Bei #ftp_connect default 21, bei #sftp_connect default 22&lt;br /&gt;
* to (&amp;quot;timeout&amp;quot;) - Zeit in Sekunden, die auf eine Antwort des Servers gewartet wird; default 15, Funktionen werden ersetzt&lt;br /&gt;
* usr (&amp;quot;user&amp;quot;) - User auf dem Server; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter nur ftp_connect'''&lt;br /&gt;
* crpt (&amp;quot;crypt&amp;quot;) - Wenn Y, wird der Datenkanal verschlüssel; default N, Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf FTP-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* up (&amp;quot;use passive&amp;quot;) - Wenn Y, wird der Passiv-Modus genutzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - TLS-Modus; Funktionen werden ersetzt; default allow&lt;br /&gt;
** allow&lt;br /&gt;
** disable&lt;br /&gt;
** implicit&lt;br /&gt;
** require&lt;br /&gt;
&lt;br /&gt;
'''Parameter nur sftp_connect'''&lt;br /&gt;
* av (&amp;quot;Always validate&amp;quot;) - Wenn Y, wird der Server key immer validiert; Funktionen werden ersetzt; Default N&lt;br /&gt;
* kea (&amp;quot;KeyExchangeAlgorithms&amp;quot;) - Liste der Algorithmen, die für einen Schlüsseltausch verwendet werden, getrennt jeweils durch ein Komma. Default standard, Funktionen werden ersetzt. Es gibt zusätzlich standard und all.&lt;br /&gt;
** standard: curve25519-sha256,curve25519-sha256@libssh.org,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256&lt;br /&gt;
** all: zusätzlich zu standard diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1 - wird benötigt, wenn der Server völlig veraltete Algorithmen einsetzt.&lt;br /&gt;
* private - Name des privaten Schlüssels bei der Authentifizierungsmethode pk&lt;br /&gt;
* y - Authentifizierungsmethode; default pw&lt;br /&gt;
** pk - Private key&lt;br /&gt;
** pw - Passwort&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #ftp_connect   host=w0012345.kasserver.com   usr=w0012345   pw=cWLS12345NhVEcll&lt;br /&gt;
 #sftp_connect   host=w0012345.kasserver.com   usr=w0012345   pw=cWLS12345NhVEcll&lt;br /&gt;
&lt;br /&gt;
==#ftp_disconnect/#sftp_disconnect==&lt;br /&gt;
&lt;br /&gt;
Trennt die Verbindung zum FTP-Server. Sollte dann als letzte Prozedur aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #ftp_connect   host=w0012345.kasserver.com   usr=w0012345   pw=cWLS12345NhVEcll&lt;br /&gt;
 #ftp_upload   src=c:\temp\test.csv   dst=test.csv&lt;br /&gt;
 #ftp_disconnect&lt;br /&gt;
 &lt;br /&gt;
 #sftp_connect   host=w0012345.kasserver.com   usr=w0012345   pw=cWLS12345NhVEcll&lt;br /&gt;
 #sftp_upload   src=c:\temp\test.csv   dst=test.csv&lt;br /&gt;
 #sftp_disconnect&lt;br /&gt;
&lt;br /&gt;
==#ftp_download/#sftp_download==&lt;br /&gt;
&lt;br /&gt;
Lädt eine Datei vom Server herunter&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* dst (&amp;quot;destination&amp;quot;) - Dateiname auf dem lokalen Rechner; Funktionen werden ersetzt&lt;br /&gt;
* ie (&amp;quot;is empty&amp;quot;) - Wenn Y, dann wird die Datei nur auf den lokalen Rechner herunter geladen, wenn sie dort noch nicht vorhanden ist&lt;br /&gt;
* src (&amp;quot;source&amp;quot;) - Dateiname auf dem Server; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ftp_connect   host=w0012345.kasserver.com   usr=w0012345   pw=cWLS12345NhVEcll&lt;br /&gt;
 #ftp_download   src=test.pdf   dst=c:\temp\hallo.pdf&lt;br /&gt;
 #ftp_disconnect&lt;br /&gt;
&lt;br /&gt;
==#ftp_upload/#sftp_upload==&lt;br /&gt;
&lt;br /&gt;
Lädt eine Datei auf den Server hoch&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* dst (&amp;quot;destination&amp;quot;) - Dateiname auf dem Server; Funktionen werden ersetzt&lt;br /&gt;
* ie (&amp;quot;is empty&amp;quot;) - Wenn Y, dann wird die Datei nur auf den Server hoch geladen, wenn sie dort noch nicht vorhanden ist&lt;br /&gt;
* src (&amp;quot;source&amp;quot;) - Dateiname auf dem lokalen Rechner; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ftp_upload   src=c:\temp\test.csv   dst=test.csv&lt;br /&gt;
&lt;br /&gt;
==#ftp_rename/#sftp_rename==&lt;br /&gt;
&lt;br /&gt;
Benennt eine Datei auf dem Server um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* dest (&amp;quot;destination&amp;quot;) - Neuer Name der Datei&lt;br /&gt;
* src (&amp;quot;source&amp;quot;) - Bestehender Name der Datei&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ftp_rename   src=test.csv   dst=hallo.csv&lt;br /&gt;
&lt;br /&gt;
==#ftp_delete/#sftp_delete==&lt;br /&gt;
&lt;br /&gt;
Löscht eine Datei auf dem Server&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, die gelöscht werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ftp_delete   fn=hallo.csv&lt;br /&gt;
&lt;br /&gt;
==#ftp_mkdir/#sftp_mkdir==&lt;br /&gt;
&lt;br /&gt;
Legt ein Verzeichnis auf dem Server an (&amp;quot;make directory&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des neuen Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ftp_mkdir   n=testdir&lt;br /&gt;
&lt;br /&gt;
==#ftp_remdir/#sftp_remdir==&lt;br /&gt;
&lt;br /&gt;
Entfernt ein Verzeichnis auf dem Server (&amp;quot;remove directory&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;Name&amp;quot;) - Name des Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ftp_remdir   n=testdir&lt;br /&gt;
&lt;br /&gt;
==#ftp_chgdir==&lt;br /&gt;
&lt;br /&gt;
Ändert das aktuelle Verzeichnis (&amp;quot;change directory&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Hinweis: Diese Prozedur ist für SFTP nicht verfügbar.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des neuen Verzeichnisses&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ftp_chgdir   n=testdir&lt;br /&gt;
&lt;br /&gt;
==$FTP_SIZE()/$SFTP_SIZE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Größe einer Datei auf dem Server in Bytes.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Datei&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $FTP_SIZE(test.pdf) Bytes&lt;br /&gt;
&lt;br /&gt;
==$FTP_LIST() /$SFTP_LIST() ==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine Liste von Dateien im aktuellen Verzeichnis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Pfad-Angabe; kann sich auf Verzeichnisse beziehen, jedoch auch auf die Dateinamen (z.B. *.pdf) &lt;br /&gt;
# Wenn ''det'' oder ''details'', dann wird eine Liste mit erweiterten Datei-Informationen (Größe, UNIX-mode,...) geliefert.&lt;br /&gt;
&lt;br /&gt;
Bitte beachten Sie, dass bei $FTP_LIST() derzeit nur Verzeichnis-Namen im Pfad zulässig sind, sofern erweiterte Datei-Informationen angefordert werden.&lt;br /&gt;
&lt;br /&gt;
'''Ausgabeformate'''&lt;br /&gt;
&lt;br /&gt;
Bitte beachten Sie, dass sich die Ausgabeformate von $FTP_LIST() und $SFTP_LIST() unterscheiden:&lt;br /&gt;
&lt;br /&gt;
Beispiel $FTP_LIST()&lt;br /&gt;
 .&lt;br /&gt;
 ..&lt;br /&gt;
 test.csv&lt;br /&gt;
 XL2KeyServer.exe&lt;br /&gt;
&lt;br /&gt;
Beispiel $SFTP_LIST()&lt;br /&gt;
 test.csv&lt;br /&gt;
 XL2KeyServer.exe&lt;br /&gt;
&lt;br /&gt;
Beispiel $FTP_LIST(,det) &lt;br /&gt;
 -r-xr-xrwx   1 owner    group              39 Jan 22 08:51      test.csv&lt;br /&gt;
 -r-xr-xrwx   1 owner    group         3757056 Jan 21 19:33      XL2KeyServer.exe&lt;br /&gt;
&lt;br /&gt;
Beispiel $SFTP_LIST(,det) &lt;br /&gt;
 -rw-rw-rw   1     root     root        39 Jan 22 08:51 test.csv&lt;br /&gt;
 -rw-rw-rw   1     root     root   3757056 Jan 21 20:33 XL2KeyServer.exe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $FTP_LIST() &lt;br /&gt;
 #coutl $FTP_LIST(*.pdf) &lt;br /&gt;
 #coutl $FTP_LIST(,det) &lt;br /&gt;
 #coutl $FTP_LIST(usage,det)&lt;br /&gt;
&lt;br /&gt;
=Web=&lt;br /&gt;
&lt;br /&gt;
==#http_request ==&lt;br /&gt;
&lt;br /&gt;
Setzt einen http- oder https-Request ab und schreibt ggf. das Ergebnis in eine Variable oder einen Value. Diese Prozedur eignet sich auch für REST-Aufrufe.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Name der einzelnen Array-Elemente; Funktionen werden ersetzt&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* scode - Statuscode der Antwort als dreistellige Zahl (404 - not found, etc.)&lt;br /&gt;
* se (&amp;quot;show error&amp;quot;) - Wenn Y, wird im Fehlerfall die Fehlermeldung in einer Meldungsbox eingesetzt. Funtkionen werden ersetzt. Sollte im Server-Betrieb auf N gesetzt werden.&lt;br /&gt;
* status - Status der Antwort als Klartext&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
* y - Typ&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear &lt;br /&gt;
 #text {&lt;br /&gt;
 #text     &amp;quot;userId&amp;quot;: 1&lt;br /&gt;
 #text }&lt;br /&gt;
 &lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&amp;quot;&lt;br /&gt;
 #code   url=https://xxxxx.net/sore/printall  &lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/json&amp;quot;   request=$TEXT(1)   response=1   scode=2   status = 3   se=Y   acc=application/json     $CODE$&lt;br /&gt;
 #cout   c=&amp;quot;$VAL(2) - VAL(3)&amp;quot;&lt;br /&gt;
 #cout   c=$VAL(1)&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22524</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22524"/>
		<updated>2025-07-01T15:52:15Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* $GRD_REGEX */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$GRD_REGEX==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_REGEX prüft ein Grid-Segment die die Einhaltung eines Regex-Staements in einer bestimmten Spalte. Eignet sich insbesondere für #page_check, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Regex-Statement&lt;br /&gt;
# Optionen&lt;br /&gt;
## e (&amp;quot;allow empty&amp;quot;) - $GRD_REGEX gibt auch Y zurück, wenn der Zellenwert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Aktionscode entspricht nicht den Formatvorgaben&amp;quot;   chk=$GRD_REGEX(reisen,aktionscode,all,[A-Z]{3}\d{4},e)&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22523</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22523"/>
		<updated>2025-07-01T15:51:07Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* $GRD_CHECK */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$GRD_REGEX==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Regex-Statement&lt;br /&gt;
# Optionen&lt;br /&gt;
## e (&amp;quot;allow empty&amp;quot;) - $GRD_REGEX gibt auch Y zurück, wenn der Zellenwert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Aktionscode entspricht nicht den Formatvorgaben&amp;quot;   chk=$GRD_REGEX(reisen,aktionscode,all,[A-Z]{3}\d{4},e)&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22522</id>
		<title>Modul VAR neu</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22522"/>
		<updated>2025-06-24T14:47:09Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #dir_proc */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das Modul Var sammelt neben den Variablen auch die grundlegenden Prozeduren und Funktionen.&lt;br /&gt;
&lt;br /&gt;
=Variable=&lt;br /&gt;
&lt;br /&gt;
==#var_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#setvar setzt den Wert einer Variablen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis: Variable sind global, auf sie kann auch in Sub-Kommandos zugegriffen werden. Values sind dagegen lokal.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*rf (replace functions) - Wenn Y, dann werden nach der Zuweisung auf die Variable nochmals die Funktionen ersetzt. Wird zum Beispiel benötigt, wenn Code mit Funktionen mittels $DATA() aus der Datenbank geladen wird; Funktionen werden ersetzt, default N; siehe Beispiel&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_set   n=test2  z=$GUID()&lt;br /&gt;
 #var_set   n=edt    z=$EDT(edt1)   ie=42&lt;br /&gt;
 #var_set   n=_page_kunde_adressänderung_ro   z=N   zn=Y   zr=Y   r=kundenservice&lt;br /&gt;
&lt;br /&gt;
Zum Parameter rf: $NOW() in die Zwischenablage kopieren und dann ausführen:&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=N&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=Y&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_setempty==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_setempty setzt den Wert einer Variablen, sofern sie (noch) leer ist.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Besteht der Variableninhalt aus Leerzeichen, gilt die Variable auch als leer.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_setempty   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_setempty   n=test2  z=$GUID()&lt;br /&gt;
 #var_setempty   n=edt    z=$EDT(edt1)    ie=42&lt;br /&gt;
&lt;br /&gt;
==#var_add==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_add fügt einer Variablen einen Wert hinzu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. &lt;br /&gt;
* y -Typ der Operation; default ''text''&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** month - Es wird dem Datum eine Anzahl von Monaten hinzugefügt&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
*z - Wert, welcher der Variablen hinzugefügt wird, Funktionen werden ersetzt, default ist ein leerer String oder eine 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$NOW()&lt;br /&gt;
 #var_add   n=test   z=1   y=datetime&lt;br /&gt;
 #cout   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_log==&lt;br /&gt;
&lt;br /&gt;
Schreibt den Inhalt aller Variablen in das Debug-Log.&lt;br /&gt;
&lt;br /&gt;
Wird nur zur Fehlersuche verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_log&lt;br /&gt;
&lt;br /&gt;
==$VAR()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $VAR() wird auf den Inhalt der Variable zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
# optional: Der Wert wird vor oder nach der Rückgabe als Funktionsergebnis verändert; nur für ganzzahlige Werte&lt;br /&gt;
## ib (&amp;quot;increment before&amp;quot;) - Der Wert wird vor der Rückgabe um eins erhöht&lt;br /&gt;
## db (&amp;quot;decrement before&amp;quot;) - Der Wert wird vor der Rückgabe um eins verringert&lt;br /&gt;
## ia (&amp;quot;increment after&amp;quot;) - Der Wert wird nach der Rückgabe um eins erhöht&lt;br /&gt;
## da (&amp;quot;decrement after&amp;quot;) - Der Wert wird nach der Rückgabe um eins verringert&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #message  c=$VAR(test)&lt;br /&gt;
 #var_set  n=neuer_wert   z=$VAR(wert)   ie=$VAR(alternativwert)&lt;br /&gt;
 #execsql   k_lfdnr=$VAR(lfdnr,ib)&lt;br /&gt;
&lt;br /&gt;
=Kommandos=&lt;br /&gt;
&lt;br /&gt;
(Primär- und Sub) Kommandos sind üblicherweise benannt und werden im Code-Dialog eingegeben.&lt;br /&gt;
&lt;br /&gt;
Es besteht jedoch auch die Möglichkeit, lokale Kommandos innerhalb eines anderen Kommandos zu definieren. Diese Kommandos haben statt eines Kommando-Namens dann dann eine Kommando-Nummer.&lt;br /&gt;
&lt;br /&gt;
Lokale Kommandos werden üblicherweise für folgende Zwecke verwendet:&lt;br /&gt;
&lt;br /&gt;
* Bei der Verwendung von xlive werden bisweilen Prozeduren eingesetzt, die ihrerseits ein Kommando aufrufen (z.B. #sql_open). Wenn dieses Kommando nichts bereits existiert, kann es nur als lokales Kommando erstellt werden.&lt;br /&gt;
&lt;br /&gt;
* Wenn das auszuführende Kommando auf derselben Seite stehen soll wie die aufrufende Prozedur.&lt;br /&gt;
&lt;br /&gt;
Siehe als Beispiel: [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd fügt dem Kommando eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd fügt dem ersten Kommando eine Zeile hinzu, #cmd2 fügt dem zweiten Kommando eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd hat keine benannten Parameter. Die ganze Zeile nach dem #cmd und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd3 #text $DATA(n,login);$DATA(n,shortname);$DATA(n,firstname);$DATA(n,lastname);$DATA(n,userid);&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clear löscht ein Kommando&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd_clear löscht das erste Kommando, #cmd_clear2 löscht das zweite Kommando, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #cmd_clear Zeichen, so werden die dem gerade gelöschten Kommando hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear3&lt;br /&gt;
 #cmd_clear #grd_add   i=grid   f_logtext=&amp;quot;Kunde angerufen und nicht erreicht.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#cmd_clearall==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clearall löscht alle Kommandos&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clearall&lt;br /&gt;
&lt;br /&gt;
=CSV=&lt;br /&gt;
&lt;br /&gt;
Die CSV-Routinen werden verwendet, um CSV-Dateien einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==#csv_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_open öffnet eine CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_open öffnet die erste CSV-Datei, #csv_open2 öffnet die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*ber - wenn Y, werden die Zeilenumbrüche innerhalb von Feldern durch Leerzeichen ersetzt. Die Felder müssen dabei in doppelten Anführungszeichen eingeschlossen sein.&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - (&amp;quot;Filename&amp;quot;) Dateiname der CSV-Datei&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich. Muss bereits hier gesetzt werden, wenn mit $CSV_LINE auf den Header zugegriffen werden soll, bevor #csv_line ausgeführt wird.&lt;br /&gt;
*txt (&amp;quot;Text&amp;quot;) - alternativ zum Dateinamen fn die Nummer eines Textes, der als CSV-Datei verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open  fn=c:\temp\text.csv&lt;br /&gt;
&lt;br /&gt;
==#csv_line==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_line geht zeilenweise durch die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_line geht durch die erste CSV-Datei, #csv_line2 geht durch die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;database&amp;quot;) - Die Datenbank, für welche die Transaktion ausgeführt wird, wenn ert=Y gesetzt ist. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
*er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
*ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt, Funktionen werden ersetzt&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich.&lt;br /&gt;
*m (&amp;quot;maximum&amp;quot;) - Maximale Anzahl der Zeilen, die verarbeitet wird. Wird gerne bei der Entwicklung verwendet, um die Bearbeitungsgeschwindigkeit zu erhöhen. Funktionen werden ersetzt&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird im Falle einer Exception die Bearbeitung nicht abgebrochen, sondern lediglich Warnungen geloggt; Default N, Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Semikolon, Funktionen werden ersetzt&lt;br /&gt;
*trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_line  er=test_csv_line   hhr=Y   m=3&lt;br /&gt;
&lt;br /&gt;
==#csv_check==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_check prüft die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnt (&amp;quot;count&amp;quot;) - Anzahl der Header-Einträge, die geprüft wird; Funktionen werden ersetzt&lt;br /&gt;
*h1, h2... (&amp;quot;header&amp;quot;) - Eintrag im Header, der auf existenz geprüft wird; Groß und Kleinschreibung ist unerheblich, Funktionen werden ersetzt.&lt;br /&gt;
*n (&amp;quot;name&amp;quot; / &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in die/den das Ergebnis (Y oder N) geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*res (&amp;quot;result&amp;quot;) - Name der Variable oder Nummer des Values, in die/den der Ergebnistext geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwischen den einzelnen Spalten; Funktionen werden ersetzt&lt;br /&gt;
*y - Typ der Prüfung; Funktionen werden ersetzt, default header&lt;br /&gt;
** header - Prüft die Existenz von Spaltennamen im Header. Die zu prüfenden Spaltennamen werden als h1, h2... übergeben, cnt ist entsprechend zu setzen. Wenn alle geprüften Spaltennamen vorhanden sind, wird Y zurück gegeben, ansonsten N. Die fehlenden Spaltennamen werden als Ergebnistext zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open   fn=C:\temp\mad\done\MTF3108_ET2607_selektion.CSV&lt;br /&gt;
 #csv_check   n=1   res=2   cnt=3   h1=eins   h2=zwei   h3=drei&lt;br /&gt;
 #coutl $VAL(1) - $VAL(2)&lt;br /&gt;
&lt;br /&gt;
==#csv_paste==&lt;br /&gt;
&lt;br /&gt;
Übernimmt eine CSV-Datei aus der Zwischenablage. Auf die Werte kann mit $SEPLINE() zugegriffen werden, siehe [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
'''Multi-Row'''&lt;br /&gt;
&lt;br /&gt;
Mit dem Multi-Row-Modus können Daten eingelesen werden, die in einer Zeile mehrere gleichartige Werte haben.&lt;br /&gt;
&lt;br /&gt;
Daten, die im Single-Row-Modus wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465&lt;br /&gt;
 01.01.2020     8574&lt;br /&gt;
 01.01.2020     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     3456&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     4457&lt;br /&gt;
 03.01.2020     7658&lt;br /&gt;
&lt;br /&gt;
Würden im Multi-Row-Modus wie folgt aussehen (und könnten auch so eingelesen werden):&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465     8574     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436     6578     3456     6578     4457     7658&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Wenn dieser Parameter einen Wert hat, dann muss die kopierte CSV-Datei in der ersten Zeile auch diesen Wert haben, oder die Aktion wird abgebrochen; Funktionen werden ersetzt&lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden.&lt;br /&gt;
* mrs (&amp;quot;multi row start&amp;quot;) - Erste Spalte für den Multi-Row-Bereich&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Tabulatorzeichen&lt;br /&gt;
* trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ; default s&lt;br /&gt;
** m - multi; siehe Abschnitt Multi-Row&lt;br /&gt;
** s - single; die CSV-Datei wird Zeile für Zeile eingelesen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
* [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
 #csv_paste   er=imp_line   hhr=Y&lt;br /&gt;
 #csv_paste   er=imp_line   y=m   mrs=1&lt;br /&gt;
&lt;br /&gt;
==$CSV()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV() greift auf einen Feldinhalt der aktuellen CSV-Zeile zu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Spalte oder 0-relative Spaltennummer. Name der Spalte setzt voraus, dass bei #csv_line der Parameter hhr gleich Y ist.&lt;br /&gt;
# optional: Stelle der Zeichens, ab dem der Inhalt des CSV-Feldes zurück gegeben wird&lt;br /&gt;
# optional: Anzahl der Zeichen, die maximal zurück gegeben werden; wird meist dafür verwendet, damit die maximale Länge von Datenbankfeldern nicht überschritten wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0)&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird in der ersten CSV-Datei (#csv_open) auf die erste Spalte (0, da 0-relativ) zugegriffen.&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0,1,30)&lt;br /&gt;
&lt;br /&gt;
Wie oben, nur werden nur die ersten 30 Zeichen zurück gegeben&lt;br /&gt;
&lt;br /&gt;
==$CSV_LINE()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV_LINE() Gibt eine ganze Zeile einer CSV-Datei zurück&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Zeile: header gibt die Header-Zeile zurück, current die aktuelle Zeile in #csv_line&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CSV_LINE wird insbesondere dafür verwendet, um CSV-Dateien mit Daten zu ergänzen. Hier im Beispiel wird jede Zeile mit einer GUID ergänzt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #text $CSV_LINE(1,current)$GUID();&lt;br /&gt;
 &lt;br /&gt;
 #csv_open   fn=c:\temp\ex.csv   hhr=Y&lt;br /&gt;
 #text_clear $CSV_LINE(1,header)guid;&lt;br /&gt;
 #csv_line   er=1   hhr=Y&lt;br /&gt;
 &lt;br /&gt;
 #text_save   fn=c:\temp\ex2.csv&lt;br /&gt;
&lt;br /&gt;
Nach dem Öffnen der bestehenden CSV-Datei (es muss hier bereits hhr gesetzt werden) wird zunächst der Header in Text 1 eingefügt, ergänzt um die Spalte ''guid'' und das abschließende Semikolon. Danach gehen wir mit #csv_line durch alle Zeile, fügen diese komplett in Text 1 ein und hängen eine GUID hinten dran. Danach wird die Datei gespeichert.&lt;br /&gt;
&lt;br /&gt;
=Text=&lt;br /&gt;
&lt;br /&gt;
==#text==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text fügt dem Text eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text fügt dem ersten Text eine Zeile hinzu, #text2 fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Und jetzt noch eine GUID: $GUID()&lt;br /&gt;
 #text Der folgende Text kommt in Großbuchstaben: $UPP(hello world)&lt;br /&gt;
&lt;br /&gt;
==#textn==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#textn fügt dem Text eine Zeile hinzu. Im Unterschied zu #text werden dabei keine Funktionen ersetzt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #textn fügt dem ersten Text eine Zeile hinzu, #text2n fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #textn und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden dabei '''nicht''' ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #textn Zeile 1&lt;br /&gt;
 #textn Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_clear löscht einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_clear löscht den ersten Text, #text_clear2 löscht den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #text_clear Zeichen, so werden die dem gerade gelöschten Text hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear7&lt;br /&gt;
 #text7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
Das vorangestellt #text_clear stellt sicher, dass Text7 leer ist. Alternativ könnte man formulieren:&lt;br /&gt;
&lt;br /&gt;
 #text_clear7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_save==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_save speichert einen Text in einer Datei.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_save speichert den ersten Text, #text_save2 speichert den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* bom (&amp;quot;Byte order mark&amp;quot;) - Wenn Y, dann wird die Datei mit BOM geschrieben; default Y&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu speichernden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname, unter dem die Datei gespeichert wird. Bestehende Dateien werden überschrieben, sofern das Betriebssystem das nicht verhindert (z.B, weil die Datei gerade geöffnet ist)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Öffnet die gespeicherte Datei gleich anschließend.&lt;br /&gt;
*sort - Wenn Y, dann wird die Datei vor dem Speichern sortiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Hello world&lt;br /&gt;
 #text_save  fn=$DIR(userroot)hello_world.txt&lt;br /&gt;
 #text_save  fn=c:\temp\export_vert_export.prepared_.csv   e=utf8   bom=N&lt;br /&gt;
&lt;br /&gt;
==#text_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_open öffnet einen Text aus einer Datei, der bisherige Inhalt der Datei wird überschrieben.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_open öffnet den ersten Text, #text_open2 öffnet den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname der Datei, die geöffnet wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_open  fn=$DIR(userroot)test.txt&lt;br /&gt;
 #text Eine weitere Zeile, $GUID()&lt;br /&gt;
 #text_save  fn=$DIR(userroot)test.txt&lt;br /&gt;
&lt;br /&gt;
==#text_props==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_props stellt Eigenschaften des Textes ein.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_props bezieht sich auf den ersten Text, #text_props2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* dub (&amp;quot;duplicates&amp;quot;) - Verhalten einer sortierten Liste bezüglich Dubletten&lt;br /&gt;
** acc (&amp;quot;accept&amp;quot;) - Dubletten werden akzeptiert&lt;br /&gt;
** err (&amp;quot;error&amp;quot;) - Dubletten führen zu Fehlern&lt;br /&gt;
** ign (&amp;quot;ignore) - Dubletten werden ignoriert&lt;br /&gt;
* srt (&amp;quot;sorted&amp;quot;) - Wenn ja, dann ist die Liste sortiert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_props   srt=Y   dup=ign&lt;br /&gt;
&lt;br /&gt;
==#text_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_set setzt eine bestimmte Zeile eines Textes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_set bezieht sich auf den ersten Text, #text_set2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;index&amp;quot;) - 0-relativer Index der Zeile, die geschrieben werden soll. Mit ''last'' kann die letzte Zeile geschrieben werden, mit ''all'' werden alle Zeilen ersetzt, das wird dann gebraucht, wenn mehrzeiliger Text zugewiesen werden soll; Funktionen werden ersetzt&lt;br /&gt;
* z - Text, der geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text_set   i=2   z=&amp;quot;dritte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=last   z=&amp;quot;letzte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=all   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
==#text_sort==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_sort sortiert einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_sort bezieht sich auf den ersten Text, #text_sort2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* y - Typ, default alpha, Funktionen werden ersetzt&lt;br /&gt;
** alpha - sortiert alphanumerisch&lt;br /&gt;
** inv - invertiert die gegebene Reihenfolge&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=&amp;quot;,OU=2nd_Level_T1,OU=Kundenservice,OU=Benutzer,OU=Testtours,OU=Travel&amp;quot;&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text_dissect   z=$VAL(1)   sep=&amp;quot;,OU=&amp;quot;&lt;br /&gt;
 #coutl  $TEXT(1)&lt;br /&gt;
 #text_sort   y=inv&lt;br /&gt;
 #text_compose   n=1   sep=.&lt;br /&gt;
 #val_set   n=1   z=tt.$VAL(1)&lt;br /&gt;
 #coutl $VAL(1)&lt;br /&gt;
&lt;br /&gt;
 Ergebnis ist:&lt;br /&gt;
 2nd_Level_T1&lt;br /&gt;
 Kundenservice&lt;br /&gt;
 Benutzer&lt;br /&gt;
 Testtours&lt;br /&gt;
 tt.Testtours.Benutzer.Kundenservice.2nd_Level_T1.&lt;br /&gt;
&lt;br /&gt;
==#text_dissect==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_dissect zerteilt einen String anhand einer vorgegebenen Trennzeichenfolge und fügt das Ergebnis dem betreffenden Text hinzu. Gegebenenfalls muss der Text vorher mit #text_clear geleert werden.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_dissect bezieht sich auf den ersten Text, #text_dissect bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - wenn Y, wird die sep-Zeichenfolge noch mal dem String angehängt; default N, Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, anhand der String zerteilt wird; Funktionen werden ersetzt&lt;br /&gt;
* z - String, der zerlegt wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_compose==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_compose setzt einen Text mithilfe eines Trennzeichens zu einem String zusammen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_compose bezieht sich auf den ersten Text, #text_compose bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - Wenn Y, wird die Trennzeichenfolge auch noch mal am Ende des Strings eingefügt; default N, Funktionen werden ersetzt&lt;br /&gt;
* n - Nummer des Values oder Name der Variable, in welche der String geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichenfolge, die beim Zusammenfügen des Textes verwendet wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_act==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_act bearbeitet einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_act bezieht sich auf den ersten Text, #text_act2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text der Zeile, die bei insert eingefügt werden soll; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* cu (&amp;quot;current&amp;quot;) - 0-relative Zeilennummer der Operation; default 0, Funktionen werden ersetzt&lt;br /&gt;
* ne (&amp;quot;new&amp;quot;) - 0-relative Zeilennummer als Ziel bei move; default 0, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt&lt;br /&gt;
** delete - Löscht die Zeile an Position cu (&amp;quot;current&amp;quot;)&lt;br /&gt;
** insert - Fügt den Text c an der Position cu (&amp;quot;current&amp;quot;) ein&lt;br /&gt;
** move - verschiebt die Zeile cu (&amp;quot;current&amp;quot;) nach Zeile ne (&amp;quot;new&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #text_act   y=move   cu=0&lt;br /&gt;
&lt;br /&gt;
==#text_loop==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_loop geht durch die Zeilen eines Textes und ruft für jede Zeile ''er'' auf&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_loop  bezieht sich auf den ersten Text, #text_loop2  bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich ert bezieht&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m - (&amp;quot;maximum&amp;quot;) Es wird maximal für die Anzahl der angegebenen Zeilen das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* n - Name der Variable, in welche die 0-relative Schleifenvariable geschrieben wird. (Es würde auch in einen Value geschrieben, wenn es sich um eine Nummer handelt, das ergibt in der Praxis aber meist nicht viel Sinn) Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear eins&lt;br /&gt;
 #text zwei&lt;br /&gt;
 #text drei&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear #coutl - $TEXT(1,$VAR(eins))&lt;br /&gt;
 #text_loop   er=1   n=eins&lt;br /&gt;
&lt;br /&gt;
==#tvl_add==&lt;br /&gt;
&lt;br /&gt;
Addiert dem Wert in einer Text-Valueliste einen Wert hinzu. Es handelt sich dabei um eine nummerierte Prozedur: #tvl_add arbeitet mit Text 1, #tvl_add2 mit Text 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Zeile, der ein Wert hinzugefügt wird; Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Operation, Funktionen werden ersetzt, default text&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
* z - Der Wert, der hinzugefügt wird&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text eins=1&lt;br /&gt;
 #text zwei=2&lt;br /&gt;
 #text drei=3&lt;br /&gt;
 #tvl_add   y=int   n=zwei   z=1&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==$TEXT()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $TEXT() wird auf den Inhalt des Textes zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# optional Zeile des Textes (0-relativ). Wenn es keinen zweiten Parameter gibt, wird der komplette Text zurück gegeben. Alternativ als zweiter Parameter eine Sonderfunktion:&lt;br /&gt;
## cnt / count - Gibt die Anzahl der Zeilen zurück&lt;br /&gt;
## last - Gibt die letzte Zeile zurück&lt;br /&gt;
## ix - Gibt die Position des Textes im dritten Parameter zurück&lt;br /&gt;
## as_line - Gibt den Text als eine Zeile zurück, Zeilenumbrüche werden durch den dritten Parameter ersetzt&lt;br /&gt;
# optional in abhängigkeit vom zweiten Paremeter&lt;br /&gt;
## wenn zweiter Parameter ix: Textzeile, nach der mit ix gesucht wird&lt;br /&gt;
## wenn zweiter Parameter as_line: Zeichenfolge, mit der die Zeilenumbrüche ersetzt werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Zeile 3&lt;br /&gt;
 #message  c=$TEXT(1)&lt;br /&gt;
&lt;br /&gt;
 #code url=$TEXT(1,as_line,&amp;amp;)&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich gilt in BAL: Eine Prozedur - eine Zeile.&lt;br /&gt;
&lt;br /&gt;
Bei vielen und/oder langen Parametern führt das zu recht langen Code-Zeilen und zu Unübersichtlichkeit. Hier können nun Teile der Parameter mit #code in weitere Zeile ausgelagert werden, deren Inhalt dann mit $CODE$ oder $CODE$ der eigentlichen Code-Zeile hinzugefügt wird.&lt;br /&gt;
&lt;br /&gt;
==#code==&lt;br /&gt;
&lt;br /&gt;
Fügt Text dem Code-Speicher hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#code hat keine benannten Parameter. Die ganze Zeile nach dem #code und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=G:\pics\pic5d68865cdaba62_62767562.jpg&lt;br /&gt;
 #code fn2=G:\pics\pic5d913c48682128_67979256.jpg&lt;br /&gt;
 #email_send   from=test@****.de   to=info@*****************.de   bcc=info@*****.de   subject=Testmail   text=$TEXT(1)   $CODE$&lt;br /&gt;
&lt;br /&gt;
==$CODE$ / $CODEN$==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CODE$ und $CODEN$ sind keine Funktionen, auch wenn sie auf den ersten Blick ähnlich aussehen. Sie haben keine Parameter und auch keine Klammern, dafür ein abschließendes $.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen fügen den Code-Speicher der jeweiligen Zeile hinzu. $CODE$ löscht danach den Code-Speicher, $CODEN$ tut das nicht, so dass dieselben Parameter wiederholt eingefügt werden können (beim letzten Einfügen sollte dann $CODE$ verwendet werden).&lt;br /&gt;
&lt;br /&gt;
=Separierte Zeile=&lt;br /&gt;
&lt;br /&gt;
Eine separierte Zeile ist eine Textzeile, die mehrere gleichartige Werte enthält, die durch Trennzeichen getrennt sind.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 3244,4465,7763,4536,4356,7777&lt;br /&gt;
&lt;br /&gt;
Solche Zeilen können mit #sepline aufgetrennt werden.&lt;br /&gt;
&lt;br /&gt;
==#sepline==&lt;br /&gt;
&lt;br /&gt;
Trennt eine separierte Zeile auf und führt für jeden Wert das mit er angegebene Kommando aus.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur (#sepline, #sepline2...)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y; Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, für welche die Transaktion gestartet wird, wenn ert=Y. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern (&amp;quot;each row no&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Wenn Y, wird für jeden Wert der separierten Zeile eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Es wird maximal für die Anzahl der angegebenen Werte das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten; Funktionen werden ersetzt.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N; Funktionen werden ersetzt.&lt;br /&gt;
* nn (&amp;quot;not null&amp;quot;) - Wenn Y, dann wird er nur für Werte der separierten Zeile aufgerufen, die nicht leer sind. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Das oder die Trennzeichen; default ist das Semikolon, Funktionen werden ersetzt.&lt;br /&gt;
* z - Der Inhalt der separierten Zeile; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(1)&lt;br /&gt;
 #sepline z=3244,4465,7763,4536,4356,7777   sep=,   er=1&lt;br /&gt;
&lt;br /&gt;
==$SEPLINE()==&lt;br /&gt;
&lt;br /&gt;
Greift auf den einzelnen Wert einer mit #sepline getrennten Zeile zu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der separierten Zeile&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(3)&lt;br /&gt;
 #sepline3 z=3244;4465;7763;4536;4356;7777     er=1&lt;br /&gt;
&lt;br /&gt;
=User und Rechte=&lt;br /&gt;
&lt;br /&gt;
Aus Gründen der Übersichtlichkeit ist die Rechtevergabe zweistufig:&lt;br /&gt;
&lt;br /&gt;
# Es werden (meist am Anfang eines Primär-Kommandos) Rechte-Definitionen erstellt, die einer oder mehreren Benutzergruppen Rechte (lesen oder lesen und schreiben) zuweisen. Die Rechte werden dabei implizit auch allen Untergruppen der angegebenen Benutzergruppe erteilt (Zum Beispiel: Rechte der Gruppe ''user'' hat auch implizit die Gruppe ''user.admin'').&lt;br /&gt;
# Dem Parameter r verschiedener Prozeduren kann dann eine Rechte-Definition zugewiesen werden.&lt;br /&gt;
&lt;br /&gt;
Den Parameter r als Rechte-Definition berücksichtigen die folgenden Prozeduren:&lt;br /&gt;
&lt;br /&gt;
* #frm&lt;br /&gt;
* Buttons (#btn, #btns_btn)&lt;br /&gt;
* Alle Segmente (#text_seg, #memo_seg, #btns_seg, vl_seg, #grd_seg, #xgrd_seg)&lt;br /&gt;
* Tree (#tree_add, #tree_fill, #tree_fillsql, Lese-Recht reicht)&lt;br /&gt;
* Grid-Spalten (#grd_col, #xgrd_col)&lt;br /&gt;
* #vl_line (für die komplette Zeile (r) und die einzelne Zelle (r1, r2, r3...))&lt;br /&gt;
&lt;br /&gt;
Wo der Parameter r nicht gesetzt ist, wird die Rechte-Definition der Formulars verwendet.&lt;br /&gt;
&lt;br /&gt;
==#rights==&lt;br /&gt;
&lt;br /&gt;
Setzt eine Rechte-Definition im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Rechte-Definition; default ist ''frm'', also dsa Default-Recht für das Formular.&lt;br /&gt;
* r_ (&amp;quot;right&amp;quot;) - Prefix für die Benutzergruppe. Für die Rechte-Definition sind die folgenden Werte zulässig&lt;br /&gt;
** n (&amp;quot;no&amp;quot;) - kein Recht&lt;br /&gt;
** r (&amp;quot;read&amp;quot;) - nur lesen&lt;br /&gt;
** w (&amp;quot;write&amp;quot;) - lesen und schreiben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights  n=frm   r_user=r   r_user.admin=w&lt;br /&gt;
&lt;br /&gt;
Setzt für alle User das Lese-Recht und für Administratoren das Lese- und Schreibrecht.&lt;br /&gt;
&lt;br /&gt;
==#rights_clear==&lt;br /&gt;
&lt;br /&gt;
Löscht alle Rechte-Definitionen im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
(Wird in der Praxis selten benötigt, weil Kommandos mit leerer Rechte-Definition starten.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights_clear&lt;br /&gt;
&lt;br /&gt;
==$USERID()==&lt;br /&gt;
&lt;br /&gt;
Die ID des angemeldeten Users&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kusr=$USERID()&lt;br /&gt;
&lt;br /&gt;
==$RIGHTUSERID()==&lt;br /&gt;
&lt;br /&gt;
Administratoren können andere User einstellen (Userliste links unten im BAF-Client), vor allem um deren Rechte zu prüfen. Die UserID dieses ausgewählten Users kann mit der Funktion $RIGHTUSERID() ermittelt werden.&lt;br /&gt;
&lt;br /&gt;
In fast allen Fällen gilt der folgende Grundsatz: Lesende Operationen mit $RIGHTUSERID(), schreibende Operationen mit $USERID().&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_open   kusr=$RIGHTUSERID()&lt;br /&gt;
&lt;br /&gt;
==$ADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der angemeldete User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $ADM()&lt;br /&gt;
&lt;br /&gt;
==$RADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der ausgewählte User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $RADM()&lt;br /&gt;
&lt;br /&gt;
=Ausführen=&lt;br /&gt;
&lt;br /&gt;
==#exec==&lt;br /&gt;
&lt;br /&gt;
Führt ein anderes Kommando aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Names des (Primär- oder Sub-) Kommandos, das ausgeführt werden soll.&lt;br /&gt;
* ex (&amp;quot;exception&amp;quot;) - Name oder Nummer des Kommandos, das ausgeführt wird, wenn bei der Ausführung von cmd eine Exception auftritt; siehe Beispiele&lt;br /&gt;
* fin (&amp;quot;finally&amp;quot;) - Name oder Nummer des Kommandos, das nach der Ausführung von cmd ausgeführt wird - egal ob eine Exception aufgetreten ist oder nicht. Wird nur berücksichtigt, wenn der Parameter ex nicht gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel löst das Problem, dass ein neues PDF unter demselben Dateinamen nicht erstellt werden kann, wenn beim vorherigen Versuche der Erstellung eine Exception aufgetreten ist. In einem solchen Fall wurde ein #pdf_start, aber kein #pdf_stop ausgeführt, und die geöffnete Datei sperrt diesen Dateiname, bis der BAF-Client geschlossen wird. Lösung dieses Problems ist es, im Parameter ex ein #pdf stop auszuführen; auf das Öffnen der Datei kann in einem solchen Fall verzichtet werden. Mit der Funktion $DATA() wird hier im Beispiel gezielt eine Exception ausgelöst.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test_pdf&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #pdf_text  c=&amp;quot;Hello World&amp;quot;&lt;br /&gt;
 -- #cmd #pdf_text  c=&amp;quot;Hello World $DATA(dat,test)&amp;quot;&lt;br /&gt;
 #cmd #pdf_stop   o=Y&lt;br /&gt;
 &lt;br /&gt;
 #pdf_start  fn=$DIR(doc)\test.pdf&lt;br /&gt;
 #exec   cmd=1   ex=&amp;quot;#pdf_stop   o=N&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test_pdf executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#batchexec==&lt;br /&gt;
&lt;br /&gt;
Speichert den Text n in der Datei batch.bat und führt diese aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clr (&amp;quot;clear&amp;quot;) - Wenn Y, wird der Text nach Ausführung des Batch-Datei gelöscht; Default Y; Funktionen werden ersetzt;&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes; der mit #text gespeicherte Text hat die Nummer 1 &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #batchexec   n=1&lt;br /&gt;
&lt;br /&gt;
==#file_open==&lt;br /&gt;
&lt;br /&gt;
Öffnet eine Datei (oder auch eine Webseite)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder die URL der Webseite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_open  fn=c:\temp\test.csv&lt;br /&gt;
 #file_open  fn=https://www.google.de&lt;br /&gt;
&lt;br /&gt;
==#loop==&lt;br /&gt;
&lt;br /&gt;
BAL kennt keine Schleifen als Sprachelement. Um Schleifen mit einer fest Schleifenzahl auszuführen, wird die Prozedur #loop verwendet. lf muss nicht kleiner als lt sein, #loop kann auch von oben nach unten zählen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* lf (&amp;quot;loop from&amp;quot;) - Anfangswert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* lt (&amp;quot;loop to&amp;quot;) - Endwert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in der die Schleifenvariable gespeichert wird (damit sie an anderer Stelle gelesen werden kann); Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #loop   lf=42   lt=1337   er=test_line&lt;br /&gt;
&lt;br /&gt;
==#exit==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #exit bricht die Ausführung auf der jeweiligen Code-Ebene (Kommando bzw. Sub-Kommando) ab&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 ~ $EMPTY($PVAL(vl,id))   and   $PVAL(vl,status) &amp;gt; 20&lt;br /&gt;
 #sql select nextval('ausza_id') as id&lt;br /&gt;
 #sql_openval   f_id=1&lt;br /&gt;
 #page_val   i=vl   f=id   z=$VAL(1)&lt;br /&gt;
 #save&lt;br /&gt;
 #exit&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Der Beispiel-Code befindet sich auf der Seite xausza_page_ausza und baut die entsprechende Seite auf. Er prüft, ob bereits eine ID-Gesetzt ist - wenn nicht, wird über eine Datenbank-Sequenz die nächste ID abgefragt, in das VL-Segment geschrieben und die Seite gespeichert. Beim Speichern der Seite wird sie jedoch neu aufgerufen, also komplett neu aufgebaut, was erst einmal kein Problem ist. Danach würde aber die Ausführung auf der Code-Ebene, auf der sich #save befindet, fortgeführt, was zur Folge hat, dass die dann folgenden Segmente doppelt erscheinen (zunächst die aus dem Neu-Aufbau der Seite, dann die, die von der Fortsetzung des Codes her stammen).&lt;br /&gt;
&lt;br /&gt;
Um dies zu vermeiden muss die Ausführung des Codes nach #save abgebrochen werden.&lt;br /&gt;
&lt;br /&gt;
==$EXEC==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando. Im ausgeführten Kommando kann eine Variable gesetzt werden, die dann als Funktionsergebnis von $EXEC zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll&lt;br /&gt;
# optional: Der Name der Variablen, in der das Ergebnis steht; default ist ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;test_funkexec&amp;quot;   y=console&lt;br /&gt;
 #cout   c=$EXEC(test_funkexec_line)&lt;br /&gt;
&lt;br /&gt;
 -- test_funkexec_line&lt;br /&gt;
 #var_set   n=result   z=42&lt;br /&gt;
&lt;br /&gt;
=Dateien und Verzeichnisse=&lt;br /&gt;
&lt;br /&gt;
==#file_op==&lt;br /&gt;
&lt;br /&gt;
Führt eine Operation mit einer Datei oder einem Verzeichnis aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder des Verzeichnisses&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in die/den das Ergebnis der Operation (Y oder N) geschrieben wird.&lt;br /&gt;
* on (&amp;quot;old name) - der bisherige Dateiname bei RenameFile&lt;br /&gt;
* y - Typ der Operation&lt;br /&gt;
** cd / createdir - Erzeugt ein Verzeichnis&lt;br /&gt;
** cf / copyfile - Kopiert eine Datei (von on zu fn)&lt;br /&gt;
** df / deletefile - Löscht eine Datei&lt;br /&gt;
** fd / forcedirectories - Stellt sicher, dass ein Pfad vorhanden ist&lt;br /&gt;
** rd / removedir - Entfernt ein Verzeichnis&lt;br /&gt;
** rf / renamefile - Benennt eine Datei um, kann auch dazu verwendet werden, eine Datei zu verschieben&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #file_op   y=renamefile   on=c:\temp\debug.txt   fn=c:\temp\test\debug.txt   n=1&lt;br /&gt;
 #cout   c=$VAL(1)&lt;br /&gt;
 &lt;br /&gt;
 #file_op   y=fd   fn=c:\eins\zwei\drei\vier&lt;br /&gt;
&lt;br /&gt;
==#file_search==&lt;br /&gt;
&lt;br /&gt;
Sucht Dateien und schreibt die Ergebnisliste in einen Text.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* clr - (&amp;quot;clear&amp;quot;) wenn Y, wird der Text vor der Suche geleert. Default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, in den die Ergebnisliste geschrieben wird; default 1, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_search   fn=c:\*.ini   n=1   y=0   all_=Y&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==#file_wait==&lt;br /&gt;
&lt;br /&gt;
Wartet, bis zumindest eine Datei vorhanden ist, die den Kriterien entspricht, und führt dann cmd aus. Wird nach der in to eingestellten Zeit keine Datei gefunden, dann wird mit dem in cmdto eingestellten Kommando abgebrochen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* cmd - Kommando, das ausgeführt wird, sobald eine Datei gefunden wird; Funktionen werden ersetzt&lt;br /&gt;
* cmdto - Kommando, das ausgeführt wird, sobald die Prozedur wegen eines TimeOuts abgebrochen wird; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* sleep - Zeit in ms zwischen den einzelnen Suchen nach einer Datei, die den Kriterien entspricht; Default 1000, Funktionen werden ersetzt&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in ms, nach der die Ausführung abgebrochen wird; Default 15000, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #cout c=&amp;quot;Gefunden&amp;quot;&lt;br /&gt;
 #cmd_clear2 #cout c=&amp;quot;TimeOut&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #file_wait   fn=C:\temp\test\*.txt   cmd=1   cmdto=2&lt;br /&gt;
&lt;br /&gt;
==#dir_force==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass es den spezifizierten Verzeichnispfad gibt, indem erforderlichenfalls Verzeichnisse angelegt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Names des Pfads&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_force   n=c:\temp\pdf&lt;br /&gt;
&lt;br /&gt;
==#dir_proc==&lt;br /&gt;
&lt;br /&gt;
Durchsucht ein Verzeichnis nach Dateien, die den angegebenen Kriterien entsprechen, und führt für jede gefundene Datei ''cmd'' aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das für jede gefundene Datei ausgeführt wird&lt;br /&gt;
* dn (&amp;quot;DirectoryName&amp;quot;) - Pfad des Verzeichnisses, in dem die Dateien gesucht werden; Funktionen werden ersetzt.&lt;br /&gt;
* done - Verzeichnis, in das die Dateien nach Abarbeitung verschoben werden (sofern der Parameter nicht leer ist). Funktionen werden ersetzt.&lt;br /&gt;
* error- Verzeichnis, in das die Dateien nach Abarbeitung verschoben werden (sofern der Parameter nicht leer ist), wenn der Inhalte der unter ndone angegebenen Variablen E ist. Funktionen werden ersetzt.&lt;br /&gt;
* fn (&amp;quot;filename&amp;quot;) - Suchkriterium für den Dateinamen; Funktionen werden ersetzt; Default *&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in welcher der Dateiname der aktuell zu bearbeitenden Datei inklusive Pfad gespeichert wird; Funktionen werden ersetzt; Default dir_proc&lt;br /&gt;
* ndone(&amp;quot;name done&amp;quot;) - Name der Variablen, die bestimmt, ob eine Datei in das Done-Verzeichnis verschoben wird. Vor jedem Aufruf von cmd wird diese Variable auf 'Y' gesetzt. Sie kann während der Bearbeitung auf N gesetzt werden - damit wird verhindert, dass die Datei in das Done-Verzeichnis verschoben wird. Wir die Variable auf E gesetzt, wird die Datei ins Error-Verzeichnis verschoben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_proc   dn=c:\temp\in   done=c:\temp\done   fn=*.csv   cmd=importcsv_line&lt;br /&gt;
&lt;br /&gt;
==$FILEINFO()==&lt;br /&gt;
&lt;br /&gt;
Liefert Infos über eine Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Dateiname&lt;br /&gt;
# Typ der Information, es stehen dabei folgende Optionen zur Verfügung&lt;br /&gt;
#* size - Dateigröße in Byte&lt;br /&gt;
#* size_point - Dateigröße in Byte, Punkte alle drei Zeichen von rechts&lt;br /&gt;
#* size_auto - Dateigröße in Byte, kB, MB oder GB, je nach Größe; mit Einheit&lt;br /&gt;
#* size_kb - Dateigröße in kB (analog Windows-Explorer)&lt;br /&gt;
#* date - Datum im Format dd.mm.yyyy&lt;br /&gt;
#* date_yyyy - Datum im Format yyyymmdd&lt;br /&gt;
#* datetime - Datum und Uhrzeit im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
#* datetime_yyyy - Datum im Format yyyymmddhhmmss&lt;br /&gt;
#* exists - Y, wenn die Datei existiert, sonst N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=fn   z=&amp;quot;T:\Tools Gruppenrechte\BC3 light\BafClientFM.exe&amp;quot;&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_point)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_auto)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_kb)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),exists)&lt;br /&gt;
&lt;br /&gt;
Ergebnis&lt;br /&gt;
&lt;br /&gt;
 27668480&lt;br /&gt;
 27.668.480&lt;br /&gt;
 26,39 MB&lt;br /&gt;
 27.020 kB&lt;br /&gt;
 02.05.2023&lt;br /&gt;
 20230502&lt;br /&gt;
 02.05.2023 12:20:09&lt;br /&gt;
 20230502122009&lt;br /&gt;
 Y&lt;br /&gt;
&lt;br /&gt;
==$DIR()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Verzeichnisnamen. Trailing Path Delimiter (\ bei Windows) wird immer angehängt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bezeichnung des Verzeichnisses&lt;br /&gt;
## appdata - Verzeichnis für Anwendungsdaten des Users&lt;br /&gt;
## cappdata - gemeinsames Verzeichnis für Anwendungsdaten aller User&lt;br /&gt;
## cdoc - gemeinsames Dokumentenverzeichnis  aller User&lt;br /&gt;
## cfav / cfavorites - gemeinsames Favoritenverzeichnis aller User&lt;br /&gt;
## cmusic - gemeinsames Musikverzeichnis aller User&lt;br /&gt;
## cpic / cpictures - gemeinsames Bilderverzeichnis aller User&lt;br /&gt;
## cvideo - gemeinsames Videoverzeichnis aller User&lt;br /&gt;
## desktop - Desktopverzeichnis des Rechners&lt;br /&gt;
## '''doc''' / docdir - Dokumentenverzeichnis des Users&lt;br /&gt;
## downloads - Downloadsverzeichnis des Users&lt;br /&gt;
## fav / favorites - Favoritenverzeichnis des Users&lt;br /&gt;
## fonts - Fontsverzeichnis des Rechners&lt;br /&gt;
## music - Musikverzeichnis des Users&lt;br /&gt;
## pic / pictures - Bilderverzeichnis des Users&lt;br /&gt;
## prog / program - Programmverzeichnis des Rechners&lt;br /&gt;
## prog86 / program86 - Programm86-Verzeichnis des Rechners&lt;br /&gt;
## '''root''' - Root-Verzeichnis des BAF-Clients bzw. des BAF-Servers&lt;br /&gt;
## '''userroot''' / usrroot - User-Verzeichnis des BAF-Clients&lt;br /&gt;
## video - Videoverzeichnis des Users&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=$DIR(doc)test.txt&lt;br /&gt;
&lt;br /&gt;
==$FILEDIALOG()==&lt;br /&gt;
&lt;br /&gt;
Führt einen Dateiauswahl-Dialog aus und gibt den gewählten Dateinamen zurück. Im Falle des Abbruchs wird ''abort'' zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wenn der erste Parameter ''save'' lautet, wird ein Speichern-Dialog, sonst ein Öffnen-Dialog aufgerufen.&lt;br /&gt;
# Filter-Statement, immer Kombinationen aus Text (Text-Dateien *.txt) und Filter-Statement(*.txt), getrennt durch Pipes.&lt;br /&gt;
# Standard-Dateierweiterung&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=&amp;quot;$FILEDIALOG(save,Text-Dateien *.txt|*.txt|Alle Dateien *.*|*.*,txt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Bitte beachten: Wegen der Leerzeichen im Filter-Statement muss der ganze Parameter in doppelte Anführungszeichen gesetzt werden.)&lt;br /&gt;
&lt;br /&gt;
=ZIP=&lt;br /&gt;
&lt;br /&gt;
==#zip_create==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine ZIP-Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Dateien, die der ZIP-Datei hinzugefügt werden; Funktionen werden ersetzt&lt;br /&gt;
* dir (&amp;quot;directory&amp;quot;) - Verzeichnis, wenn das nicht bei allen fn1, fn2... angegeben werden soll&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Der Dateiname, unter dem die ZIP-Datei gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* fn1, fn2,... (&amp;quot;FileName&amp;quot;) - Die Dateien, die in der ZIP-Datei gespeichert werden; die Anzahl wird mit dem Parameter cnt bestimmt; Funktionen werden ersetzt&lt;br /&gt;
* list - Nummer eines Textes (#text, #text2...), in dem die Dateien gelistet sind, die der ZIP-Datei hinzugefügt werden sollen. Wenn list ein Wert größer 0 hat, werden cnt und fn1, fn2... ignoriert. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* pw (&amp;quot;PassWord&amp;quot;) - Password der erzeugten ZIP-Datei; Funktionen werden ersetzt.&lt;br /&gt;
* pwc (&amp;quot;PassWordCrypted&amp;quot;) - Wenn Y, dann ist das Passwort mit der Verschlüsselungsfunktion auf der Seite Tools des Code-Dialogs verschlüsselt. Hinweis: Mit dieser Verschlüsselung verhindert man lediglich, dass das Passwort direkt aus dem Code ausgelesen werden kann. Wird der BAF-Client mit dem Delphi-Debugger ausgeführt, lässt sich leicht an die betreffende Stelle ein Breakpoint setzen und das Passwort dann im Klartext auslesen (dieselbe Unit uBafCrypt vorausgesetzt).&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #zip_create   fn=$VAR(root).zip   list=1&lt;br /&gt;
 &lt;br /&gt;
 #var_set   n=fn_zip   z=tt_mail_$VAR(reise)-$VAR(reisename)_$PAD($VAR(lfdnr),4,L,0)_$NOWFMT(yyyymmdd).zip&lt;br /&gt;
 #file_op   y=df   fn=$VAR(path)\$VAR(fn_zip)&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=$VAR(filename).txt&lt;br /&gt;
 #code fn2=$VAR(filename).sab&lt;br /&gt;
 #zip_create   dir=$VAR(path)   fn=$VAR(path)\$VAR(fn_zip)    pw=$VAR(pw)   $CODE$&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #zip_create ersetzt nicht vorherige Dateien. Von daher im Zweifelsfall wie im zweiten Beispiel vorher eine Datei dieses Namens löschen.&lt;br /&gt;
&lt;br /&gt;
=Ini-Dateien=&lt;br /&gt;
&lt;br /&gt;
Der BAF-Client verwendet eine Ini-Datei im Root-Verzeichnis (vor allem für die Datenbankverbindungen) und eine Ini-Datei ''BafClientFM.ini'' im User-Anwendungsverzeichnis (vor allem für die Formularpositionen). Es können aber auch weitere Ini-Dateien verwendet werden.&lt;br /&gt;
&lt;br /&gt;
==#ini_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Ini-Datei. #ini_val ist eine nummerierte Prozedur: #ini_val schreibt in die erste Ini-Datei, #ini_val2 in die zweite Ini-Datei und so weiter. Diese Ini-Dateien werden zunächst nur im Speicher gehalten und müssen explizit aus einer Datei geladen oder in eine Datei gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;item&amp;quot; / &amp;quot;ident&amp;quot;) - Name des Eintrags in der Ini-Datei; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Wenn der Parameter n den Wert ''usr'' oder ''user'' hat, dann bleibt die Nummer der Ini-Datei unberücksichtigt und der Wert wird in die Datei ''BafClientFM.ini'' im im User-Anwendungsverzeichnis geschrieben.&lt;br /&gt;
* sec (&amp;quot;section&amp;quot;) - Abschnitt in der Ini-Datei; Funktionen werden ersetzt; default ''values''&lt;br /&gt;
* z - Wert, der in die Ini-Datei geschrieben wird; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_val  i=date_last   z=$NOW()&lt;br /&gt;
&lt;br /&gt;
==#ini_load==&lt;br /&gt;
&lt;br /&gt;
Lädt eine Ini-Datei aus einer Datei. Es handelt sich um eine nummerierte Prozedur: #ini_load lädt die Ini-Datei 1, #ini_load2 lädt die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, die geladen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_load   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==#ini_save==&lt;br /&gt;
&lt;br /&gt;
Speichert eine Ini-Datei ineine Datei. Es handelt sich um eine nummerierte Prozedur: #ini_save speichert die Ini-Datei 1, #ini_save2 speichert die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, in die gespeichert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_save   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==$INI()==&lt;br /&gt;
&lt;br /&gt;
Liest einen Wert aus einer Ini-Datei.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
# Item (Ident)&lt;br /&gt;
# optional: Sektion; wenn nicht vorhanden, dann ''values''. Wenn ''db!'', dann wird als Sektion die aktuell gewählte Datenbankverbindung verwendet (in diesem Fall sollte als erster Parameter ''root'' verwendet werden).&lt;br /&gt;
# optional: Default-Wert; wenn nicht vorhanden, dann ein leerer String&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum)&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum,bearbeitung,$TODAY())&lt;br /&gt;
&lt;br /&gt;
==$INITEXT()==&lt;br /&gt;
&lt;br /&gt;
Gibt die komplette Ini-Datei zurück. Wird vor allem beim Debugging verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $INITEXT(usr)&lt;br /&gt;
&lt;br /&gt;
=Zwischenablage=&lt;br /&gt;
&lt;br /&gt;
Das BAF-Framework unterstützt die Zwischenablage nur für Text.&lt;br /&gt;
&lt;br /&gt;
==#clipboard==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Text in die Zwischenablage&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* z - Wert, der in der Zwischenablage gespeichert werden soll; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #clipboard   z=$TEXT()&lt;br /&gt;
 #clipboard   z=$CHR(dquote)$PVAL(test,zahl,allsel,$CHR(crlf))$CHR(dquote)&lt;br /&gt;
&lt;br /&gt;
==$CLIPBOARD()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Text aus der Zwischenablage zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setvar   n=clp   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
=String-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben einen String zurück.&lt;br /&gt;
&lt;br /&gt;
==$BASE64()==&lt;br /&gt;
&lt;br /&gt;
En- oder Decodiert einen Text im Base64-Code&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Encoding oder Decoding:&lt;br /&gt;
## e - Encoding&lt;br /&gt;
## d - Decoding&lt;br /&gt;
# Text, der en-oder decodet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $BASE64(e,Dies ist ein Test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$CHR()==&lt;br /&gt;
&lt;br /&gt;
Gibt ein Zeichen (ggf zwei Zeichen) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Ansi-Zeichennummer oder eine der folgenden Bezeichnungen:&lt;br /&gt;
## crlf - Zeilenumbruch #13#10&lt;br /&gt;
## cr - Zeichen #13&lt;br /&gt;
## lf - Zeichen #10&lt;br /&gt;
## tab - Tabulator&lt;br /&gt;
## quote - ' (einfache Anführungszeichen)&lt;br /&gt;
## dquote - &amp;quot; (doppelte Anführungszeichen)&lt;br /&gt;
## space / leer - Leerzeichen&lt;br /&gt;
## comma / komma - , (Komma)&lt;br /&gt;
## questionmark / qmark / frage / fragezeichen - ?&lt;br /&gt;
## bro / bracket_open - (&lt;br /&gt;
## brc / bracket_close - )&lt;br /&gt;
## dollar - $&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CONVERT()==&lt;br /&gt;
&lt;br /&gt;
Konvertiert einen String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Konvertierungsfunktion&lt;br /&gt;
## isodate&lt;br /&gt;
## isodatetime&lt;br /&gt;
## truefalse&lt;br /&gt;
## pointfloat&lt;br /&gt;
## urlcode&lt;br /&gt;
## utf8&lt;br /&gt;
# String, der konvertiert werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $CONVERT(isodate,2025-03-12)&lt;br /&gt;
 #coutl $CONVERT(isodatetime,2025-03-12 12:03:17)&lt;br /&gt;
 #coutl $CONVERT(truefalse,true)&lt;br /&gt;
 #coutl $CONVERT(pointfloat,12.3)&lt;br /&gt;
 #coutl $CONVERT(urlcode,Für schönen Ärger)&lt;br /&gt;
 #coutl $CONVERT(utf8,Für schönen Ärger)&lt;br /&gt;
&lt;br /&gt;
(Ergebnis)&lt;br /&gt;
 12.03.2025&lt;br /&gt;
 12.03.2025 12:03:17&lt;br /&gt;
 Y&lt;br /&gt;
 12,3&lt;br /&gt;
 F%C3%BCr%20sch%C3%B6nen%20%C3%84rger&lt;br /&gt;
 Für schönen Ärger&lt;br /&gt;
&lt;br /&gt;
==$COPY()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$COPY($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$EXEC()==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando aus und gibt ein Funktionsergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll.&lt;br /&gt;
# optional: Name der Variable, die als Funktionsergebnis zurück gegeben werden soll; default ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=test   z=$EXEC(testkommando)&lt;br /&gt;
&lt;br /&gt;
==$GUID()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine GUID und gibt sie zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# optional: Name einer Variablen, in welcher die GUID zusätzlich gespeichert wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kid=$GUID()&lt;br /&gt;
&lt;br /&gt;
==$HASH()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt einen Hash-Wert vom String im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, von welchem der Hash gebildet werden soll.&lt;br /&gt;
# zu verwendender Hash-Algorithmus:&lt;br /&gt;
## sha512&lt;br /&gt;
## sha512_256&lt;br /&gt;
## sha512_224&lt;br /&gt;
## sha384&lt;br /&gt;
## sha256&lt;br /&gt;
## sha224&lt;br /&gt;
## sha1&lt;br /&gt;
## md5 (Hinweis: MD5 gilt seit Längerem als nicht mehr sicher. Verwenden Sie ihn nur, wenn dies aus Gründen der Abwärts-Kompatbilität zwingend ist.)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$HASH($PVAL(vl,1,2),sha512)&lt;br /&gt;
&lt;br /&gt;
==$INCLUDE()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass der als dritter Parameter übergebene Text am Anfang oder am Ende steht, gegebenenfalls wird er dort eingefügt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## lead(oder leading) - Text muss am Anfang stehen&lt;br /&gt;
## leadci(oder leadingci oder leadingcaseinsensitive) - Text muss am Anfang stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
## trail(oder trailing) - Text muss am Ende stehen&lt;br /&gt;
## trailci(oder trailci oder trailingcaseinsensitive) - Text muss am Ende stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
# Text, in den gegebenenfalls eingefügt wird&lt;br /&gt;
# Text, der gegebenenfalls eingefügt wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCLUDE(trailci,test.PDF,.pdf)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$INVLOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Key aus einer Nachschlageliste bei Übergabe des Values.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Value des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$INVLOOKUP(general_status,aktiv,Wert nicht vorhanden)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus einer Nachschlageliste.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Key des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$LOOKUP(general_status,1,Status nicht gesetzt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOW()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Kleinbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Kleinbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LOW($EDT(edt1)) = bus&lt;br /&gt;
&lt;br /&gt;
==$LOWNOSPACE()==&lt;br /&gt;
&lt;br /&gt;
Wandelt einen String in Kleinbuchstaben und ersetzt alle Leerzeichen durch Unterstriche.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der gewandelt werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$LOWNOSPACE($PVAL(vl,1,2))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$NOCRLF()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Zeilenumbrüche&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem die Zeilenumbrüche entfernt werden sollen&lt;br /&gt;
# optional: Zeichenfolge, die an Stelle der Zeilenumbrüche eingefügt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=2   z=$NOCRLF($VAL(1),;)&lt;br /&gt;
&lt;br /&gt;
==$NVL()==&lt;br /&gt;
&lt;br /&gt;
Liefert einen Ersatzwert, wenn der Wert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird, wenn der erste Parameter leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   where ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0)&lt;br /&gt;
&lt;br /&gt;
Liefert $PVAL einen leeren Wert zurück (z.B., weil die Gridzeile neu angelegt wurde und daher noch keine Nummer eingetragen ist), so wird statt dessen 0 verwendet, damit die WHERE-Klausel syntaktisch korrekt ist.&lt;br /&gt;
&lt;br /&gt;
==$ONLYCHAR()==&lt;br /&gt;
&lt;br /&gt;
Entfernt unerwünschte Zeichen aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# optional: Typ der Funktion&lt;br /&gt;
## (leer) - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z', 'ä', 'ö', 'ü', 'Ä','Ö', 'Ü', 'ß']) sind&lt;br /&gt;
## charnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind&lt;br /&gt;
## low - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## upp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## charnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## charnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## uml - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z') sind, Umlaute werden konvertiert (ä -&amp;gt; ae, ö -&amp;gt; oe, ü -&amp;gt; ue, Ä -&amp;gt; Ae, Ö -&amp;gt; Oe, Ü -&amp;gt; Ue, ß -&amp;gt; ss)&lt;br /&gt;
## umlcharnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Umlaute werden konvertiert&lt;br /&gt;
## umllow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## no191 / not191 - Es werden alle Zeichen mit der ANSI-Nummer 191 (¿) entfernt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg)&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg,umllow)&lt;br /&gt;
&lt;br /&gt;
==$PAD()==&lt;br /&gt;
&lt;br /&gt;
Füllt links oder rechts bis zur vorgegebenen Länge mit Zeichen auf.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# Soll-Länge. Ist der ursprüngliche String bereits länger, wird er nicht gekürzt, es werden aber auch keine weiteren Zeichen hinzugefügt&lt;br /&gt;
# Wenn L, werden die Zeichen vorne hinzugefügt, andernfalls hinten&lt;br /&gt;
# Zeichen, die soweit und so oft hinzugefügt werden, bis die Soll-Länge erreicht ist. Umfasst der Parameter mehrere Zeichen, werden diese ggf. nicht alle hinzugefügt.&lt;br /&gt;
# optional: Länge, auf die der ursprüngliche String vor der weiteren Verarbeitung gekürzt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   text1 = '$PAD($VAR(text1),70,R, )'&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ des Ergebnisses&lt;br /&gt;
## curr - Zahl mit zwei Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## curr4 - Zahl mit vier Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## date - Datum in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## int - ganze Zahl  in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## ld - Key einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ldv - Value einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ls - Key eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## lsv - Value eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## text, text2, text3... - Zeile eines Textes&lt;br /&gt;
# untere Grenze bzw. Name der Nachschlageliste oder des Specials&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $RANDOM(date,01.01.2022,31.12.2022)&lt;br /&gt;
 #coutl $RANDOM(text2)&lt;br /&gt;
&lt;br /&gt;
==$SUBSTR()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Selbe Funktionalität wie $COPY())&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$SUBSTR($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$STREP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string replace&amp;quot;) Ersetzt Zeichen im String durch andere Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, in welchen Zeichen ersetzt werden sollen.&lt;br /&gt;
# Zeichen, die ersetzt werden sollen&lt;br /&gt;
# Zeichen, die an deren Stelle treten sollen&lt;br /&gt;
# optional: Optionen (kombinierbar)&lt;br /&gt;
## i - Groß- und Kleinschreibung ignorieren &lt;br /&gt;
## a - Alle Vorkommen ersetzen (andernfalls wird nur das erste Vorkommen ersetzt)&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=&amp;quot;$STREP($PVAL(vl,1,2), ,_,a)&amp;quot;&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$STREP($PVAL(vl,1,2),$CHR(space),_,a)&lt;br /&gt;
&lt;br /&gt;
Hinweis: Beide Beispiele haben exakt dieselbe Funktion. Im oberen Beispiel steht das Leerzeichen direkt im Text, dafür muss der komplette Parameter in doppelte Anführungszeichen, im unteren Beispiel wird das Leerzeichen durch $CHR(space) eingefügt, dafür können die Leerzeichen unterbleiben.&lt;br /&gt;
&lt;br /&gt;
==$STROP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string operation&amp;quot;) Sammelsurium von String-Operationen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## trim - entfernt führende und folgende Leerzeichen&lt;br /&gt;
## trimleft - entfernt führende Leerzeichen&lt;br /&gt;
## trimright - entferne folgende Leerzeichen&lt;br /&gt;
## quote - setzt den String in einfache Anführungszeichen&lt;br /&gt;
## unquote - entfernt einschließende einfache Anführungszeichen&lt;br /&gt;
## dquote - setzt den String in doppelte Anführungszeichen&lt;br /&gt;
## unqduote - entfernt einschließende doppelte Anführungszeichen&lt;br /&gt;
## ex_filepath - entspricht der Delphi-Funktion ExtractFilePath&lt;br /&gt;
## ex_filedir - entspricht der Delphi-Funktion ExtractFileDir&lt;br /&gt;
## ex_filedrive - entspricht der Delphi-Funktion ExtractFileDrive&lt;br /&gt;
## ex_filename - entspricht der Delphi-Funktion ExtractFileName&lt;br /&gt;
## ex_fileext - entspricht der Delphi-Funktion ExtractFileExt&lt;br /&gt;
# String, der bearbeitet werden soll&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$STROP(quote,Test)&lt;br /&gt;
&lt;br /&gt;
==$STREXTR()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string extract&amp;quot;) Extrahiert einen Teil aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem extrahiert werden soll&lt;br /&gt;
# Extraktionstyp&lt;br /&gt;
## ffe (&amp;quot;from first exclude&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## ffi (&amp;quot;from first include&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tfe (&amp;quot;to first exclude&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tfi (&amp;quot;to first include&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## fle (&amp;quot;from last exclude&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## fli (&amp;quot;from last include&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tle (&amp;quot;to last  exclude&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tli (&amp;quot;to last include&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Trennzeichen&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffe,;)&amp;quot;    -- Ergebnis: test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffi,;)&amp;quot;    -- Ergebnis: ;test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfe,;)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfi,;)&amp;quot;    -- Ergebnis: test;&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;!§§test2,tfe,;!§§)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
&lt;br /&gt;
==$TRIM()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Leerzeichen und Zeilenumbrüche am Rand des Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der getrimmt werden soll&lt;br /&gt;
# optional&lt;br /&gt;
## L - trimmt nur auf der linken Seite&lt;br /&gt;
## R - trimmt nur auf der rechten Seite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$TRIM($VAL(1),R)&lt;br /&gt;
&lt;br /&gt;
==$UPP()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Großbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Großbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $UPP($EDT(edt1)) = BUS&lt;br /&gt;
&lt;br /&gt;
==$VT()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VT (&amp;quot;Value Translate&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Vergleichswert 1&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 1 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 2&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 2 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 3&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 3 dem ersten Parameter entspricht &lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VT(Frau,1,Herr,2,Frau,3)&lt;br /&gt;
 -- Frau -&amp;gt; 3&lt;br /&gt;
 -- Herr -&amp;gt; 2&lt;br /&gt;
 -- Test -&amp;gt; 1&lt;br /&gt;
 -- Firma -&amp;gt; 1&lt;br /&gt;
&lt;br /&gt;
==$VTVL()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VTVL (&amp;quot;Value Translate ValueList&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu $VT werden die zu prüfenden Werte und deren Entsprechungen nicht über Parameter übergeben, sondern aus einer Werte-Liste geholt, die in einem Text gespeichert sein muss.&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich wie folgt aufbauen&lt;br /&gt;
&lt;br /&gt;
 key1=value1&lt;br /&gt;
 key2=value2&lt;br /&gt;
 key3=value3&lt;br /&gt;
 key4=value4&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich auch mit #sql_opentvl erzeugen, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Nummer des Textes, in dem sich die Werteliste befindet.&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select userid as ckey, shortname as cvalue from user_user&lt;br /&gt;
 #sql_opentvl n=1&lt;br /&gt;
 #coutl $VTVL(591,(nicht gefunden),1)&lt;br /&gt;
&lt;br /&gt;
==$XR()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $XR (&amp;quot;XmlReplace&amp;quot;) ersetzt in XML nicht zulässige Zeichen:&lt;br /&gt;
* aus &amp;amp; wird $amp ;&lt;br /&gt;
* aus &amp;lt; wird &amp;amp;lt ;&lt;br /&gt;
* aus &amp;gt; wird &amp;amp;gt ;&lt;br /&gt;
* aus &amp;quot; wird &amp;amp;quot ;&lt;br /&gt;
* aus ' wird &amp;amp;apos ;&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Das Leerzeichen vor dem Semikolon soll verhindern, dass die Zeichen hier in der Darstellung ersetzt werden und wird nicht eingefügt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text &amp;lt;firmenname&amp;gt;$XR($DATA(dat,firmenname))&amp;lt;/firmenname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==$XRR()==&lt;br /&gt;
&lt;br /&gt;
Umkehrfunktion von $XR()&lt;br /&gt;
* aus $amp ; wird &amp;amp;&lt;br /&gt;
* aus &amp;amp;lt ; wird &amp;lt;&lt;br /&gt;
* aus &amp;amp;gt ; wird &amp;gt;&lt;br /&gt;
* aus &amp;amp;quot ; wird &amp;quot;&lt;br /&gt;
* aus &amp;amp;apos ; wird '&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
=Integer-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben eine ganze Zahl zurück&lt;br /&gt;
&lt;br /&gt;
==$DEC()==&lt;br /&gt;
&lt;br /&gt;
Verringert die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die verringert werden soll.&lt;br /&gt;
# optional: Zahl, um die verringert werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$DEC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ICALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit ganzzahligen Werten durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator, es stehen zur Verfügung&lt;br /&gt;
## +&lt;br /&gt;
## -&lt;br /&gt;
## *&lt;br /&gt;
## div&lt;br /&gt;
## mod&lt;br /&gt;
# Erste Zahl&lt;br /&gt;
# Zweite Zahl&lt;br /&gt;
# optional beim Operator +: weitere Summanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$ICALC(mod,17,5)&lt;br /&gt;
&lt;br /&gt;
==$INC()==&lt;br /&gt;
&lt;br /&gt;
Erhöht die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die erhöht werden soll.&lt;br /&gt;
# optional: Zahl, um die erhöht werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$INC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$INTLEN()==&lt;br /&gt;
&lt;br /&gt;
Ist der String im Parameter eine ganz Zahl, dann wird deren Länge in Zeichen zurückgegeben, andernfalls -1; ein leerer String im ersten Parameter ergibt 0.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, deren Länge ermittelt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTLEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Länge eines Strings in Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Länge ermittelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEVENSHTEIN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Levenshtein-Distanz (https://de.wikipedia.org/wiki/Levenshtein-Distanz) der beiden übergebenen Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# erster String&lt;br /&gt;
# zweiter String&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $LEVENSHTEIN(alpha,beta)&lt;br /&gt;
&lt;br /&gt;
==$POS()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Position des Substrings in einem String. Das Funktionsergebnis ist die Position, das erste Zeichen ist 1. 0 wird zurück gegeben, wenn der Substring im String nicht vorkommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Substring (nach dem gesucht wird)&lt;br /&gt;
# String (in dem gesucht wird)&lt;br /&gt;
# optional: Wenn ic (ignore case), dann wird bei der Suche die Groß- und Kleinschreibung nicht beachtet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $POS($EDT(edt1),$VAR(1),ic) &amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert zwischen der oberen und unteren Grenze&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ&lt;br /&gt;
## int - zufällige Ganzzahl &lt;br /&gt;
## date - zufälliges Datum &lt;br /&gt;
## curr - zufällige Zahl mit zwei Nachkommastellen&lt;br /&gt;
## curr4 - zufällige Zahl mit vier Nachkommastellen&lt;br /&gt;
## text1, text2, text3... - zufällige Zeile aus dem jeweiligen Text; text ist text1; untere und obere Grenze bleiben unberücksichtigt&lt;br /&gt;
## ld - zufälliger Schlüssel-Wert aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ldv - zufälliger Text aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ls - zufälliger Schlüssel-Wert aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## lsv - zufälliger Text aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
# untere Grenze&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $RANDOM(int,1,6)&lt;br /&gt;
&lt;br /&gt;
=Datumsfunktionen=&lt;br /&gt;
&lt;br /&gt;
==$INCDATE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktione  $INCDATE() verändert das Datum im ersten Parameter um die Anzahl Tage im zweiten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das verändert werden soll&lt;br /&gt;
# optional: Die Tage, um die verändert werden soll; wenn leer, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCDATE($NOW(),-3)   clr=Y&lt;br /&gt;
&lt;br /&gt;
==$INT2TIME()==&lt;br /&gt;
&lt;br /&gt;
Macht aus z.B. 1130 die Zeit 11:30&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zeit im Integer-Format&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_time=$INT2TIME($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$NOW()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit im Format dd.mm.yyyy hh:mm:ss zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #execsql   k_datechg=$NOW()&lt;br /&gt;
&lt;br /&gt;
==$NOWFMT()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und/oder die aktuelle Uhrzeit im angegebenen Format zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Formatierungsstring (Syntax wie FormatDateTime in Delphi)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$NOWFMT(yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$NOWMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit ohne Sekunden (also dd.mm.yyyy hh:mm) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$NOWMIN()&lt;br /&gt;
&lt;br /&gt;
==$TODAY()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum im Format dd.mm.yyyy zurück.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Wenn das Datum in einem anderen Format benötigt wird, ist $NOWFMT() das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$TODAY()&lt;br /&gt;
&lt;br /&gt;
==$DFMT()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;date formated&amp;quot;) Formatiert das übergebene Datum. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, ggf. mit Uhrzeit, das formatiert werden soll.&lt;br /&gt;
# Formatierungsstring wie in Delphi&lt;br /&gt;
# optional: Wenn hn (&amp;quot;hide null&amp;quot;), dann wird ein leerer String zurück gegeben, wenn das Datum kleiner/gleich 1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$DFMT($NOW(),yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Bool'sche Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
==$BFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert einen bool'schen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'scher Wert&lt;br /&gt;
# optional: Ergebnis, wenn Wert Y ('y', 'J', 'j', '1') ist, default Y&lt;br /&gt;
# optional: Ergebnis, wenn Wert N (also nicht 'Y', 'y', 'J', 'j', '1') ist, default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cout   c=$BFMT($VAR(test),x,)&lt;br /&gt;
&lt;br /&gt;
==$BOOL()==&lt;br /&gt;
&lt;br /&gt;
Wertet das bool'sche Statement im Parameter aus.&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
* = gleich&lt;br /&gt;
* == gleich ohne Berücksichtigung der Groß- und Kleinschreibung&lt;br /&gt;
* &amp;lt;&amp;gt; ungleich&lt;br /&gt;
* != ungleich&lt;br /&gt;
* &amp;gt; größer&lt;br /&gt;
* &amp;gt;= größer gleich&lt;br /&gt;
* &amp;lt; kleiner&lt;br /&gt;
* &amp;lt;= kleiner gleich &lt;br /&gt;
* and Und-Verknüpfung&lt;br /&gt;
* or ODER-Verknüpfung&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Statements werden von links nach rechts ausgewertet, and und or sind gleichwetig, gegebenenfalls müssen Klammern eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'sches Statement, das ausgewertet wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL((17 &amp;gt; 22) or (5 &amp;gt; 3))&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL(17 &amp;gt; 22 or 5 &amp;gt; 3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATECOMP()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn Datum 2 Operator Datum 1 zutreffend ist. Ansonsten wird N zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Wird kein Operator angegeben, dann wird die Anzahl der Tage Datum 2 - Datum 1 als Zahl zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum 1&lt;br /&gt;
# Datum 2&lt;br /&gt;
# Operator&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024,&amp;lt;)&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATEMINREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMINREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEMAXREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMAXREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in ein Datum wandeln lassen, werden zu 0 (30.12.1899) konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter diesem Datum entspricht. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;Test $DATEBETWEEN($TODAY(),1.1.2020,2.2.2022)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$EMPTY()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Parameter ein leerer String ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTY($DATE(n,grpname))&lt;br /&gt;
&lt;br /&gt;
==$EMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable ein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTYVAR(buchungsnr)&lt;br /&gt;
&lt;br /&gt;
==$IN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INIC() beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die erste Anweisung gibt Y und die zweite N zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INIC()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $IN() nicht beachtet beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen geben Y zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich die Variable, deren Namen im ersten Parameter steht, in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INICVAR() beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable, die geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die erste Anweisung gibt Y und die zweite N zurück&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=beta&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INICVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich die Variable, deren Namen im ersten Parameter steht, in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INVAR() nicht beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable, die geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen geben Y zurück&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=beta&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$ISCURR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen Currency-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISCURR($DATA(n,rechnungssumme))&lt;br /&gt;
&lt;br /&gt;
==$ISDATE()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in ein Datums- oder DatumsZeit-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Prüfoperation, default ist date&lt;br /&gt;
## date - prüft, ob in ein Datum gewandelt werden kann&lt;br /&gt;
## datetime - prüft, ob in ein Datums-Zeit-Wert gewandelt werden kann&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISDATE($DATA(n,beginn))&lt;br /&gt;
&lt;br /&gt;
==$ISINT()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen ganzzahligen Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISINT($DATA(n,tage))&lt;br /&gt;
&lt;br /&gt;
==$INTMAX()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMAX($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$INTMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMIN($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$NEMPTY()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;not empty&amp;quot;) Gibt Y zurück, wenn der Parameter nicht leer ist. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalt geprüft wird. Leerzeichen gelten als leerer String.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 &lt;br /&gt;
 ~ $NEMPTY($EDT(edt1))&lt;br /&gt;
&lt;br /&gt;
==$NEMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable kein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $NEMPTYVAR(kundennr)&lt;br /&gt;
&lt;br /&gt;
==$NOT==&lt;br /&gt;
&lt;br /&gt;
Invertiert einen bool'schen Wert. Aus Y (y, J, j, 1) wird N und aus N wird Y.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der invertiert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $NOT(2)&lt;br /&gt;
&lt;br /&gt;
==$NUMBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in eine Zahl wandeln lassen, werden zu 0 konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter dieser Zahl entspricht. Siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56,)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die beiden Beispiele unterscheiden sich auf den ersten Blick kaum. Bei der ersten Zeile muss jedoch eine Schuhgröße eingegeben werden. Bleibt das Feld im VL-Segment leer, so wird dieser fehlende Wert nach 0 konvertiert und liegt nicht zwischen 28 und 56.&lt;br /&gt;
&lt;br /&gt;
Anders bei der zweiten Zeile: Das Komma vor der schließenden Klammer sorgt für einen vierten Parameter, der ebenfalls leer ist und damit nach 0 gewandelt wird. Auf diese Weise werden die leere Eingaben (und die Eingabe von 0) gültig.&lt;br /&gt;
&lt;br /&gt;
==$REGEX()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $REGEX() (&amp;quot;regular expressions&amp;quot;) prüft, ob der String in Parameter 1 den Anforderungen von Parameter 2 entspricht (Ergebnis Y) oder nicht (Ergebnis N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft werden soll&lt;br /&gt;
# Regulärer Ausdruck, mit dem der String in Parameter 2 geprüft wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $REGEX($VAR(med),^[A-Z]{3}$)&lt;br /&gt;
&lt;br /&gt;
==$TEXT_HASLINE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $TEXT_HASLINE() prüft, ob die als Parameter 2 übergebene Textzeile in einem Text vorkommt. Es wird nur auf komplette Textzeilen geprüft. Wird zum Beispiel verwendet, um eine Liste von Kundennummern zu erstellen, und dann auf einzelne Nummern zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# Textzeile, deren Vorkommen geprüft wird&lt;br /&gt;
# Ergebnis, wenn die Textzeile vorkommt; default Y&lt;br /&gt;
# Ergebnis, wenn die Textzeile nicht vorkommt; default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $TEXT_HASLINE(1,990000018,1,0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$VIBAN()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VIBAN() (&amp;quot;validate IBAN&amp;quot;) prüft eine IBAN anhand der Prüfziffern (3. und 4. Stelle).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# IBAN, die geprüft werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VIBAN(DE12345)&lt;br /&gt;
&lt;br /&gt;
=Currency-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==$CCALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit Festkommawerten durch&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
** + - Addition&lt;br /&gt;
** - - Subtraktion&lt;br /&gt;
** * - Multiplikation&lt;br /&gt;
** / - Division&lt;br /&gt;
** % - Division und Multiplikation des Ergebnisses mit 100&lt;br /&gt;
** +4 - Addition und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** -4 - Subtraktion und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** *4 - Multiplikation und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** /4 - Division und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** %4 - Division, Multiplikation des Ergebnisses mit 100 und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
** B, b, B4, b4 - Bruttobetrag, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** E, e, E4, e4 - Enthaltene MWSt, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** M, m, M4, m4 - MWSt, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** N, n, N4, n4 - Nettobetrag, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator&lt;br /&gt;
# und weitere: Operanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 10&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(+,1,2,3,4)&amp;quot;&lt;br /&gt;
 -- Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #val_set   n=1   z=1038,87&lt;br /&gt;
 #coutl $CCALC(N,$VAL(1),19)  -  $CCALC(E,$VAL(1),19)  -&lt;br /&gt;
&lt;br /&gt;
==$CURR()==&lt;br /&gt;
&lt;br /&gt;
Currency-Werte müssen in Funktionen mit einem Punkt als Dezimaltrennzeichen eingegeben werden, da das Komma die Parameter trennt. Sofern Konstanten verwendet werden, lässt sich das einfach so eingeben, sobald aber die Werte aus anderen Funktionen kommen (zum Beispiel $DATA()), müssen sie dann mit $CURR() in dieses Format umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Vorkommastellen&lt;br /&gt;
# Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 43,48&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,$CURR(2,3))&amp;quot;&lt;br /&gt;
 -- zum Vergleich; Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert Curreny-Werte&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert&lt;br /&gt;
# optional: Formatierungsstring, default 0.00&lt;br /&gt;
# optional: wenn hn (&amp;quot;hide null&amp;quot;), dann werden leere Strings als Wert auch als leerer String ausgegeben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=###,###,###,##0.00&lt;br /&gt;
 #val_set   n=2   z=1337,42&lt;br /&gt;
 #cout   c=$CFMT($VAL(2),$VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ONLYNUM()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass in einem String nur Zahlen (ggf. auch Kommas oder Punkte) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl&lt;br /&gt;
# Art der Operation; default numkomma&lt;br /&gt;
## flnnc (&amp;quot;from last not numeric character&amp;quot;) - Ab dem letzten Zeichen, das keine Ziffer ist&lt;br /&gt;
## num - Nur Ziffern, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numkomma - Nur Ziffern und Kommata, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numpoint - Nur Ziffern und Punkte, alle anderen Zeichen werden entfernt&lt;br /&gt;
## ufnnc (&amp;quot;until first not numeric character&amp;quot;) - vom Anfang bis zum ersten Zeichen, das keine Ziffer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 -- Ergebnis 123456&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,num)&lt;br /&gt;
 -- Ergebnis 123&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,ufnnc)&lt;br /&gt;
 -- Ergebnis 456 &lt;br /&gt;
 #coutl   $ONLYNUM(123-456,flnnc)&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22521</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22521"/>
		<updated>2025-06-10T17:53:48Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #tree_node */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* iek (&amp;quot;ignore empty key&amp;quot;) - wenn Y, dann wird kein Eintrag im Baum erzeugt, wenn die jeweilige Wert in der mit k bezeichneten Spalte (ggf. über t abgeleitet) leer ist. Siehe Beispiel&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel für iek=Y. Sofern es keine Zubringer gibt, wird auch der entsprechende Eintrag sowie dessen beiden Untereinträge (''Passagierliste'' und ''Angebote und Aufträge'') nicht eingefügt. Es ist zu beachten, dass die Parameter iek=Y sowie k=zubringer auch bei den beiden Untereinträgen zu setzen sind.&lt;br /&gt;
&lt;br /&gt;
 #tree_node   u=o   t=bus_touren   c1=tournr   c2=c2   f_zielbus=!   nc=Y   s=&amp;quot;#page_fill   d=xbus_page_br_tour(hb)&amp;quot;   nc=Y&lt;br /&gt;
 #tree_node   u=l   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(hb)&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote&amp;quot;&lt;br /&gt;
 #tree_node   u=lp   k=rueckbus   c1=r_tournr   c2=r2   nc=Y   f_bus_touren_id=rueckbus   f_tournr=r_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(r)&amp;quot;   cnd=$FND(o,bit_pendelreise)&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c1=z_tournr   c2=z2   nc=Y   f_bus_touren_id=zubringer   f_tournr=z_tournr   s=&amp;quot;#page_fill   d=xbus_page_br_tour(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=l   k=zubringer   c=Passagierliste   s=&amp;quot;#page_fill   d=xbus_page_br_tour_pl(zu)&amp;quot;   iek=Y&lt;br /&gt;
 #tree_node   u=lp   k=zubringer   c=&amp;quot;Angebote und Aufträge&amp;quot;   s=&amp;quot;#page_fill   d=xbus_page_br_tour_angebote_zu&amp;quot;   iek=Y&lt;br /&gt;
 #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22520</id>
		<title>Modul VAR neu</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22520"/>
		<updated>2025-06-10T17:48:40Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* $INIC() */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das Modul Var sammelt neben den Variablen auch die grundlegenden Prozeduren und Funktionen.&lt;br /&gt;
&lt;br /&gt;
=Variable=&lt;br /&gt;
&lt;br /&gt;
==#var_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#setvar setzt den Wert einer Variablen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis: Variable sind global, auf sie kann auch in Sub-Kommandos zugegriffen werden. Values sind dagegen lokal.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*rf (replace functions) - Wenn Y, dann werden nach der Zuweisung auf die Variable nochmals die Funktionen ersetzt. Wird zum Beispiel benötigt, wenn Code mit Funktionen mittels $DATA() aus der Datenbank geladen wird; Funktionen werden ersetzt, default N; siehe Beispiel&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_set   n=test2  z=$GUID()&lt;br /&gt;
 #var_set   n=edt    z=$EDT(edt1)   ie=42&lt;br /&gt;
 #var_set   n=_page_kunde_adressänderung_ro   z=N   zn=Y   zr=Y   r=kundenservice&lt;br /&gt;
&lt;br /&gt;
Zum Parameter rf: $NOW() in die Zwischenablage kopieren und dann ausführen:&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=N&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=Y&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_setempty==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_setempty setzt den Wert einer Variablen, sofern sie (noch) leer ist.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Besteht der Variableninhalt aus Leerzeichen, gilt die Variable auch als leer.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_setempty   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_setempty   n=test2  z=$GUID()&lt;br /&gt;
 #var_setempty   n=edt    z=$EDT(edt1)    ie=42&lt;br /&gt;
&lt;br /&gt;
==#var_add==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_add fügt einer Variablen einen Wert hinzu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. &lt;br /&gt;
* y -Typ der Operation; default ''text''&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** month - Es wird dem Datum eine Anzahl von Monaten hinzugefügt&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
*z - Wert, welcher der Variablen hinzugefügt wird, Funktionen werden ersetzt, default ist ein leerer String oder eine 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$NOW()&lt;br /&gt;
 #var_add   n=test   z=1   y=datetime&lt;br /&gt;
 #cout   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_log==&lt;br /&gt;
&lt;br /&gt;
Schreibt den Inhalt aller Variablen in das Debug-Log.&lt;br /&gt;
&lt;br /&gt;
Wird nur zur Fehlersuche verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_log&lt;br /&gt;
&lt;br /&gt;
==$VAR()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $VAR() wird auf den Inhalt der Variable zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
# optional: Der Wert wird vor oder nach der Rückgabe als Funktionsergebnis verändert; nur für ganzzahlige Werte&lt;br /&gt;
## ib (&amp;quot;increment before&amp;quot;) - Der Wert wird vor der Rückgabe um eins erhöht&lt;br /&gt;
## db (&amp;quot;decrement before&amp;quot;) - Der Wert wird vor der Rückgabe um eins verringert&lt;br /&gt;
## ia (&amp;quot;increment after&amp;quot;) - Der Wert wird nach der Rückgabe um eins erhöht&lt;br /&gt;
## da (&amp;quot;decrement after&amp;quot;) - Der Wert wird nach der Rückgabe um eins verringert&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #message  c=$VAR(test)&lt;br /&gt;
 #var_set  n=neuer_wert   z=$VAR(wert)   ie=$VAR(alternativwert)&lt;br /&gt;
 #execsql   k_lfdnr=$VAR(lfdnr,ib)&lt;br /&gt;
&lt;br /&gt;
=Kommandos=&lt;br /&gt;
&lt;br /&gt;
(Primär- und Sub) Kommandos sind üblicherweise benannt und werden im Code-Dialog eingegeben.&lt;br /&gt;
&lt;br /&gt;
Es besteht jedoch auch die Möglichkeit, lokale Kommandos innerhalb eines anderen Kommandos zu definieren. Diese Kommandos haben statt eines Kommando-Namens dann dann eine Kommando-Nummer.&lt;br /&gt;
&lt;br /&gt;
Lokale Kommandos werden üblicherweise für folgende Zwecke verwendet:&lt;br /&gt;
&lt;br /&gt;
* Bei der Verwendung von xlive werden bisweilen Prozeduren eingesetzt, die ihrerseits ein Kommando aufrufen (z.B. #sql_open). Wenn dieses Kommando nichts bereits existiert, kann es nur als lokales Kommando erstellt werden.&lt;br /&gt;
&lt;br /&gt;
* Wenn das auszuführende Kommando auf derselben Seite stehen soll wie die aufrufende Prozedur.&lt;br /&gt;
&lt;br /&gt;
Siehe als Beispiel: [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd fügt dem Kommando eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd fügt dem ersten Kommando eine Zeile hinzu, #cmd2 fügt dem zweiten Kommando eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd hat keine benannten Parameter. Die ganze Zeile nach dem #cmd und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd3 #text $DATA(n,login);$DATA(n,shortname);$DATA(n,firstname);$DATA(n,lastname);$DATA(n,userid);&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clear löscht ein Kommando&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd_clear löscht das erste Kommando, #cmd_clear2 löscht das zweite Kommando, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #cmd_clear Zeichen, so werden die dem gerade gelöschten Kommando hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear3&lt;br /&gt;
 #cmd_clear #grd_add   i=grid   f_logtext=&amp;quot;Kunde angerufen und nicht erreicht.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#cmd_clearall==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clearall löscht alle Kommandos&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clearall&lt;br /&gt;
&lt;br /&gt;
=CSV=&lt;br /&gt;
&lt;br /&gt;
Die CSV-Routinen werden verwendet, um CSV-Dateien einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==#csv_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_open öffnet eine CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_open öffnet die erste CSV-Datei, #csv_open2 öffnet die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*ber - wenn Y, werden die Zeilenumbrüche innerhalb von Feldern durch Leerzeichen ersetzt. Die Felder müssen dabei in doppelten Anführungszeichen eingeschlossen sein.&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - (&amp;quot;Filename&amp;quot;) Dateiname der CSV-Datei&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich. Muss bereits hier gesetzt werden, wenn mit $CSV_LINE auf den Header zugegriffen werden soll, bevor #csv_line ausgeführt wird.&lt;br /&gt;
*txt (&amp;quot;Text&amp;quot;) - alternativ zum Dateinamen fn die Nummer eines Textes, der als CSV-Datei verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open  fn=c:\temp\text.csv&lt;br /&gt;
&lt;br /&gt;
==#csv_line==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_line geht zeilenweise durch die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_line geht durch die erste CSV-Datei, #csv_line2 geht durch die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;database&amp;quot;) - Die Datenbank, für welche die Transaktion ausgeführt wird, wenn ert=Y gesetzt ist. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
*er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
*ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt, Funktionen werden ersetzt&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich.&lt;br /&gt;
*m (&amp;quot;maximum&amp;quot;) - Maximale Anzahl der Zeilen, die verarbeitet wird. Wird gerne bei der Entwicklung verwendet, um die Bearbeitungsgeschwindigkeit zu erhöhen. Funktionen werden ersetzt&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird im Falle einer Exception die Bearbeitung nicht abgebrochen, sondern lediglich Warnungen geloggt; Default N, Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Semikolon, Funktionen werden ersetzt&lt;br /&gt;
*trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_line  er=test_csv_line   hhr=Y   m=3&lt;br /&gt;
&lt;br /&gt;
==#csv_check==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_check prüft die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnt (&amp;quot;count&amp;quot;) - Anzahl der Header-Einträge, die geprüft wird; Funktionen werden ersetzt&lt;br /&gt;
*h1, h2... (&amp;quot;header&amp;quot;) - Eintrag im Header, der auf existenz geprüft wird; Groß und Kleinschreibung ist unerheblich, Funktionen werden ersetzt.&lt;br /&gt;
*n (&amp;quot;name&amp;quot; / &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in die/den das Ergebnis (Y oder N) geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*res (&amp;quot;result&amp;quot;) - Name der Variable oder Nummer des Values, in die/den der Ergebnistext geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwischen den einzelnen Spalten; Funktionen werden ersetzt&lt;br /&gt;
*y - Typ der Prüfung; Funktionen werden ersetzt, default header&lt;br /&gt;
** header - Prüft die Existenz von Spaltennamen im Header. Die zu prüfenden Spaltennamen werden als h1, h2... übergeben, cnt ist entsprechend zu setzen. Wenn alle geprüften Spaltennamen vorhanden sind, wird Y zurück gegeben, ansonsten N. Die fehlenden Spaltennamen werden als Ergebnistext zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open   fn=C:\temp\mad\done\MTF3108_ET2607_selektion.CSV&lt;br /&gt;
 #csv_check   n=1   res=2   cnt=3   h1=eins   h2=zwei   h3=drei&lt;br /&gt;
 #coutl $VAL(1) - $VAL(2)&lt;br /&gt;
&lt;br /&gt;
==#csv_paste==&lt;br /&gt;
&lt;br /&gt;
Übernimmt eine CSV-Datei aus der Zwischenablage. Auf die Werte kann mit $SEPLINE() zugegriffen werden, siehe [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
'''Multi-Row'''&lt;br /&gt;
&lt;br /&gt;
Mit dem Multi-Row-Modus können Daten eingelesen werden, die in einer Zeile mehrere gleichartige Werte haben.&lt;br /&gt;
&lt;br /&gt;
Daten, die im Single-Row-Modus wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465&lt;br /&gt;
 01.01.2020     8574&lt;br /&gt;
 01.01.2020     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     3456&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     4457&lt;br /&gt;
 03.01.2020     7658&lt;br /&gt;
&lt;br /&gt;
Würden im Multi-Row-Modus wie folgt aussehen (und könnten auch so eingelesen werden):&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465     8574     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436     6578     3456     6578     4457     7658&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Wenn dieser Parameter einen Wert hat, dann muss die kopierte CSV-Datei in der ersten Zeile auch diesen Wert haben, oder die Aktion wird abgebrochen; Funktionen werden ersetzt&lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden.&lt;br /&gt;
* mrs (&amp;quot;multi row start&amp;quot;) - Erste Spalte für den Multi-Row-Bereich&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Tabulatorzeichen&lt;br /&gt;
* trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ; default s&lt;br /&gt;
** m - multi; siehe Abschnitt Multi-Row&lt;br /&gt;
** s - single; die CSV-Datei wird Zeile für Zeile eingelesen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
* [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
 #csv_paste   er=imp_line   hhr=Y&lt;br /&gt;
 #csv_paste   er=imp_line   y=m   mrs=1&lt;br /&gt;
&lt;br /&gt;
==$CSV()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV() greift auf einen Feldinhalt der aktuellen CSV-Zeile zu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Spalte oder 0-relative Spaltennummer. Name der Spalte setzt voraus, dass bei #csv_line der Parameter hhr gleich Y ist.&lt;br /&gt;
# optional: Stelle der Zeichens, ab dem der Inhalt des CSV-Feldes zurück gegeben wird&lt;br /&gt;
# optional: Anzahl der Zeichen, die maximal zurück gegeben werden; wird meist dafür verwendet, damit die maximale Länge von Datenbankfeldern nicht überschritten wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0)&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird in der ersten CSV-Datei (#csv_open) auf die erste Spalte (0, da 0-relativ) zugegriffen.&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0,1,30)&lt;br /&gt;
&lt;br /&gt;
Wie oben, nur werden nur die ersten 30 Zeichen zurück gegeben&lt;br /&gt;
&lt;br /&gt;
==$CSV_LINE()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV_LINE() Gibt eine ganze Zeile einer CSV-Datei zurück&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Zeile: header gibt die Header-Zeile zurück, current die aktuelle Zeile in #csv_line&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CSV_LINE wird insbesondere dafür verwendet, um CSV-Dateien mit Daten zu ergänzen. Hier im Beispiel wird jede Zeile mit einer GUID ergänzt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #text $CSV_LINE(1,current)$GUID();&lt;br /&gt;
 &lt;br /&gt;
 #csv_open   fn=c:\temp\ex.csv   hhr=Y&lt;br /&gt;
 #text_clear $CSV_LINE(1,header)guid;&lt;br /&gt;
 #csv_line   er=1   hhr=Y&lt;br /&gt;
 &lt;br /&gt;
 #text_save   fn=c:\temp\ex2.csv&lt;br /&gt;
&lt;br /&gt;
Nach dem Öffnen der bestehenden CSV-Datei (es muss hier bereits hhr gesetzt werden) wird zunächst der Header in Text 1 eingefügt, ergänzt um die Spalte ''guid'' und das abschließende Semikolon. Danach gehen wir mit #csv_line durch alle Zeile, fügen diese komplett in Text 1 ein und hängen eine GUID hinten dran. Danach wird die Datei gespeichert.&lt;br /&gt;
&lt;br /&gt;
=Text=&lt;br /&gt;
&lt;br /&gt;
==#text==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text fügt dem Text eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text fügt dem ersten Text eine Zeile hinzu, #text2 fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Und jetzt noch eine GUID: $GUID()&lt;br /&gt;
 #text Der folgende Text kommt in Großbuchstaben: $UPP(hello world)&lt;br /&gt;
&lt;br /&gt;
==#textn==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#textn fügt dem Text eine Zeile hinzu. Im Unterschied zu #text werden dabei keine Funktionen ersetzt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #textn fügt dem ersten Text eine Zeile hinzu, #text2n fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #textn und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden dabei '''nicht''' ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #textn Zeile 1&lt;br /&gt;
 #textn Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_clear löscht einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_clear löscht den ersten Text, #text_clear2 löscht den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #text_clear Zeichen, so werden die dem gerade gelöschten Text hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear7&lt;br /&gt;
 #text7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
Das vorangestellt #text_clear stellt sicher, dass Text7 leer ist. Alternativ könnte man formulieren:&lt;br /&gt;
&lt;br /&gt;
 #text_clear7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_save==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_save speichert einen Text in einer Datei.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_save speichert den ersten Text, #text_save2 speichert den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* bom (&amp;quot;Byte order mark&amp;quot;) - Wenn Y, dann wird die Datei mit BOM geschrieben; default Y&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu speichernden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname, unter dem die Datei gespeichert wird. Bestehende Dateien werden überschrieben, sofern das Betriebssystem das nicht verhindert (z.B, weil die Datei gerade geöffnet ist)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Öffnet die gespeicherte Datei gleich anschließend.&lt;br /&gt;
*sort - Wenn Y, dann wird die Datei vor dem Speichern sortiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Hello world&lt;br /&gt;
 #text_save  fn=$DIR(userroot)hello_world.txt&lt;br /&gt;
 #text_save  fn=c:\temp\export_vert_export.prepared_.csv   e=utf8   bom=N&lt;br /&gt;
&lt;br /&gt;
==#text_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_open öffnet einen Text aus einer Datei, der bisherige Inhalt der Datei wird überschrieben.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_open öffnet den ersten Text, #text_open2 öffnet den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname der Datei, die geöffnet wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_open  fn=$DIR(userroot)test.txt&lt;br /&gt;
 #text Eine weitere Zeile, $GUID()&lt;br /&gt;
 #text_save  fn=$DIR(userroot)test.txt&lt;br /&gt;
&lt;br /&gt;
==#text_props==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_props stellt Eigenschaften des Textes ein.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_props bezieht sich auf den ersten Text, #text_props2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* dub (&amp;quot;duplicates&amp;quot;) - Verhalten einer sortierten Liste bezüglich Dubletten&lt;br /&gt;
** acc (&amp;quot;accept&amp;quot;) - Dubletten werden akzeptiert&lt;br /&gt;
** err (&amp;quot;error&amp;quot;) - Dubletten führen zu Fehlern&lt;br /&gt;
** ign (&amp;quot;ignore) - Dubletten werden ignoriert&lt;br /&gt;
* srt (&amp;quot;sorted&amp;quot;) - Wenn ja, dann ist die Liste sortiert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_props   srt=Y   dup=ign&lt;br /&gt;
&lt;br /&gt;
==#text_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_set setzt eine bestimmte Zeile eines Textes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_set bezieht sich auf den ersten Text, #text_set2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;index&amp;quot;) - 0-relativer Index der Zeile, die geschrieben werden soll. Mit ''last'' kann die letzte Zeile geschrieben werden, mit ''all'' werden alle Zeilen ersetzt, das wird dann gebraucht, wenn mehrzeiliger Text zugewiesen werden soll; Funktionen werden ersetzt&lt;br /&gt;
* z - Text, der geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text_set   i=2   z=&amp;quot;dritte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=last   z=&amp;quot;letzte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=all   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
==#text_sort==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_sort sortiert einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_sort bezieht sich auf den ersten Text, #text_sort2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* y - Typ, default alpha, Funktionen werden ersetzt&lt;br /&gt;
** alpha - sortiert alphanumerisch&lt;br /&gt;
** inv - invertiert die gegebene Reihenfolge&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=&amp;quot;,OU=2nd_Level_T1,OU=Kundenservice,OU=Benutzer,OU=Testtours,OU=Travel&amp;quot;&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text_dissect   z=$VAL(1)   sep=&amp;quot;,OU=&amp;quot;&lt;br /&gt;
 #coutl  $TEXT(1)&lt;br /&gt;
 #text_sort   y=inv&lt;br /&gt;
 #text_compose   n=1   sep=.&lt;br /&gt;
 #val_set   n=1   z=tt.$VAL(1)&lt;br /&gt;
 #coutl $VAL(1)&lt;br /&gt;
&lt;br /&gt;
 Ergebnis ist:&lt;br /&gt;
 2nd_Level_T1&lt;br /&gt;
 Kundenservice&lt;br /&gt;
 Benutzer&lt;br /&gt;
 Testtours&lt;br /&gt;
 tt.Testtours.Benutzer.Kundenservice.2nd_Level_T1.&lt;br /&gt;
&lt;br /&gt;
==#text_dissect==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_dissect zerteilt einen String anhand einer vorgegebenen Trennzeichenfolge und fügt das Ergebnis dem betreffenden Text hinzu. Gegebenenfalls muss der Text vorher mit #text_clear geleert werden.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_dissect bezieht sich auf den ersten Text, #text_dissect bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - wenn Y, wird die sep-Zeichenfolge noch mal dem String angehängt; default N, Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, anhand der String zerteilt wird; Funktionen werden ersetzt&lt;br /&gt;
* z - String, der zerlegt wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_compose==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_compose setzt einen Text mithilfe eines Trennzeichens zu einem String zusammen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_compose bezieht sich auf den ersten Text, #text_compose bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - Wenn Y, wird die Trennzeichenfolge auch noch mal am Ende des Strings eingefügt; default N, Funktionen werden ersetzt&lt;br /&gt;
* n - Nummer des Values oder Name der Variable, in welche der String geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichenfolge, die beim Zusammenfügen des Textes verwendet wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_act==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_act bearbeitet einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_act bezieht sich auf den ersten Text, #text_act2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text der Zeile, die bei insert eingefügt werden soll; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* cu (&amp;quot;current&amp;quot;) - 0-relative Zeilennummer der Operation; default 0, Funktionen werden ersetzt&lt;br /&gt;
* ne (&amp;quot;new&amp;quot;) - 0-relative Zeilennummer als Ziel bei move; default 0, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt&lt;br /&gt;
** delete - Löscht die Zeile an Position cu (&amp;quot;current&amp;quot;)&lt;br /&gt;
** insert - Fügt den Text c an der Position cu (&amp;quot;current&amp;quot;) ein&lt;br /&gt;
** move - verschiebt die Zeile cu (&amp;quot;current&amp;quot;) nach Zeile ne (&amp;quot;new&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #text_act   y=move   cu=0&lt;br /&gt;
&lt;br /&gt;
==#text_loop==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_loop geht durch die Zeilen eines Textes und ruft für jede Zeile ''er'' auf&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_loop  bezieht sich auf den ersten Text, #text_loop2  bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich ert bezieht&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m - (&amp;quot;maximum&amp;quot;) Es wird maximal für die Anzahl der angegebenen Zeilen das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* n - Name der Variable, in welche die 0-relative Schleifenvariable geschrieben wird. (Es würde auch in einen Value geschrieben, wenn es sich um eine Nummer handelt, das ergibt in der Praxis aber meist nicht viel Sinn) Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear eins&lt;br /&gt;
 #text zwei&lt;br /&gt;
 #text drei&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear #coutl - $TEXT(1,$VAR(eins))&lt;br /&gt;
 #text_loop   er=1   n=eins&lt;br /&gt;
&lt;br /&gt;
==#tvl_add==&lt;br /&gt;
&lt;br /&gt;
Addiert dem Wert in einer Text-Valueliste einen Wert hinzu. Es handelt sich dabei um eine nummerierte Prozedur: #tvl_add arbeitet mit Text 1, #tvl_add2 mit Text 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Zeile, der ein Wert hinzugefügt wird; Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Operation, Funktionen werden ersetzt, default text&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
* z - Der Wert, der hinzugefügt wird&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text eins=1&lt;br /&gt;
 #text zwei=2&lt;br /&gt;
 #text drei=3&lt;br /&gt;
 #tvl_add   y=int   n=zwei   z=1&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==$TEXT()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $TEXT() wird auf den Inhalt des Textes zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# optional Zeile des Textes (0-relativ). Wenn es keinen zweiten Parameter gibt, wird der komplette Text zurück gegeben. Alternativ als zweiter Parameter eine Sonderfunktion:&lt;br /&gt;
## cnt / count - Gibt die Anzahl der Zeilen zurück&lt;br /&gt;
## last - Gibt die letzte Zeile zurück&lt;br /&gt;
## ix - Gibt die Position des Textes im dritten Parameter zurück&lt;br /&gt;
## as_line - Gibt den Text als eine Zeile zurück, Zeilenumbrüche werden durch den dritten Parameter ersetzt&lt;br /&gt;
# optional in abhängigkeit vom zweiten Paremeter&lt;br /&gt;
## wenn zweiter Parameter ix: Textzeile, nach der mit ix gesucht wird&lt;br /&gt;
## wenn zweiter Parameter as_line: Zeichenfolge, mit der die Zeilenumbrüche ersetzt werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Zeile 3&lt;br /&gt;
 #message  c=$TEXT(1)&lt;br /&gt;
&lt;br /&gt;
 #code url=$TEXT(1,as_line,&amp;amp;)&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich gilt in BAL: Eine Prozedur - eine Zeile.&lt;br /&gt;
&lt;br /&gt;
Bei vielen und/oder langen Parametern führt das zu recht langen Code-Zeilen und zu Unübersichtlichkeit. Hier können nun Teile der Parameter mit #code in weitere Zeile ausgelagert werden, deren Inhalt dann mit $CODE$ oder $CODE$ der eigentlichen Code-Zeile hinzugefügt wird.&lt;br /&gt;
&lt;br /&gt;
==#code==&lt;br /&gt;
&lt;br /&gt;
Fügt Text dem Code-Speicher hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#code hat keine benannten Parameter. Die ganze Zeile nach dem #code und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=G:\pics\pic5d68865cdaba62_62767562.jpg&lt;br /&gt;
 #code fn2=G:\pics\pic5d913c48682128_67979256.jpg&lt;br /&gt;
 #email_send   from=test@****.de   to=info@*****************.de   bcc=info@*****.de   subject=Testmail   text=$TEXT(1)   $CODE$&lt;br /&gt;
&lt;br /&gt;
==$CODE$ / $CODEN$==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CODE$ und $CODEN$ sind keine Funktionen, auch wenn sie auf den ersten Blick ähnlich aussehen. Sie haben keine Parameter und auch keine Klammern, dafür ein abschließendes $.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen fügen den Code-Speicher der jeweiligen Zeile hinzu. $CODE$ löscht danach den Code-Speicher, $CODEN$ tut das nicht, so dass dieselben Parameter wiederholt eingefügt werden können (beim letzten Einfügen sollte dann $CODE$ verwendet werden).&lt;br /&gt;
&lt;br /&gt;
=Separierte Zeile=&lt;br /&gt;
&lt;br /&gt;
Eine separierte Zeile ist eine Textzeile, die mehrere gleichartige Werte enthält, die durch Trennzeichen getrennt sind.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 3244,4465,7763,4536,4356,7777&lt;br /&gt;
&lt;br /&gt;
Solche Zeilen können mit #sepline aufgetrennt werden.&lt;br /&gt;
&lt;br /&gt;
==#sepline==&lt;br /&gt;
&lt;br /&gt;
Trennt eine separierte Zeile auf und führt für jeden Wert das mit er angegebene Kommando aus.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur (#sepline, #sepline2...)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y; Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, für welche die Transaktion gestartet wird, wenn ert=Y. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern (&amp;quot;each row no&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Wenn Y, wird für jeden Wert der separierten Zeile eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Es wird maximal für die Anzahl der angegebenen Werte das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten; Funktionen werden ersetzt.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N; Funktionen werden ersetzt.&lt;br /&gt;
* nn (&amp;quot;not null&amp;quot;) - Wenn Y, dann wird er nur für Werte der separierten Zeile aufgerufen, die nicht leer sind. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Das oder die Trennzeichen; default ist das Semikolon, Funktionen werden ersetzt.&lt;br /&gt;
* z - Der Inhalt der separierten Zeile; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(1)&lt;br /&gt;
 #sepline z=3244,4465,7763,4536,4356,7777   sep=,   er=1&lt;br /&gt;
&lt;br /&gt;
==$SEPLINE()==&lt;br /&gt;
&lt;br /&gt;
Greift auf den einzelnen Wert einer mit #sepline getrennten Zeile zu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der separierten Zeile&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(3)&lt;br /&gt;
 #sepline3 z=3244;4465;7763;4536;4356;7777     er=1&lt;br /&gt;
&lt;br /&gt;
=User und Rechte=&lt;br /&gt;
&lt;br /&gt;
Aus Gründen der Übersichtlichkeit ist die Rechtevergabe zweistufig:&lt;br /&gt;
&lt;br /&gt;
# Es werden (meist am Anfang eines Primär-Kommandos) Rechte-Definitionen erstellt, die einer oder mehreren Benutzergruppen Rechte (lesen oder lesen und schreiben) zuweisen. Die Rechte werden dabei implizit auch allen Untergruppen der angegebenen Benutzergruppe erteilt (Zum Beispiel: Rechte der Gruppe ''user'' hat auch implizit die Gruppe ''user.admin'').&lt;br /&gt;
# Dem Parameter r verschiedener Prozeduren kann dann eine Rechte-Definition zugewiesen werden.&lt;br /&gt;
&lt;br /&gt;
Den Parameter r als Rechte-Definition berücksichtigen die folgenden Prozeduren:&lt;br /&gt;
&lt;br /&gt;
* #frm&lt;br /&gt;
* Buttons (#btn, #btns_btn)&lt;br /&gt;
* Alle Segmente (#text_seg, #memo_seg, #btns_seg, vl_seg, #grd_seg, #xgrd_seg)&lt;br /&gt;
* Tree (#tree_add, #tree_fill, #tree_fillsql, Lese-Recht reicht)&lt;br /&gt;
* Grid-Spalten (#grd_col, #xgrd_col)&lt;br /&gt;
* #vl_line (für die komplette Zeile (r) und die einzelne Zelle (r1, r2, r3...))&lt;br /&gt;
&lt;br /&gt;
Wo der Parameter r nicht gesetzt ist, wird die Rechte-Definition der Formulars verwendet.&lt;br /&gt;
&lt;br /&gt;
==#rights==&lt;br /&gt;
&lt;br /&gt;
Setzt eine Rechte-Definition im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Rechte-Definition; default ist ''frm'', also dsa Default-Recht für das Formular.&lt;br /&gt;
* r_ (&amp;quot;right&amp;quot;) - Prefix für die Benutzergruppe. Für die Rechte-Definition sind die folgenden Werte zulässig&lt;br /&gt;
** n (&amp;quot;no&amp;quot;) - kein Recht&lt;br /&gt;
** r (&amp;quot;read&amp;quot;) - nur lesen&lt;br /&gt;
** w (&amp;quot;write&amp;quot;) - lesen und schreiben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights  n=frm   r_user=r   r_user.admin=w&lt;br /&gt;
&lt;br /&gt;
Setzt für alle User das Lese-Recht und für Administratoren das Lese- und Schreibrecht.&lt;br /&gt;
&lt;br /&gt;
==#rights_clear==&lt;br /&gt;
&lt;br /&gt;
Löscht alle Rechte-Definitionen im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
(Wird in der Praxis selten benötigt, weil Kommandos mit leerer Rechte-Definition starten.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights_clear&lt;br /&gt;
&lt;br /&gt;
==$USERID()==&lt;br /&gt;
&lt;br /&gt;
Die ID des angemeldeten Users&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kusr=$USERID()&lt;br /&gt;
&lt;br /&gt;
==$RIGHTUSERID()==&lt;br /&gt;
&lt;br /&gt;
Administratoren können andere User einstellen (Userliste links unten im BAF-Client), vor allem um deren Rechte zu prüfen. Die UserID dieses ausgewählten Users kann mit der Funktion $RIGHTUSERID() ermittelt werden.&lt;br /&gt;
&lt;br /&gt;
In fast allen Fällen gilt der folgende Grundsatz: Lesende Operationen mit $RIGHTUSERID(), schreibende Operationen mit $USERID().&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_open   kusr=$RIGHTUSERID()&lt;br /&gt;
&lt;br /&gt;
==$ADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der angemeldete User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $ADM()&lt;br /&gt;
&lt;br /&gt;
==$RADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der ausgewählte User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $RADM()&lt;br /&gt;
&lt;br /&gt;
=Ausführen=&lt;br /&gt;
&lt;br /&gt;
==#exec==&lt;br /&gt;
&lt;br /&gt;
Führt ein anderes Kommando aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Names des (Primär- oder Sub-) Kommandos, das ausgeführt werden soll.&lt;br /&gt;
* ex (&amp;quot;exception&amp;quot;) - Name oder Nummer des Kommandos, das ausgeführt wird, wenn bei der Ausführung von cmd eine Exception auftritt; siehe Beispiele&lt;br /&gt;
* fin (&amp;quot;finally&amp;quot;) - Name oder Nummer des Kommandos, das nach der Ausführung von cmd ausgeführt wird - egal ob eine Exception aufgetreten ist oder nicht. Wird nur berücksichtigt, wenn der Parameter ex nicht gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel löst das Problem, dass ein neues PDF unter demselben Dateinamen nicht erstellt werden kann, wenn beim vorherigen Versuche der Erstellung eine Exception aufgetreten ist. In einem solchen Fall wurde ein #pdf_start, aber kein #pdf_stop ausgeführt, und die geöffnete Datei sperrt diesen Dateiname, bis der BAF-Client geschlossen wird. Lösung dieses Problems ist es, im Parameter ex ein #pdf stop auszuführen; auf das Öffnen der Datei kann in einem solchen Fall verzichtet werden. Mit der Funktion $DATA() wird hier im Beispiel gezielt eine Exception ausgelöst.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test_pdf&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #pdf_text  c=&amp;quot;Hello World&amp;quot;&lt;br /&gt;
 -- #cmd #pdf_text  c=&amp;quot;Hello World $DATA(dat,test)&amp;quot;&lt;br /&gt;
 #cmd #pdf_stop   o=Y&lt;br /&gt;
 &lt;br /&gt;
 #pdf_start  fn=$DIR(doc)\test.pdf&lt;br /&gt;
 #exec   cmd=1   ex=&amp;quot;#pdf_stop   o=N&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test_pdf executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#batchexec==&lt;br /&gt;
&lt;br /&gt;
Speichert den Text n in der Datei batch.bat und führt diese aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clr (&amp;quot;clear&amp;quot;) - Wenn Y, wird der Text nach Ausführung des Batch-Datei gelöscht; Default Y; Funktionen werden ersetzt;&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes; der mit #text gespeicherte Text hat die Nummer 1 &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #batchexec   n=1&lt;br /&gt;
&lt;br /&gt;
==#file_open==&lt;br /&gt;
&lt;br /&gt;
Öffnet eine Datei (oder auch eine Webseite)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder die URL der Webseite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_open  fn=c:\temp\test.csv&lt;br /&gt;
 #file_open  fn=https://www.google.de&lt;br /&gt;
&lt;br /&gt;
==#loop==&lt;br /&gt;
&lt;br /&gt;
BAL kennt keine Schleifen als Sprachelement. Um Schleifen mit einer fest Schleifenzahl auszuführen, wird die Prozedur #loop verwendet. lf muss nicht kleiner als lt sein, #loop kann auch von oben nach unten zählen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* lf (&amp;quot;loop from&amp;quot;) - Anfangswert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* lt (&amp;quot;loop to&amp;quot;) - Endwert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in der die Schleifenvariable gespeichert wird (damit sie an anderer Stelle gelesen werden kann); Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #loop   lf=42   lt=1337   er=test_line&lt;br /&gt;
&lt;br /&gt;
==#exit==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #exit bricht die Ausführung auf der jeweiligen Code-Ebene (Kommando bzw. Sub-Kommando) ab&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 ~ $EMPTY($PVAL(vl,id))   and   $PVAL(vl,status) &amp;gt; 20&lt;br /&gt;
 #sql select nextval('ausza_id') as id&lt;br /&gt;
 #sql_openval   f_id=1&lt;br /&gt;
 #page_val   i=vl   f=id   z=$VAL(1)&lt;br /&gt;
 #save&lt;br /&gt;
 #exit&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Der Beispiel-Code befindet sich auf der Seite xausza_page_ausza und baut die entsprechende Seite auf. Er prüft, ob bereits eine ID-Gesetzt ist - wenn nicht, wird über eine Datenbank-Sequenz die nächste ID abgefragt, in das VL-Segment geschrieben und die Seite gespeichert. Beim Speichern der Seite wird sie jedoch neu aufgerufen, also komplett neu aufgebaut, was erst einmal kein Problem ist. Danach würde aber die Ausführung auf der Code-Ebene, auf der sich #save befindet, fortgeführt, was zur Folge hat, dass die dann folgenden Segmente doppelt erscheinen (zunächst die aus dem Neu-Aufbau der Seite, dann die, die von der Fortsetzung des Codes her stammen).&lt;br /&gt;
&lt;br /&gt;
Um dies zu vermeiden muss die Ausführung des Codes nach #save abgebrochen werden.&lt;br /&gt;
&lt;br /&gt;
==$EXEC==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando. Im ausgeführten Kommando kann eine Variable gesetzt werden, die dann als Funktionsergebnis von $EXEC zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll&lt;br /&gt;
# optional: Der Name der Variablen, in der das Ergebnis steht; default ist ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;test_funkexec&amp;quot;   y=console&lt;br /&gt;
 #cout   c=$EXEC(test_funkexec_line)&lt;br /&gt;
&lt;br /&gt;
 -- test_funkexec_line&lt;br /&gt;
 #var_set   n=result   z=42&lt;br /&gt;
&lt;br /&gt;
=Dateien und Verzeichnisse=&lt;br /&gt;
&lt;br /&gt;
==#file_op==&lt;br /&gt;
&lt;br /&gt;
Führt eine Operation mit einer Datei oder einem Verzeichnis aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder des Verzeichnisses&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in die/den das Ergebnis der Operation (Y oder N) geschrieben wird.&lt;br /&gt;
* on (&amp;quot;old name) - der bisherige Dateiname bei RenameFile&lt;br /&gt;
* y - Typ der Operation&lt;br /&gt;
** cd / createdir - Erzeugt ein Verzeichnis&lt;br /&gt;
** cf / copyfile - Kopiert eine Datei (von on zu fn)&lt;br /&gt;
** df / deletefile - Löscht eine Datei&lt;br /&gt;
** fd / forcedirectories - Stellt sicher, dass ein Pfad vorhanden ist&lt;br /&gt;
** rd / removedir - Entfernt ein Verzeichnis&lt;br /&gt;
** rf / renamefile - Benennt eine Datei um, kann auch dazu verwendet werden, eine Datei zu verschieben&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #file_op   y=renamefile   on=c:\temp\debug.txt   fn=c:\temp\test\debug.txt   n=1&lt;br /&gt;
 #cout   c=$VAL(1)&lt;br /&gt;
 &lt;br /&gt;
 #file_op   y=fd   fn=c:\eins\zwei\drei\vier&lt;br /&gt;
&lt;br /&gt;
==#file_search==&lt;br /&gt;
&lt;br /&gt;
Sucht Dateien und schreibt die Ergebnisliste in einen Text.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* clr - (&amp;quot;clear&amp;quot;) wenn Y, wird der Text vor der Suche geleert. Default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, in den die Ergebnisliste geschrieben wird; default 1, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_search   fn=c:\*.ini   n=1   y=0   all_=Y&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==#file_wait==&lt;br /&gt;
&lt;br /&gt;
Wartet, bis zumindest eine Datei vorhanden ist, die den Kriterien entspricht, und führt dann cmd aus. Wird nach der in to eingestellten Zeit keine Datei gefunden, dann wird mit dem in cmdto eingestellten Kommando abgebrochen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* cmd - Kommando, das ausgeführt wird, sobald eine Datei gefunden wird; Funktionen werden ersetzt&lt;br /&gt;
* cmdto - Kommando, das ausgeführt wird, sobald die Prozedur wegen eines TimeOuts abgebrochen wird; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* sleep - Zeit in ms zwischen den einzelnen Suchen nach einer Datei, die den Kriterien entspricht; Default 1000, Funktionen werden ersetzt&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in ms, nach der die Ausführung abgebrochen wird; Default 15000, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #cout c=&amp;quot;Gefunden&amp;quot;&lt;br /&gt;
 #cmd_clear2 #cout c=&amp;quot;TimeOut&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #file_wait   fn=C:\temp\test\*.txt   cmd=1   cmdto=2&lt;br /&gt;
&lt;br /&gt;
==#dir_force==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass es den spezifizierten Verzeichnispfad gibt, indem erforderlichenfalls Verzeichnisse angelegt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Names des Pfads&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_force   n=c:\temp\pdf&lt;br /&gt;
&lt;br /&gt;
==#dir_proc==&lt;br /&gt;
&lt;br /&gt;
Durchsucht ein Verzeichnis nach Dateien, die den angegebenen Kriterien entsprechen, und führt für jede gefundene Datei ''cmd'' aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das für jede gefundene Datei ausgeführt wird&lt;br /&gt;
* dn (&amp;quot;DirectoryName&amp;quot;) - Pfad des Verzeichnisses, in dem die Dateien gesucht werden; Funktionen werden ersetzt.&lt;br /&gt;
* done - Verzeichnis, in das die Dateien nach Abarbeitung verschoben werden (sofern der Parameter nicht leer ist). Funktionen werden ersetzt.&lt;br /&gt;
* fn (&amp;quot;filename&amp;quot;) - Suchkriterium für den Dateinamen; Funktionen werden ersetzt; Default *&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in welcher der Dateiname der aktuell zu bearbeitenden Datei inklusive Pfad gespeichert wird; Funktionen werden ersetzt; Default dir_proc&lt;br /&gt;
* ndone(&amp;quot;name done&amp;quot;) - Name der Variablen, die bestimmt, ob eine Datei in das Done-Verzeichnis verschoben wird. Vor jedem Aufruf von cmd wird diese Variable auf 'Y' gesetzt. Sie kann während der Bearbeitung auf N gesetzt werden - damit wird verhindert, dass die Datei in das Done-Verzeichnis verschoben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_proc   dn=c:\temp\in   done=c:\temp\done   fn=*.csv   cmd=importcsv_line&lt;br /&gt;
&lt;br /&gt;
==$FILEINFO()==&lt;br /&gt;
&lt;br /&gt;
Liefert Infos über eine Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Dateiname&lt;br /&gt;
# Typ der Information, es stehen dabei folgende Optionen zur Verfügung&lt;br /&gt;
#* size - Dateigröße in Byte&lt;br /&gt;
#* size_point - Dateigröße in Byte, Punkte alle drei Zeichen von rechts&lt;br /&gt;
#* size_auto - Dateigröße in Byte, kB, MB oder GB, je nach Größe; mit Einheit&lt;br /&gt;
#* size_kb - Dateigröße in kB (analog Windows-Explorer)&lt;br /&gt;
#* date - Datum im Format dd.mm.yyyy&lt;br /&gt;
#* date_yyyy - Datum im Format yyyymmdd&lt;br /&gt;
#* datetime - Datum und Uhrzeit im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
#* datetime_yyyy - Datum im Format yyyymmddhhmmss&lt;br /&gt;
#* exists - Y, wenn die Datei existiert, sonst N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=fn   z=&amp;quot;T:\Tools Gruppenrechte\BC3 light\BafClientFM.exe&amp;quot;&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_point)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_auto)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_kb)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),exists)&lt;br /&gt;
&lt;br /&gt;
Ergebnis&lt;br /&gt;
&lt;br /&gt;
 27668480&lt;br /&gt;
 27.668.480&lt;br /&gt;
 26,39 MB&lt;br /&gt;
 27.020 kB&lt;br /&gt;
 02.05.2023&lt;br /&gt;
 20230502&lt;br /&gt;
 02.05.2023 12:20:09&lt;br /&gt;
 20230502122009&lt;br /&gt;
 Y&lt;br /&gt;
&lt;br /&gt;
==$DIR()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Verzeichnisnamen. Trailing Path Delimiter (\ bei Windows) wird immer angehängt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bezeichnung des Verzeichnisses&lt;br /&gt;
## appdata - Verzeichnis für Anwendungsdaten des Users&lt;br /&gt;
## cappdata - gemeinsames Verzeichnis für Anwendungsdaten aller User&lt;br /&gt;
## cdoc - gemeinsames Dokumentenverzeichnis  aller User&lt;br /&gt;
## cfav / cfavorites - gemeinsames Favoritenverzeichnis aller User&lt;br /&gt;
## cmusic - gemeinsames Musikverzeichnis aller User&lt;br /&gt;
## cpic / cpictures - gemeinsames Bilderverzeichnis aller User&lt;br /&gt;
## cvideo - gemeinsames Videoverzeichnis aller User&lt;br /&gt;
## desktop - Desktopverzeichnis des Rechners&lt;br /&gt;
## '''doc''' / docdir - Dokumentenverzeichnis des Users&lt;br /&gt;
## downloads - Downloadsverzeichnis des Users&lt;br /&gt;
## fav / favorites - Favoritenverzeichnis des Users&lt;br /&gt;
## fonts - Fontsverzeichnis des Rechners&lt;br /&gt;
## music - Musikverzeichnis des Users&lt;br /&gt;
## pic / pictures - Bilderverzeichnis des Users&lt;br /&gt;
## prog / program - Programmverzeichnis des Rechners&lt;br /&gt;
## prog86 / program86 - Programm86-Verzeichnis des Rechners&lt;br /&gt;
## '''root''' - Root-Verzeichnis des BAF-Clients bzw. des BAF-Servers&lt;br /&gt;
## '''userroot''' / usrroot - User-Verzeichnis des BAF-Clients&lt;br /&gt;
## video - Videoverzeichnis des Users&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=$DIR(doc)test.txt&lt;br /&gt;
&lt;br /&gt;
==$FILEDIALOG()==&lt;br /&gt;
&lt;br /&gt;
Führt einen Dateiauswahl-Dialog aus und gibt den gewählten Dateinamen zurück. Im Falle des Abbruchs wird ''abort'' zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wenn der erste Parameter ''save'' lautet, wird ein Speichern-Dialog, sonst ein Öffnen-Dialog aufgerufen.&lt;br /&gt;
# Filter-Statement, immer Kombinationen aus Text (Text-Dateien *.txt) und Filter-Statement(*.txt), getrennt durch Pipes.&lt;br /&gt;
# Standard-Dateierweiterung&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=&amp;quot;$FILEDIALOG(save,Text-Dateien *.txt|*.txt|Alle Dateien *.*|*.*,txt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Bitte beachten: Wegen der Leerzeichen im Filter-Statement muss der ganze Parameter in doppelte Anführungszeichen gesetzt werden.)&lt;br /&gt;
&lt;br /&gt;
=ZIP=&lt;br /&gt;
&lt;br /&gt;
==#zip_create==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine ZIP-Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Dateien, die der ZIP-Datei hinzugefügt werden; Funktionen werden ersetzt&lt;br /&gt;
* dir (&amp;quot;directory&amp;quot;) - Verzeichnis, wenn das nicht bei allen fn1, fn2... angegeben werden soll&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Der Dateiname, unter dem die ZIP-Datei gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* fn1, fn2,... (&amp;quot;FileName&amp;quot;) - Die Dateien, die in der ZIP-Datei gespeichert werden; die Anzahl wird mit dem Parameter cnt bestimmt; Funktionen werden ersetzt&lt;br /&gt;
* list - Nummer eines Textes (#text, #text2...), in dem die Dateien gelistet sind, die der ZIP-Datei hinzugefügt werden sollen. Wenn list ein Wert größer 0 hat, werden cnt und fn1, fn2... ignoriert. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* pw (&amp;quot;PassWord&amp;quot;) - Password der erzeugten ZIP-Datei; Funktionen werden ersetzt.&lt;br /&gt;
* pwc (&amp;quot;PassWordCrypted&amp;quot;) - Wenn Y, dann ist das Passwort mit der Verschlüsselungsfunktion auf der Seite Tools des Code-Dialogs verschlüsselt. Hinweis: Mit dieser Verschlüsselung verhindert man lediglich, dass das Passwort direkt aus dem Code ausgelesen werden kann. Wird der BAF-Client mit dem Delphi-Debugger ausgeführt, lässt sich leicht an die betreffende Stelle ein Breakpoint setzen und das Passwort dann im Klartext auslesen (dieselbe Unit uBafCrypt vorausgesetzt).&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #zip_create   fn=$VAR(root).zip   list=1&lt;br /&gt;
 &lt;br /&gt;
 #var_set   n=fn_zip   z=tt_mail_$VAR(reise)-$VAR(reisename)_$PAD($VAR(lfdnr),4,L,0)_$NOWFMT(yyyymmdd).zip&lt;br /&gt;
 #file_op   y=df   fn=$VAR(path)\$VAR(fn_zip)&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=$VAR(filename).txt&lt;br /&gt;
 #code fn2=$VAR(filename).sab&lt;br /&gt;
 #zip_create   dir=$VAR(path)   fn=$VAR(path)\$VAR(fn_zip)    pw=$VAR(pw)   $CODE$&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #zip_create ersetzt nicht vorherige Dateien. Von daher im Zweifelsfall wie im zweiten Beispiel vorher eine Datei dieses Namens löschen.&lt;br /&gt;
&lt;br /&gt;
=Ini-Dateien=&lt;br /&gt;
&lt;br /&gt;
Der BAF-Client verwendet eine Ini-Datei im Root-Verzeichnis (vor allem für die Datenbankverbindungen) und eine Ini-Datei ''BafClientFM.ini'' im User-Anwendungsverzeichnis (vor allem für die Formularpositionen). Es können aber auch weitere Ini-Dateien verwendet werden.&lt;br /&gt;
&lt;br /&gt;
==#ini_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Ini-Datei. #ini_val ist eine nummerierte Prozedur: #ini_val schreibt in die erste Ini-Datei, #ini_val2 in die zweite Ini-Datei und so weiter. Diese Ini-Dateien werden zunächst nur im Speicher gehalten und müssen explizit aus einer Datei geladen oder in eine Datei gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;item&amp;quot; / &amp;quot;ident&amp;quot;) - Name des Eintrags in der Ini-Datei; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Wenn der Parameter n den Wert ''usr'' oder ''user'' hat, dann bleibt die Nummer der Ini-Datei unberücksichtigt und der Wert wird in die Datei ''BafClientFM.ini'' im im User-Anwendungsverzeichnis geschrieben.&lt;br /&gt;
* sec (&amp;quot;section&amp;quot;) - Abschnitt in der Ini-Datei; Funktionen werden ersetzt; default ''values''&lt;br /&gt;
* z - Wert, der in die Ini-Datei geschrieben wird; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_val  i=date_last   z=$NOW()&lt;br /&gt;
&lt;br /&gt;
==#ini_load==&lt;br /&gt;
&lt;br /&gt;
Lädt eine Ini-Datei aus einer Datei. Es handelt sich um eine nummerierte Prozedur: #ini_load lädt die Ini-Datei 1, #ini_load2 lädt die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, die geladen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_load   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==#ini_save==&lt;br /&gt;
&lt;br /&gt;
Speichert eine Ini-Datei ineine Datei. Es handelt sich um eine nummerierte Prozedur: #ini_save speichert die Ini-Datei 1, #ini_save2 speichert die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, in die gespeichert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_save   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==$INI()==&lt;br /&gt;
&lt;br /&gt;
Liest einen Wert aus einer Ini-Datei.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
# Item (Ident)&lt;br /&gt;
# optional: Sektion; wenn nicht vorhanden, dann ''values''. Wenn ''db!'', dann wird als Sektion die aktuell gewählte Datenbankverbindung verwendet (in diesem Fall sollte als erster Parameter ''root'' verwendet werden).&lt;br /&gt;
# optional: Default-Wert; wenn nicht vorhanden, dann ein leerer String&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum)&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum,bearbeitung,$TODAY())&lt;br /&gt;
&lt;br /&gt;
==$INITEXT()==&lt;br /&gt;
&lt;br /&gt;
Gibt die komplette Ini-Datei zurück. Wird vor allem beim Debugging verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $INITEXT(usr)&lt;br /&gt;
&lt;br /&gt;
=Zwischenablage=&lt;br /&gt;
&lt;br /&gt;
Das BAF-Framework unterstützt die Zwischenablage nur für Text.&lt;br /&gt;
&lt;br /&gt;
==#clipboard==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Text in die Zwischenablage&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* z - Wert, der in der Zwischenablage gespeichert werden soll; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #clipboard   z=$TEXT()&lt;br /&gt;
 #clipboard   z=$CHR(dquote)$PVAL(test,zahl,allsel,$CHR(crlf))$CHR(dquote)&lt;br /&gt;
&lt;br /&gt;
==$CLIPBOARD()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Text aus der Zwischenablage zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setvar   n=clp   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
=String-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben einen String zurück.&lt;br /&gt;
&lt;br /&gt;
==$BASE64()==&lt;br /&gt;
&lt;br /&gt;
En- oder Decodiert einen Text im Base64-Code&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Encoding oder Decoding:&lt;br /&gt;
## e - Encoding&lt;br /&gt;
## d - Decoding&lt;br /&gt;
# Text, der en-oder decodet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $BASE64(e,Dies ist ein Test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$CHR()==&lt;br /&gt;
&lt;br /&gt;
Gibt ein Zeichen (ggf zwei Zeichen) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Ansi-Zeichennummer oder eine der folgenden Bezeichnungen:&lt;br /&gt;
## crlf - Zeilenumbruch #13#10&lt;br /&gt;
## cr - Zeichen #13&lt;br /&gt;
## lf - Zeichen #10&lt;br /&gt;
## tab - Tabulator&lt;br /&gt;
## quote - ' (einfache Anführungszeichen)&lt;br /&gt;
## dquote - &amp;quot; (doppelte Anführungszeichen)&lt;br /&gt;
## space / leer - Leerzeichen&lt;br /&gt;
## comma / komma - , (Komma)&lt;br /&gt;
## questionmark / qmark / frage / fragezeichen - ?&lt;br /&gt;
## bro / bracket_open - (&lt;br /&gt;
## brc / bracket_close - )&lt;br /&gt;
## dollar - $&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CONVERT()==&lt;br /&gt;
&lt;br /&gt;
Konvertiert einen String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Konvertierungsfunktion&lt;br /&gt;
## isodate&lt;br /&gt;
## isodatetime&lt;br /&gt;
## truefalse&lt;br /&gt;
## pointfloat&lt;br /&gt;
## urlcode&lt;br /&gt;
## utf8&lt;br /&gt;
# String, der konvertiert werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $CONVERT(isodate,2025-03-12)&lt;br /&gt;
 #coutl $CONVERT(isodatetime,2025-03-12 12:03:17)&lt;br /&gt;
 #coutl $CONVERT(truefalse,true)&lt;br /&gt;
 #coutl $CONVERT(pointfloat,12.3)&lt;br /&gt;
 #coutl $CONVERT(urlcode,Für schönen Ärger)&lt;br /&gt;
 #coutl $CONVERT(utf8,Für schönen Ärger)&lt;br /&gt;
&lt;br /&gt;
(Ergebnis)&lt;br /&gt;
 12.03.2025&lt;br /&gt;
 12.03.2025 12:03:17&lt;br /&gt;
 Y&lt;br /&gt;
 12,3&lt;br /&gt;
 F%C3%BCr%20sch%C3%B6nen%20%C3%84rger&lt;br /&gt;
 Für schönen Ärger&lt;br /&gt;
&lt;br /&gt;
==$COPY()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$COPY($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$EXEC()==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando aus und gibt ein Funktionsergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll.&lt;br /&gt;
# optional: Name der Variable, die als Funktionsergebnis zurück gegeben werden soll; default ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=test   z=$EXEC(testkommando)&lt;br /&gt;
&lt;br /&gt;
==$GUID()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine GUID und gibt sie zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# optional: Name einer Variablen, in welcher die GUID zusätzlich gespeichert wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kid=$GUID()&lt;br /&gt;
&lt;br /&gt;
==$HASH()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt einen Hash-Wert vom String im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, von welchem der Hash gebildet werden soll.&lt;br /&gt;
# zu verwendender Hash-Algorithmus:&lt;br /&gt;
## sha512&lt;br /&gt;
## sha512_256&lt;br /&gt;
## sha512_224&lt;br /&gt;
## sha384&lt;br /&gt;
## sha256&lt;br /&gt;
## sha224&lt;br /&gt;
## sha1&lt;br /&gt;
## md5 (Hinweis: MD5 gilt seit Längerem als nicht mehr sicher. Verwenden Sie ihn nur, wenn dies aus Gründen der Abwärts-Kompatbilität zwingend ist.)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$HASH($PVAL(vl,1,2),sha512)&lt;br /&gt;
&lt;br /&gt;
==$INCLUDE()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass der als dritter Parameter übergebene Text am Anfang oder am Ende steht, gegebenenfalls wird er dort eingefügt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## lead(oder leading) - Text muss am Anfang stehen&lt;br /&gt;
## leadci(oder leadingci oder leadingcaseinsensitive) - Text muss am Anfang stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
## trail(oder trailing) - Text muss am Ende stehen&lt;br /&gt;
## trailci(oder trailci oder trailingcaseinsensitive) - Text muss am Ende stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
# Text, in den gegebenenfalls eingefügt wird&lt;br /&gt;
# Text, der gegebenenfalls eingefügt wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCLUDE(trailci,test.PDF,.pdf)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$INVLOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Key aus einer Nachschlageliste bei Übergabe des Values.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Value des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$INVLOOKUP(general_status,aktiv,Wert nicht vorhanden)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus einer Nachschlageliste.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Key des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$LOOKUP(general_status,1,Status nicht gesetzt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOW()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Kleinbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Kleinbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LOW($EDT(edt1)) = bus&lt;br /&gt;
&lt;br /&gt;
==$LOWNOSPACE()==&lt;br /&gt;
&lt;br /&gt;
Wandelt einen String in Kleinbuchstaben und ersetzt alle Leerzeichen durch Unterstriche.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der gewandelt werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$LOWNOSPACE($PVAL(vl,1,2))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$NOCRLF()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Zeilenumbrüche&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem die Zeilenumbrüche entfernt werden sollen&lt;br /&gt;
# optional: Zeichenfolge, die an Stelle der Zeilenumbrüche eingefügt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=2   z=$NOCRLF($VAL(1),;)&lt;br /&gt;
&lt;br /&gt;
==$NVL()==&lt;br /&gt;
&lt;br /&gt;
Liefert einen Ersatzwert, wenn der Wert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird, wenn der erste Parameter leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   where ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0)&lt;br /&gt;
&lt;br /&gt;
Liefert $PVAL einen leeren Wert zurück (z.B., weil die Gridzeile neu angelegt wurde und daher noch keine Nummer eingetragen ist), so wird statt dessen 0 verwendet, damit die WHERE-Klausel syntaktisch korrekt ist.&lt;br /&gt;
&lt;br /&gt;
==$ONLYCHAR()==&lt;br /&gt;
&lt;br /&gt;
Entfernt unerwünschte Zeichen aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# optional: Typ der Funktion&lt;br /&gt;
## (leer) - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z', 'ä', 'ö', 'ü', 'Ä','Ö', 'Ü', 'ß']) sind&lt;br /&gt;
## charnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind&lt;br /&gt;
## low - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## upp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## charnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## charnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## uml - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z') sind, Umlaute werden konvertiert (ä -&amp;gt; ae, ö -&amp;gt; oe, ü -&amp;gt; ue, Ä -&amp;gt; Ae, Ö -&amp;gt; Oe, Ü -&amp;gt; Ue, ß -&amp;gt; ss)&lt;br /&gt;
## umlcharnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Umlaute werden konvertiert&lt;br /&gt;
## umllow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## no191 / not191 - Es werden alle Zeichen mit der ANSI-Nummer 191 (¿) entfernt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg)&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg,umllow)&lt;br /&gt;
&lt;br /&gt;
==$PAD()==&lt;br /&gt;
&lt;br /&gt;
Füllt links oder rechts bis zur vorgegebenen Länge mit Zeichen auf.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# Soll-Länge. Ist der ursprüngliche String bereits länger, wird er nicht gekürzt, es werden aber auch keine weiteren Zeichen hinzugefügt&lt;br /&gt;
# Wenn L, werden die Zeichen vorne hinzugefügt, andernfalls hinten&lt;br /&gt;
# Zeichen, die soweit und so oft hinzugefügt werden, bis die Soll-Länge erreicht ist. Umfasst der Parameter mehrere Zeichen, werden diese ggf. nicht alle hinzugefügt.&lt;br /&gt;
# optional: Länge, auf die der ursprüngliche String vor der weiteren Verarbeitung gekürzt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   text1 = '$PAD($VAR(text1),70,R, )'&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ des Ergebnisses&lt;br /&gt;
## curr - Zahl mit zwei Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## curr4 - Zahl mit vier Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## date - Datum in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## int - ganze Zahl  in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## ld - Key einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ldv - Value einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ls - Key eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## lsv - Value eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## text, text2, text3... - Zeile eines Textes&lt;br /&gt;
# untere Grenze bzw. Name der Nachschlageliste oder des Specials&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $RANDOM(date,01.01.2022,31.12.2022)&lt;br /&gt;
 #coutl $RANDOM(text2)&lt;br /&gt;
&lt;br /&gt;
==$SUBSTR()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Selbe Funktionalität wie $COPY())&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$SUBSTR($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$STREP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string replace&amp;quot;) Ersetzt Zeichen im String durch andere Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, in welchen Zeichen ersetzt werden sollen.&lt;br /&gt;
# Zeichen, die ersetzt werden sollen&lt;br /&gt;
# Zeichen, die an deren Stelle treten sollen&lt;br /&gt;
# optional: Optionen (kombinierbar)&lt;br /&gt;
## i - Groß- und Kleinschreibung ignorieren &lt;br /&gt;
## a - Alle Vorkommen ersetzen (andernfalls wird nur das erste Vorkommen ersetzt)&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=&amp;quot;$STREP($PVAL(vl,1,2), ,_,a)&amp;quot;&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$STREP($PVAL(vl,1,2),$CHR(space),_,a)&lt;br /&gt;
&lt;br /&gt;
Hinweis: Beide Beispiele haben exakt dieselbe Funktion. Im oberen Beispiel steht das Leerzeichen direkt im Text, dafür muss der komplette Parameter in doppelte Anführungszeichen, im unteren Beispiel wird das Leerzeichen durch $CHR(space) eingefügt, dafür können die Leerzeichen unterbleiben.&lt;br /&gt;
&lt;br /&gt;
==$STROP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string operation&amp;quot;) Sammelsurium von String-Operationen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## trim - entfernt führende und folgende Leerzeichen&lt;br /&gt;
## trimleft - entfernt führende Leerzeichen&lt;br /&gt;
## trimright - entferne folgende Leerzeichen&lt;br /&gt;
## quote - setzt den String in einfache Anführungszeichen&lt;br /&gt;
## unquote - entfernt einschließende einfache Anführungszeichen&lt;br /&gt;
## dquote - setzt den String in doppelte Anführungszeichen&lt;br /&gt;
## unqduote - entfernt einschließende doppelte Anführungszeichen&lt;br /&gt;
## ex_filepath - entspricht der Delphi-Funktion ExtractFilePath&lt;br /&gt;
## ex_filedir - entspricht der Delphi-Funktion ExtractFileDir&lt;br /&gt;
## ex_filedrive - entspricht der Delphi-Funktion ExtractFileDrive&lt;br /&gt;
## ex_filename - entspricht der Delphi-Funktion ExtractFileName&lt;br /&gt;
## ex_fileext - entspricht der Delphi-Funktion ExtractFileExt&lt;br /&gt;
# String, der bearbeitet werden soll&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$STROP(quote,Test)&lt;br /&gt;
&lt;br /&gt;
==$STREXTR()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string extract&amp;quot;) Extrahiert einen Teil aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem extrahiert werden soll&lt;br /&gt;
# Extraktionstyp&lt;br /&gt;
## ffe (&amp;quot;from first exclude&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## ffi (&amp;quot;from first include&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tfe (&amp;quot;to first exclude&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tfi (&amp;quot;to first include&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## fle (&amp;quot;from last exclude&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## fli (&amp;quot;from last include&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tle (&amp;quot;to last  exclude&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tli (&amp;quot;to last include&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Trennzeichen&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffe,;)&amp;quot;    -- Ergebnis: test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffi,;)&amp;quot;    -- Ergebnis: ;test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfe,;)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfi,;)&amp;quot;    -- Ergebnis: test;&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;!§§test2,tfe,;!§§)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
&lt;br /&gt;
==$TRIM()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Leerzeichen und Zeilenumbrüche am Rand des Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der getrimmt werden soll&lt;br /&gt;
# optional&lt;br /&gt;
## L - trimmt nur auf der linken Seite&lt;br /&gt;
## R - trimmt nur auf der rechten Seite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$TRIM($VAL(1),R)&lt;br /&gt;
&lt;br /&gt;
==$UPP()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Großbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Großbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $UPP($EDT(edt1)) = BUS&lt;br /&gt;
&lt;br /&gt;
==$VT()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VT (&amp;quot;Value Translate&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Vergleichswert 1&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 1 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 2&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 2 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 3&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 3 dem ersten Parameter entspricht &lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VT(Frau,1,Herr,2,Frau,3)&lt;br /&gt;
 -- Frau -&amp;gt; 3&lt;br /&gt;
 -- Herr -&amp;gt; 2&lt;br /&gt;
 -- Test -&amp;gt; 1&lt;br /&gt;
 -- Firma -&amp;gt; 1&lt;br /&gt;
&lt;br /&gt;
==$VTVL()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VTVL (&amp;quot;Value Translate ValueList&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu $VT werden die zu prüfenden Werte und deren Entsprechungen nicht über Parameter übergeben, sondern aus einer Werte-Liste geholt, die in einem Text gespeichert sein muss.&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich wie folgt aufbauen&lt;br /&gt;
&lt;br /&gt;
 key1=value1&lt;br /&gt;
 key2=value2&lt;br /&gt;
 key3=value3&lt;br /&gt;
 key4=value4&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich auch mit #sql_opentvl erzeugen, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Nummer des Textes, in dem sich die Werteliste befindet.&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select userid as ckey, shortname as cvalue from user_user&lt;br /&gt;
 #sql_opentvl n=1&lt;br /&gt;
 #coutl $VTVL(591,(nicht gefunden),1)&lt;br /&gt;
&lt;br /&gt;
==$XR()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $XR (&amp;quot;XmlReplace&amp;quot;) ersetzt in XML nicht zulässige Zeichen:&lt;br /&gt;
* aus &amp;amp; wird $amp ;&lt;br /&gt;
* aus &amp;lt; wird &amp;amp;lt ;&lt;br /&gt;
* aus &amp;gt; wird &amp;amp;gt ;&lt;br /&gt;
* aus &amp;quot; wird &amp;amp;quot ;&lt;br /&gt;
* aus ' wird &amp;amp;apos ;&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Das Leerzeichen vor dem Semikolon soll verhindern, dass die Zeichen hier in der Darstellung ersetzt werden und wird nicht eingefügt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text &amp;lt;firmenname&amp;gt;$XR($DATA(dat,firmenname))&amp;lt;/firmenname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==$XRR()==&lt;br /&gt;
&lt;br /&gt;
Umkehrfunktion von $XR()&lt;br /&gt;
* aus $amp ; wird &amp;amp;&lt;br /&gt;
* aus &amp;amp;lt ; wird &amp;lt;&lt;br /&gt;
* aus &amp;amp;gt ; wird &amp;gt;&lt;br /&gt;
* aus &amp;amp;quot ; wird &amp;quot;&lt;br /&gt;
* aus &amp;amp;apos ; wird '&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
=Integer-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben eine ganze Zahl zurück&lt;br /&gt;
&lt;br /&gt;
==$DEC()==&lt;br /&gt;
&lt;br /&gt;
Verringert die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die verringert werden soll.&lt;br /&gt;
# optional: Zahl, um die verringert werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$DEC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ICALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit ganzzahligen Werten durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator, es stehen zur Verfügung&lt;br /&gt;
## +&lt;br /&gt;
## -&lt;br /&gt;
## *&lt;br /&gt;
## div&lt;br /&gt;
## mod&lt;br /&gt;
# Erste Zahl&lt;br /&gt;
# Zweite Zahl&lt;br /&gt;
# optional beim Operator +: weitere Summanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$ICALC(mod,17,5)&lt;br /&gt;
&lt;br /&gt;
==$INC()==&lt;br /&gt;
&lt;br /&gt;
Erhöht die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die erhöht werden soll.&lt;br /&gt;
# optional: Zahl, um die erhöht werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$INC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$INTLEN()==&lt;br /&gt;
&lt;br /&gt;
Ist der String im Parameter eine ganz Zahl, dann wird deren Länge in Zeichen zurückgegeben, andernfalls -1; ein leerer String im ersten Parameter ergibt 0.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, deren Länge ermittelt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTLEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Länge eines Strings in Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Länge ermittelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEVENSHTEIN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Levenshtein-Distanz (https://de.wikipedia.org/wiki/Levenshtein-Distanz) der beiden übergebenen Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# erster String&lt;br /&gt;
# zweiter String&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $LEVENSHTEIN(alpha,beta)&lt;br /&gt;
&lt;br /&gt;
==$POS()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Position des Substrings in einem String. Das Funktionsergebnis ist die Position, das erste Zeichen ist 1. 0 wird zurück gegeben, wenn der Substring im String nicht vorkommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Substring (nach dem gesucht wird)&lt;br /&gt;
# String (in dem gesucht wird)&lt;br /&gt;
# optional: Wenn ic (ignore case), dann wird bei der Suche die Groß- und Kleinschreibung nicht beachtet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $POS($EDT(edt1),$VAR(1),ic) &amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert zwischen der oberen und unteren Grenze&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ&lt;br /&gt;
## int - zufällige Ganzzahl &lt;br /&gt;
## date - zufälliges Datum &lt;br /&gt;
## curr - zufällige Zahl mit zwei Nachkommastellen&lt;br /&gt;
## curr4 - zufällige Zahl mit vier Nachkommastellen&lt;br /&gt;
## text1, text2, text3... - zufällige Zeile aus dem jeweiligen Text; text ist text1; untere und obere Grenze bleiben unberücksichtigt&lt;br /&gt;
## ld - zufälliger Schlüssel-Wert aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ldv - zufälliger Text aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ls - zufälliger Schlüssel-Wert aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## lsv - zufälliger Text aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
# untere Grenze&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $RANDOM(int,1,6)&lt;br /&gt;
&lt;br /&gt;
=Datumsfunktionen=&lt;br /&gt;
&lt;br /&gt;
==$INCDATE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktione  $INCDATE() verändert das Datum im ersten Parameter um die Anzahl Tage im zweiten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das verändert werden soll&lt;br /&gt;
# optional: Die Tage, um die verändert werden soll; wenn leer, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCDATE($NOW(),-3)   clr=Y&lt;br /&gt;
&lt;br /&gt;
==$INT2TIME()==&lt;br /&gt;
&lt;br /&gt;
Macht aus z.B. 1130 die Zeit 11:30&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zeit im Integer-Format&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_time=$INT2TIME($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$NOW()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit im Format dd.mm.yyyy hh:mm:ss zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #execsql   k_datechg=$NOW()&lt;br /&gt;
&lt;br /&gt;
==$NOWFMT()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und/oder die aktuelle Uhrzeit im angegebenen Format zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Formatierungsstring (Syntax wie FormatDateTime in Delphi)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$NOWFMT(yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$NOWMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit ohne Sekunden (also dd.mm.yyyy hh:mm) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$NOWMIN()&lt;br /&gt;
&lt;br /&gt;
==$TODAY()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum im Format dd.mm.yyyy zurück.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Wenn das Datum in einem anderen Format benötigt wird, ist $NOWFMT() das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$TODAY()&lt;br /&gt;
&lt;br /&gt;
==$DFMT()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;date formated&amp;quot;) Formatiert das übergebene Datum. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, ggf. mit Uhrzeit, das formatiert werden soll.&lt;br /&gt;
# Formatierungsstring wie in Delphi&lt;br /&gt;
# optional: Wenn hn (&amp;quot;hide null&amp;quot;), dann wird ein leerer String zurück gegeben, wenn das Datum kleiner/gleich 1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$DFMT($NOW(),yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Bool'sche Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
==$BFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert einen bool'schen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'scher Wert&lt;br /&gt;
# optional: Ergebnis, wenn Wert Y ('y', 'J', 'j', '1') ist, default Y&lt;br /&gt;
# optional: Ergebnis, wenn Wert N (also nicht 'Y', 'y', 'J', 'j', '1') ist, default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cout   c=$BFMT($VAR(test),x,)&lt;br /&gt;
&lt;br /&gt;
==$BOOL()==&lt;br /&gt;
&lt;br /&gt;
Wertet das bool'sche Statement im Parameter aus.&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
* = gleich&lt;br /&gt;
* == gleich ohne Berücksichtigung der Groß- und Kleinschreibung&lt;br /&gt;
* &amp;lt;&amp;gt; ungleich&lt;br /&gt;
* != ungleich&lt;br /&gt;
* &amp;gt; größer&lt;br /&gt;
* &amp;gt;= größer gleich&lt;br /&gt;
* &amp;lt; kleiner&lt;br /&gt;
* &amp;lt;= kleiner gleich &lt;br /&gt;
* and Und-Verknüpfung&lt;br /&gt;
* or ODER-Verknüpfung&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Statements werden von links nach rechts ausgewertet, and und or sind gleichwetig, gegebenenfalls müssen Klammern eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'sches Statement, das ausgewertet wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL((17 &amp;gt; 22) or (5 &amp;gt; 3))&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL(17 &amp;gt; 22 or 5 &amp;gt; 3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATECOMP()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn Datum 2 Operator Datum 1 zutreffend ist. Ansonsten wird N zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Wird kein Operator angegeben, dann wird die Anzahl der Tage Datum 2 - Datum 1 als Zahl zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum 1&lt;br /&gt;
# Datum 2&lt;br /&gt;
# Operator&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024,&amp;lt;)&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATEMINREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMINREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEMAXREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMAXREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in ein Datum wandeln lassen, werden zu 0 (30.12.1899) konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter diesem Datum entspricht. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;Test $DATEBETWEEN($TODAY(),1.1.2020,2.2.2022)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$EMPTY()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Parameter ein leerer String ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTY($DATE(n,grpname))&lt;br /&gt;
&lt;br /&gt;
==$EMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable ein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTYVAR(buchungsnr)&lt;br /&gt;
&lt;br /&gt;
==$IN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INIC() beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die erste Anweisung gibt Y und die zweite N zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INIC()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $IN() nicht beachtet beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen geben Y zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich die Variable, deren Namen im ersten Parameter steht, in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INICVAR() beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable, die geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die erste Anweisung gibt Y und die zweite N zurück&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=beta&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INICVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich die Variable, deren Namen im ersten Parameter steht, in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INVAR() nicht beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable, die geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen geben Y zurück&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=beta&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INVAR(test,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$ISCURR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen Currency-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISCURR($DATA(n,rechnungssumme))&lt;br /&gt;
&lt;br /&gt;
==$ISDATE()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in ein Datums- oder DatumsZeit-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Prüfoperation, default ist date&lt;br /&gt;
## date - prüft, ob in ein Datum gewandelt werden kann&lt;br /&gt;
## datetime - prüft, ob in ein Datums-Zeit-Wert gewandelt werden kann&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISDATE($DATA(n,beginn))&lt;br /&gt;
&lt;br /&gt;
==$ISINT()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen ganzzahligen Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISINT($DATA(n,tage))&lt;br /&gt;
&lt;br /&gt;
==$INTMAX()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMAX($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$INTMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMIN($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$NEMPTY()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;not empty&amp;quot;) Gibt Y zurück, wenn der Parameter nicht leer ist. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalt geprüft wird. Leerzeichen gelten als leerer String.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 &lt;br /&gt;
 ~ $NEMPTY($EDT(edt1))&lt;br /&gt;
&lt;br /&gt;
==$NEMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable kein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $NEMPTYVAR(kundennr)&lt;br /&gt;
&lt;br /&gt;
==$NOT==&lt;br /&gt;
&lt;br /&gt;
Invertiert einen bool'schen Wert. Aus Y (y, J, j, 1) wird N und aus N wird Y.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der invertiert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $NOT(2)&lt;br /&gt;
&lt;br /&gt;
==$NUMBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in eine Zahl wandeln lassen, werden zu 0 konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter dieser Zahl entspricht. Siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56,)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die beiden Beispiele unterscheiden sich auf den ersten Blick kaum. Bei der ersten Zeile muss jedoch eine Schuhgröße eingegeben werden. Bleibt das Feld im VL-Segment leer, so wird dieser fehlende Wert nach 0 konvertiert und liegt nicht zwischen 28 und 56.&lt;br /&gt;
&lt;br /&gt;
Anders bei der zweiten Zeile: Das Komma vor der schließenden Klammer sorgt für einen vierten Parameter, der ebenfalls leer ist und damit nach 0 gewandelt wird. Auf diese Weise werden die leere Eingaben (und die Eingabe von 0) gültig.&lt;br /&gt;
&lt;br /&gt;
==$REGEX()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $REGEX() (&amp;quot;regular expressions&amp;quot;) prüft, ob der String in Parameter 1 den Anforderungen von Parameter 2 entspricht (Ergebnis Y) oder nicht (Ergebnis N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft werden soll&lt;br /&gt;
# Regulärer Ausdruck, mit dem der String in Parameter 2 geprüft wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $REGEX($VAR(med),^[A-Z]{3}$)&lt;br /&gt;
&lt;br /&gt;
==$TEXT_HASLINE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $TEXT_HASLINE() prüft, ob die als Parameter 2 übergebene Textzeile in einem Text vorkommt. Es wird nur auf komplette Textzeilen geprüft. Wird zum Beispiel verwendet, um eine Liste von Kundennummern zu erstellen, und dann auf einzelne Nummern zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# Textzeile, deren Vorkommen geprüft wird&lt;br /&gt;
# Ergebnis, wenn die Textzeile vorkommt; default Y&lt;br /&gt;
# Ergebnis, wenn die Textzeile nicht vorkommt; default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $TEXT_HASLINE(1,990000018,1,0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$VIBAN()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VIBAN() (&amp;quot;validate IBAN&amp;quot;) prüft eine IBAN anhand der Prüfziffern (3. und 4. Stelle).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# IBAN, die geprüft werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VIBAN(DE12345)&lt;br /&gt;
&lt;br /&gt;
=Currency-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==$CCALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit Festkommawerten durch&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
** + - Addition&lt;br /&gt;
** - - Subtraktion&lt;br /&gt;
** * - Multiplikation&lt;br /&gt;
** / - Division&lt;br /&gt;
** % - Division und Multiplikation des Ergebnisses mit 100&lt;br /&gt;
** +4 - Addition und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** -4 - Subtraktion und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** *4 - Multiplikation und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** /4 - Division und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** %4 - Division, Multiplikation des Ergebnisses mit 100 und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
** B, b, B4, b4 - Bruttobetrag, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** E, e, E4, e4 - Enthaltene MWSt, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** M, m, M4, m4 - MWSt, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** N, n, N4, n4 - Nettobetrag, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator&lt;br /&gt;
# und weitere: Operanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 10&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(+,1,2,3,4)&amp;quot;&lt;br /&gt;
 -- Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #val_set   n=1   z=1038,87&lt;br /&gt;
 #coutl $CCALC(N,$VAL(1),19)  -  $CCALC(E,$VAL(1),19)  -&lt;br /&gt;
&lt;br /&gt;
==$CURR()==&lt;br /&gt;
&lt;br /&gt;
Currency-Werte müssen in Funktionen mit einem Punkt als Dezimaltrennzeichen eingegeben werden, da das Komma die Parameter trennt. Sofern Konstanten verwendet werden, lässt sich das einfach so eingeben, sobald aber die Werte aus anderen Funktionen kommen (zum Beispiel $DATA()), müssen sie dann mit $CURR() in dieses Format umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Vorkommastellen&lt;br /&gt;
# Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 43,48&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,$CURR(2,3))&amp;quot;&lt;br /&gt;
 -- zum Vergleich; Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert Curreny-Werte&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert&lt;br /&gt;
# optional: Formatierungsstring, default 0.00&lt;br /&gt;
# optional: wenn hn (&amp;quot;hide null&amp;quot;), dann werden leere Strings als Wert auch als leerer String ausgegeben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=###,###,###,##0.00&lt;br /&gt;
 #val_set   n=2   z=1337,42&lt;br /&gt;
 #cout   c=$CFMT($VAL(2),$VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ONLYNUM()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass in einem String nur Zahlen (ggf. auch Kommas oder Punkte) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl&lt;br /&gt;
# Art der Operation; default numkomma&lt;br /&gt;
## flnnc (&amp;quot;from last not numeric character&amp;quot;) - Ab dem letzten Zeichen, das keine Ziffer ist&lt;br /&gt;
## num - Nur Ziffern, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numkomma - Nur Ziffern und Kommata, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numpoint - Nur Ziffern und Punkte, alle anderen Zeichen werden entfernt&lt;br /&gt;
## ufnnc (&amp;quot;until first not numeric character&amp;quot;) - vom Anfang bis zum ersten Zeichen, das keine Ziffer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 -- Ergebnis 123456&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,num)&lt;br /&gt;
 -- Ergebnis 123&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,ufnnc)&lt;br /&gt;
 -- Ergebnis 456 &lt;br /&gt;
 #coutl   $ONLYNUM(123-456,flnnc)&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22519</id>
		<title>Modul VAR neu</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22519"/>
		<updated>2025-05-22T12:11:08Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #dir_proc */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das Modul Var sammelt neben den Variablen auch die grundlegenden Prozeduren und Funktionen.&lt;br /&gt;
&lt;br /&gt;
=Variable=&lt;br /&gt;
&lt;br /&gt;
==#var_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#setvar setzt den Wert einer Variablen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis: Variable sind global, auf sie kann auch in Sub-Kommandos zugegriffen werden. Values sind dagegen lokal.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*rf (replace functions) - Wenn Y, dann werden nach der Zuweisung auf die Variable nochmals die Funktionen ersetzt. Wird zum Beispiel benötigt, wenn Code mit Funktionen mittels $DATA() aus der Datenbank geladen wird; Funktionen werden ersetzt, default N; siehe Beispiel&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_set   n=test2  z=$GUID()&lt;br /&gt;
 #var_set   n=edt    z=$EDT(edt1)   ie=42&lt;br /&gt;
 #var_set   n=_page_kunde_adressänderung_ro   z=N   zn=Y   zr=Y   r=kundenservice&lt;br /&gt;
&lt;br /&gt;
Zum Parameter rf: $NOW() in die Zwischenablage kopieren und dann ausführen:&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=N&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=Y&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_setempty==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_setempty setzt den Wert einer Variablen, sofern sie (noch) leer ist.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Besteht der Variableninhalt aus Leerzeichen, gilt die Variable auch als leer.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_setempty   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_setempty   n=test2  z=$GUID()&lt;br /&gt;
 #var_setempty   n=edt    z=$EDT(edt1)    ie=42&lt;br /&gt;
&lt;br /&gt;
==#var_add==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_add fügt einer Variablen einen Wert hinzu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. &lt;br /&gt;
* y -Typ der Operation; default ''text''&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** month - Es wird dem Datum eine Anzahl von Monaten hinzugefügt&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
*z - Wert, welcher der Variablen hinzugefügt wird, Funktionen werden ersetzt, default ist ein leerer String oder eine 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$NOW()&lt;br /&gt;
 #var_add   n=test   z=1   y=datetime&lt;br /&gt;
 #cout   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_log==&lt;br /&gt;
&lt;br /&gt;
Schreibt den Inhalt aller Variablen in das Debug-Log.&lt;br /&gt;
&lt;br /&gt;
Wird nur zur Fehlersuche verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_log&lt;br /&gt;
&lt;br /&gt;
==$VAR()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $VAR() wird auf den Inhalt der Variable zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
# optional: Der Wert wird vor oder nach der Rückgabe als Funktionsergebnis verändert; nur für ganzzahlige Werte&lt;br /&gt;
## ib (&amp;quot;increment before&amp;quot;) - Der Wert wird vor der Rückgabe um eins erhöht&lt;br /&gt;
## db (&amp;quot;decrement before&amp;quot;) - Der Wert wird vor der Rückgabe um eins verringert&lt;br /&gt;
## ia (&amp;quot;increment after&amp;quot;) - Der Wert wird nach der Rückgabe um eins erhöht&lt;br /&gt;
## da (&amp;quot;decrement after&amp;quot;) - Der Wert wird nach der Rückgabe um eins verringert&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #message  c=$VAR(test)&lt;br /&gt;
 #var_set  n=neuer_wert   z=$VAR(wert)   ie=$VAR(alternativwert)&lt;br /&gt;
 #execsql   k_lfdnr=$VAR(lfdnr,ib)&lt;br /&gt;
&lt;br /&gt;
=Kommandos=&lt;br /&gt;
&lt;br /&gt;
(Primär- und Sub) Kommandos sind üblicherweise benannt und werden im Code-Dialog eingegeben.&lt;br /&gt;
&lt;br /&gt;
Es besteht jedoch auch die Möglichkeit, lokale Kommandos innerhalb eines anderen Kommandos zu definieren. Diese Kommandos haben statt eines Kommando-Namens dann dann eine Kommando-Nummer.&lt;br /&gt;
&lt;br /&gt;
Lokale Kommandos werden üblicherweise für folgende Zwecke verwendet:&lt;br /&gt;
&lt;br /&gt;
* Bei der Verwendung von xlive werden bisweilen Prozeduren eingesetzt, die ihrerseits ein Kommando aufrufen (z.B. #sql_open). Wenn dieses Kommando nichts bereits existiert, kann es nur als lokales Kommando erstellt werden.&lt;br /&gt;
&lt;br /&gt;
* Wenn das auszuführende Kommando auf derselben Seite stehen soll wie die aufrufende Prozedur.&lt;br /&gt;
&lt;br /&gt;
Siehe als Beispiel: [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd fügt dem Kommando eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd fügt dem ersten Kommando eine Zeile hinzu, #cmd2 fügt dem zweiten Kommando eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd hat keine benannten Parameter. Die ganze Zeile nach dem #cmd und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd3 #text $DATA(n,login);$DATA(n,shortname);$DATA(n,firstname);$DATA(n,lastname);$DATA(n,userid);&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clear löscht ein Kommando&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd_clear löscht das erste Kommando, #cmd_clear2 löscht das zweite Kommando, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #cmd_clear Zeichen, so werden die dem gerade gelöschten Kommando hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear3&lt;br /&gt;
 #cmd_clear #grd_add   i=grid   f_logtext=&amp;quot;Kunde angerufen und nicht erreicht.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#cmd_clearall==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clearall löscht alle Kommandos&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clearall&lt;br /&gt;
&lt;br /&gt;
=CSV=&lt;br /&gt;
&lt;br /&gt;
Die CSV-Routinen werden verwendet, um CSV-Dateien einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==#csv_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_open öffnet eine CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_open öffnet die erste CSV-Datei, #csv_open2 öffnet die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*ber - wenn Y, werden die Zeilenumbrüche innerhalb von Feldern durch Leerzeichen ersetzt. Die Felder müssen dabei in doppelten Anführungszeichen eingeschlossen sein.&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - (&amp;quot;Filename&amp;quot;) Dateiname der CSV-Datei&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich. Muss bereits hier gesetzt werden, wenn mit $CSV_LINE auf den Header zugegriffen werden soll, bevor #csv_line ausgeführt wird.&lt;br /&gt;
*txt (&amp;quot;Text&amp;quot;) - alternativ zum Dateinamen fn die Nummer eines Textes, der als CSV-Datei verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open  fn=c:\temp\text.csv&lt;br /&gt;
&lt;br /&gt;
==#csv_line==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_line geht zeilenweise durch die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_line geht durch die erste CSV-Datei, #csv_line2 geht durch die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;database&amp;quot;) - Die Datenbank, für welche die Transaktion ausgeführt wird, wenn ert=Y gesetzt ist. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
*er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
*ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt, Funktionen werden ersetzt&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich.&lt;br /&gt;
*m (&amp;quot;maximum&amp;quot;) - Maximale Anzahl der Zeilen, die verarbeitet wird. Wird gerne bei der Entwicklung verwendet, um die Bearbeitungsgeschwindigkeit zu erhöhen. Funktionen werden ersetzt&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird im Falle einer Exception die Bearbeitung nicht abgebrochen, sondern lediglich Warnungen geloggt; Default N, Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Semikolon, Funktionen werden ersetzt&lt;br /&gt;
*trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_line  er=test_csv_line   hhr=Y   m=3&lt;br /&gt;
&lt;br /&gt;
==#csv_check==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_check prüft die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnt (&amp;quot;count&amp;quot;) - Anzahl der Header-Einträge, die geprüft wird; Funktionen werden ersetzt&lt;br /&gt;
*h1, h2... (&amp;quot;header&amp;quot;) - Eintrag im Header, der auf existenz geprüft wird; Groß und Kleinschreibung ist unerheblich, Funktionen werden ersetzt.&lt;br /&gt;
*n (&amp;quot;name&amp;quot; / &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in die/den das Ergebnis (Y oder N) geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*res (&amp;quot;result&amp;quot;) - Name der Variable oder Nummer des Values, in die/den der Ergebnistext geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwischen den einzelnen Spalten; Funktionen werden ersetzt&lt;br /&gt;
*y - Typ der Prüfung; Funktionen werden ersetzt, default header&lt;br /&gt;
** header - Prüft die Existenz von Spaltennamen im Header. Die zu prüfenden Spaltennamen werden als h1, h2... übergeben, cnt ist entsprechend zu setzen. Wenn alle geprüften Spaltennamen vorhanden sind, wird Y zurück gegeben, ansonsten N. Die fehlenden Spaltennamen werden als Ergebnistext zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open   fn=C:\temp\mad\done\MTF3108_ET2607_selektion.CSV&lt;br /&gt;
 #csv_check   n=1   res=2   cnt=3   h1=eins   h2=zwei   h3=drei&lt;br /&gt;
 #coutl $VAL(1) - $VAL(2)&lt;br /&gt;
&lt;br /&gt;
==#csv_paste==&lt;br /&gt;
&lt;br /&gt;
Übernimmt eine CSV-Datei aus der Zwischenablage. Auf die Werte kann mit $SEPLINE() zugegriffen werden, siehe [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
'''Multi-Row'''&lt;br /&gt;
&lt;br /&gt;
Mit dem Multi-Row-Modus können Daten eingelesen werden, die in einer Zeile mehrere gleichartige Werte haben.&lt;br /&gt;
&lt;br /&gt;
Daten, die im Single-Row-Modus wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465&lt;br /&gt;
 01.01.2020     8574&lt;br /&gt;
 01.01.2020     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     3456&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     4457&lt;br /&gt;
 03.01.2020     7658&lt;br /&gt;
&lt;br /&gt;
Würden im Multi-Row-Modus wie folgt aussehen (und könnten auch so eingelesen werden):&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465     8574     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436     6578     3456     6578     4457     7658&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Wenn dieser Parameter einen Wert hat, dann muss die kopierte CSV-Datei in der ersten Zeile auch diesen Wert haben, oder die Aktion wird abgebrochen; Funktionen werden ersetzt&lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden.&lt;br /&gt;
* mrs (&amp;quot;multi row start&amp;quot;) - Erste Spalte für den Multi-Row-Bereich&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Tabulatorzeichen&lt;br /&gt;
* trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ; default s&lt;br /&gt;
** m - multi; siehe Abschnitt Multi-Row&lt;br /&gt;
** s - single; die CSV-Datei wird Zeile für Zeile eingelesen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
* [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
 #csv_paste   er=imp_line   hhr=Y&lt;br /&gt;
 #csv_paste   er=imp_line   y=m   mrs=1&lt;br /&gt;
&lt;br /&gt;
==$CSV()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV() greift auf einen Feldinhalt der aktuellen CSV-Zeile zu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Spalte oder 0-relative Spaltennummer. Name der Spalte setzt voraus, dass bei #csv_line der Parameter hhr gleich Y ist.&lt;br /&gt;
# optional: Stelle der Zeichens, ab dem der Inhalt des CSV-Feldes zurück gegeben wird&lt;br /&gt;
# optional: Anzahl der Zeichen, die maximal zurück gegeben werden; wird meist dafür verwendet, damit die maximale Länge von Datenbankfeldern nicht überschritten wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0)&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird in der ersten CSV-Datei (#csv_open) auf die erste Spalte (0, da 0-relativ) zugegriffen.&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0,1,30)&lt;br /&gt;
&lt;br /&gt;
Wie oben, nur werden nur die ersten 30 Zeichen zurück gegeben&lt;br /&gt;
&lt;br /&gt;
==$CSV_LINE()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV_LINE() Gibt eine ganze Zeile einer CSV-Datei zurück&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Zeile: header gibt die Header-Zeile zurück, current die aktuelle Zeile in #csv_line&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CSV_LINE wird insbesondere dafür verwendet, um CSV-Dateien mit Daten zu ergänzen. Hier im Beispiel wird jede Zeile mit einer GUID ergänzt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #text $CSV_LINE(1,current)$GUID();&lt;br /&gt;
 &lt;br /&gt;
 #csv_open   fn=c:\temp\ex.csv   hhr=Y&lt;br /&gt;
 #text_clear $CSV_LINE(1,header)guid;&lt;br /&gt;
 #csv_line   er=1   hhr=Y&lt;br /&gt;
 &lt;br /&gt;
 #text_save   fn=c:\temp\ex2.csv&lt;br /&gt;
&lt;br /&gt;
Nach dem Öffnen der bestehenden CSV-Datei (es muss hier bereits hhr gesetzt werden) wird zunächst der Header in Text 1 eingefügt, ergänzt um die Spalte ''guid'' und das abschließende Semikolon. Danach gehen wir mit #csv_line durch alle Zeile, fügen diese komplett in Text 1 ein und hängen eine GUID hinten dran. Danach wird die Datei gespeichert.&lt;br /&gt;
&lt;br /&gt;
=Text=&lt;br /&gt;
&lt;br /&gt;
==#text==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text fügt dem Text eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text fügt dem ersten Text eine Zeile hinzu, #text2 fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Und jetzt noch eine GUID: $GUID()&lt;br /&gt;
 #text Der folgende Text kommt in Großbuchstaben: $UPP(hello world)&lt;br /&gt;
&lt;br /&gt;
==#textn==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#textn fügt dem Text eine Zeile hinzu. Im Unterschied zu #text werden dabei keine Funktionen ersetzt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #textn fügt dem ersten Text eine Zeile hinzu, #text2n fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #textn und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden dabei '''nicht''' ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #textn Zeile 1&lt;br /&gt;
 #textn Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_clear löscht einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_clear löscht den ersten Text, #text_clear2 löscht den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #text_clear Zeichen, so werden die dem gerade gelöschten Text hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear7&lt;br /&gt;
 #text7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
Das vorangestellt #text_clear stellt sicher, dass Text7 leer ist. Alternativ könnte man formulieren:&lt;br /&gt;
&lt;br /&gt;
 #text_clear7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_save==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_save speichert einen Text in einer Datei.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_save speichert den ersten Text, #text_save2 speichert den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* bom (&amp;quot;Byte order mark&amp;quot;) - Wenn Y, dann wird die Datei mit BOM geschrieben; default Y&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu speichernden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname, unter dem die Datei gespeichert wird. Bestehende Dateien werden überschrieben, sofern das Betriebssystem das nicht verhindert (z.B, weil die Datei gerade geöffnet ist)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Öffnet die gespeicherte Datei gleich anschließend.&lt;br /&gt;
*sort - Wenn Y, dann wird die Datei vor dem Speichern sortiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Hello world&lt;br /&gt;
 #text_save  fn=$DIR(userroot)hello_world.txt&lt;br /&gt;
 #text_save  fn=c:\temp\export_vert_export.prepared_.csv   e=utf8   bom=N&lt;br /&gt;
&lt;br /&gt;
==#text_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_open öffnet einen Text aus einer Datei, der bisherige Inhalt der Datei wird überschrieben.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_open öffnet den ersten Text, #text_open2 öffnet den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname der Datei, die geöffnet wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_open  fn=$DIR(userroot)test.txt&lt;br /&gt;
 #text Eine weitere Zeile, $GUID()&lt;br /&gt;
 #text_save  fn=$DIR(userroot)test.txt&lt;br /&gt;
&lt;br /&gt;
==#text_props==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_props stellt Eigenschaften des Textes ein.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_props bezieht sich auf den ersten Text, #text_props2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* dub (&amp;quot;duplicates&amp;quot;) - Verhalten einer sortierten Liste bezüglich Dubletten&lt;br /&gt;
** acc (&amp;quot;accept&amp;quot;) - Dubletten werden akzeptiert&lt;br /&gt;
** err (&amp;quot;error&amp;quot;) - Dubletten führen zu Fehlern&lt;br /&gt;
** ign (&amp;quot;ignore) - Dubletten werden ignoriert&lt;br /&gt;
* srt (&amp;quot;sorted&amp;quot;) - Wenn ja, dann ist die Liste sortiert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_props   srt=Y   dup=ign&lt;br /&gt;
&lt;br /&gt;
==#text_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_set setzt eine bestimmte Zeile eines Textes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_set bezieht sich auf den ersten Text, #text_set2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;index&amp;quot;) - 0-relativer Index der Zeile, die geschrieben werden soll. Mit ''last'' kann die letzte Zeile geschrieben werden, mit ''all'' werden alle Zeilen ersetzt, das wird dann gebraucht, wenn mehrzeiliger Text zugewiesen werden soll; Funktionen werden ersetzt&lt;br /&gt;
* z - Text, der geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text_set   i=2   z=&amp;quot;dritte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=last   z=&amp;quot;letzte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=all   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
==#text_sort==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_sort sortiert einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_sort bezieht sich auf den ersten Text, #text_sort2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* y - Typ, default alpha, Funktionen werden ersetzt&lt;br /&gt;
** alpha - sortiert alphanumerisch&lt;br /&gt;
** inv - invertiert die gegebene Reihenfolge&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=&amp;quot;,OU=2nd_Level_T1,OU=Kundenservice,OU=Benutzer,OU=Testtours,OU=Travel&amp;quot;&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text_dissect   z=$VAL(1)   sep=&amp;quot;,OU=&amp;quot;&lt;br /&gt;
 #coutl  $TEXT(1)&lt;br /&gt;
 #text_sort   y=inv&lt;br /&gt;
 #text_compose   n=1   sep=.&lt;br /&gt;
 #val_set   n=1   z=tt.$VAL(1)&lt;br /&gt;
 #coutl $VAL(1)&lt;br /&gt;
&lt;br /&gt;
 Ergebnis ist:&lt;br /&gt;
 2nd_Level_T1&lt;br /&gt;
 Kundenservice&lt;br /&gt;
 Benutzer&lt;br /&gt;
 Testtours&lt;br /&gt;
 tt.Testtours.Benutzer.Kundenservice.2nd_Level_T1.&lt;br /&gt;
&lt;br /&gt;
==#text_dissect==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_dissect zerteilt einen String anhand einer vorgegebenen Trennzeichenfolge und fügt das Ergebnis dem betreffenden Text hinzu. Gegebenenfalls muss der Text vorher mit #text_clear geleert werden.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_dissect bezieht sich auf den ersten Text, #text_dissect bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - wenn Y, wird die sep-Zeichenfolge noch mal dem String angehängt; default N, Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, anhand der String zerteilt wird; Funktionen werden ersetzt&lt;br /&gt;
* z - String, der zerlegt wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_compose==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_compose setzt einen Text mithilfe eines Trennzeichens zu einem String zusammen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_compose bezieht sich auf den ersten Text, #text_compose bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - Wenn Y, wird die Trennzeichenfolge auch noch mal am Ende des Strings eingefügt; default N, Funktionen werden ersetzt&lt;br /&gt;
* n - Nummer des Values oder Name der Variable, in welche der String geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichenfolge, die beim Zusammenfügen des Textes verwendet wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_act==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_act bearbeitet einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_act bezieht sich auf den ersten Text, #text_act2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text der Zeile, die bei insert eingefügt werden soll; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* cu (&amp;quot;current&amp;quot;) - 0-relative Zeilennummer der Operation; default 0, Funktionen werden ersetzt&lt;br /&gt;
* ne (&amp;quot;new&amp;quot;) - 0-relative Zeilennummer als Ziel bei move; default 0, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt&lt;br /&gt;
** delete - Löscht die Zeile an Position cu (&amp;quot;current&amp;quot;)&lt;br /&gt;
** insert - Fügt den Text c an der Position cu (&amp;quot;current&amp;quot;) ein&lt;br /&gt;
** move - verschiebt die Zeile cu (&amp;quot;current&amp;quot;) nach Zeile ne (&amp;quot;new&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #text_act   y=move   cu=0&lt;br /&gt;
&lt;br /&gt;
==#text_loop==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_loop geht durch die Zeilen eines Textes und ruft für jede Zeile ''er'' auf&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_loop  bezieht sich auf den ersten Text, #text_loop2  bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich ert bezieht&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m - (&amp;quot;maximum&amp;quot;) Es wird maximal für die Anzahl der angegebenen Zeilen das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* n - Name der Variable, in welche die 0-relative Schleifenvariable geschrieben wird. (Es würde auch in einen Value geschrieben, wenn es sich um eine Nummer handelt, das ergibt in der Praxis aber meist nicht viel Sinn) Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear eins&lt;br /&gt;
 #text zwei&lt;br /&gt;
 #text drei&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear #coutl - $TEXT(1,$VAR(eins))&lt;br /&gt;
 #text_loop   er=1   n=eins&lt;br /&gt;
&lt;br /&gt;
==#tvl_add==&lt;br /&gt;
&lt;br /&gt;
Addiert dem Wert in einer Text-Valueliste einen Wert hinzu. Es handelt sich dabei um eine nummerierte Prozedur: #tvl_add arbeitet mit Text 1, #tvl_add2 mit Text 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Zeile, der ein Wert hinzugefügt wird; Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Operation, Funktionen werden ersetzt, default text&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
* z - Der Wert, der hinzugefügt wird&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text eins=1&lt;br /&gt;
 #text zwei=2&lt;br /&gt;
 #text drei=3&lt;br /&gt;
 #tvl_add   y=int   n=zwei   z=1&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==$TEXT()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $TEXT() wird auf den Inhalt des Textes zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# optional Zeile des Textes (0-relativ). Wenn es keinen zweiten Parameter gibt, wird der komplette Text zurück gegeben. Alternativ als zweiter Parameter eine Sonderfunktion:&lt;br /&gt;
## cnt / count - Gibt die Anzahl der Zeilen zurück&lt;br /&gt;
## last - Gibt die letzte Zeile zurück&lt;br /&gt;
## ix - Gibt die Position des Textes im dritten Parameter zurück&lt;br /&gt;
## as_line - Gibt den Text als eine Zeile zurück, Zeilenumbrüche werden durch den dritten Parameter ersetzt&lt;br /&gt;
# optional in abhängigkeit vom zweiten Paremeter&lt;br /&gt;
## wenn zweiter Parameter ix: Textzeile, nach der mit ix gesucht wird&lt;br /&gt;
## wenn zweiter Parameter as_line: Zeichenfolge, mit der die Zeilenumbrüche ersetzt werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Zeile 3&lt;br /&gt;
 #message  c=$TEXT(1)&lt;br /&gt;
&lt;br /&gt;
 #code url=$TEXT(1,as_line,&amp;amp;)&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich gilt in BAL: Eine Prozedur - eine Zeile.&lt;br /&gt;
&lt;br /&gt;
Bei vielen und/oder langen Parametern führt das zu recht langen Code-Zeilen und zu Unübersichtlichkeit. Hier können nun Teile der Parameter mit #code in weitere Zeile ausgelagert werden, deren Inhalt dann mit $CODE$ oder $CODE$ der eigentlichen Code-Zeile hinzugefügt wird.&lt;br /&gt;
&lt;br /&gt;
==#code==&lt;br /&gt;
&lt;br /&gt;
Fügt Text dem Code-Speicher hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#code hat keine benannten Parameter. Die ganze Zeile nach dem #code und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=G:\pics\pic5d68865cdaba62_62767562.jpg&lt;br /&gt;
 #code fn2=G:\pics\pic5d913c48682128_67979256.jpg&lt;br /&gt;
 #email_send   from=test@****.de   to=info@*****************.de   bcc=info@*****.de   subject=Testmail   text=$TEXT(1)   $CODE$&lt;br /&gt;
&lt;br /&gt;
==$CODE$ / $CODEN$==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CODE$ und $CODEN$ sind keine Funktionen, auch wenn sie auf den ersten Blick ähnlich aussehen. Sie haben keine Parameter und auch keine Klammern, dafür ein abschließendes $.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen fügen den Code-Speicher der jeweiligen Zeile hinzu. $CODE$ löscht danach den Code-Speicher, $CODEN$ tut das nicht, so dass dieselben Parameter wiederholt eingefügt werden können (beim letzten Einfügen sollte dann $CODE$ verwendet werden).&lt;br /&gt;
&lt;br /&gt;
=Separierte Zeile=&lt;br /&gt;
&lt;br /&gt;
Eine separierte Zeile ist eine Textzeile, die mehrere gleichartige Werte enthält, die durch Trennzeichen getrennt sind.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 3244,4465,7763,4536,4356,7777&lt;br /&gt;
&lt;br /&gt;
Solche Zeilen können mit #sepline aufgetrennt werden.&lt;br /&gt;
&lt;br /&gt;
==#sepline==&lt;br /&gt;
&lt;br /&gt;
Trennt eine separierte Zeile auf und führt für jeden Wert das mit er angegebene Kommando aus.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur (#sepline, #sepline2...)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y; Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, für welche die Transaktion gestartet wird, wenn ert=Y. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern (&amp;quot;each row no&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Wenn Y, wird für jeden Wert der separierten Zeile eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Es wird maximal für die Anzahl der angegebenen Werte das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten; Funktionen werden ersetzt.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N; Funktionen werden ersetzt.&lt;br /&gt;
* nn (&amp;quot;not null&amp;quot;) - Wenn Y, dann wird er nur für Werte der separierten Zeile aufgerufen, die nicht leer sind. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Das oder die Trennzeichen; default ist das Semikolon, Funktionen werden ersetzt.&lt;br /&gt;
* z - Der Inhalt der separierten Zeile; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(1)&lt;br /&gt;
 #sepline z=3244,4465,7763,4536,4356,7777   sep=,   er=1&lt;br /&gt;
&lt;br /&gt;
==$SEPLINE()==&lt;br /&gt;
&lt;br /&gt;
Greift auf den einzelnen Wert einer mit #sepline getrennten Zeile zu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der separierten Zeile&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(3)&lt;br /&gt;
 #sepline3 z=3244;4465;7763;4536;4356;7777     er=1&lt;br /&gt;
&lt;br /&gt;
=User und Rechte=&lt;br /&gt;
&lt;br /&gt;
Aus Gründen der Übersichtlichkeit ist die Rechtevergabe zweistufig:&lt;br /&gt;
&lt;br /&gt;
# Es werden (meist am Anfang eines Primär-Kommandos) Rechte-Definitionen erstellt, die einer oder mehreren Benutzergruppen Rechte (lesen oder lesen und schreiben) zuweisen. Die Rechte werden dabei implizit auch allen Untergruppen der angegebenen Benutzergruppe erteilt (Zum Beispiel: Rechte der Gruppe ''user'' hat auch implizit die Gruppe ''user.admin'').&lt;br /&gt;
# Dem Parameter r verschiedener Prozeduren kann dann eine Rechte-Definition zugewiesen werden.&lt;br /&gt;
&lt;br /&gt;
Den Parameter r als Rechte-Definition berücksichtigen die folgenden Prozeduren:&lt;br /&gt;
&lt;br /&gt;
* #frm&lt;br /&gt;
* Buttons (#btn, #btns_btn)&lt;br /&gt;
* Alle Segmente (#text_seg, #memo_seg, #btns_seg, vl_seg, #grd_seg, #xgrd_seg)&lt;br /&gt;
* Tree (#tree_add, #tree_fill, #tree_fillsql, Lese-Recht reicht)&lt;br /&gt;
* Grid-Spalten (#grd_col, #xgrd_col)&lt;br /&gt;
* #vl_line (für die komplette Zeile (r) und die einzelne Zelle (r1, r2, r3...))&lt;br /&gt;
&lt;br /&gt;
Wo der Parameter r nicht gesetzt ist, wird die Rechte-Definition der Formulars verwendet.&lt;br /&gt;
&lt;br /&gt;
==#rights==&lt;br /&gt;
&lt;br /&gt;
Setzt eine Rechte-Definition im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Rechte-Definition; default ist ''frm'', also dsa Default-Recht für das Formular.&lt;br /&gt;
* r_ (&amp;quot;right&amp;quot;) - Prefix für die Benutzergruppe. Für die Rechte-Definition sind die folgenden Werte zulässig&lt;br /&gt;
** n (&amp;quot;no&amp;quot;) - kein Recht&lt;br /&gt;
** r (&amp;quot;read&amp;quot;) - nur lesen&lt;br /&gt;
** w (&amp;quot;write&amp;quot;) - lesen und schreiben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights  n=frm   r_user=r   r_user.admin=w&lt;br /&gt;
&lt;br /&gt;
Setzt für alle User das Lese-Recht und für Administratoren das Lese- und Schreibrecht.&lt;br /&gt;
&lt;br /&gt;
==#rights_clear==&lt;br /&gt;
&lt;br /&gt;
Löscht alle Rechte-Definitionen im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
(Wird in der Praxis selten benötigt, weil Kommandos mit leerer Rechte-Definition starten.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights_clear&lt;br /&gt;
&lt;br /&gt;
==$USERID()==&lt;br /&gt;
&lt;br /&gt;
Die ID des angemeldeten Users&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kusr=$USERID()&lt;br /&gt;
&lt;br /&gt;
==$RIGHTUSERID()==&lt;br /&gt;
&lt;br /&gt;
Administratoren können andere User einstellen (Userliste links unten im BAF-Client), vor allem um deren Rechte zu prüfen. Die UserID dieses ausgewählten Users kann mit der Funktion $RIGHTUSERID() ermittelt werden.&lt;br /&gt;
&lt;br /&gt;
In fast allen Fällen gilt der folgende Grundsatz: Lesende Operationen mit $RIGHTUSERID(), schreibende Operationen mit $USERID().&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_open   kusr=$RIGHTUSERID()&lt;br /&gt;
&lt;br /&gt;
==$ADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der angemeldete User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $ADM()&lt;br /&gt;
&lt;br /&gt;
==$RADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der ausgewählte User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $RADM()&lt;br /&gt;
&lt;br /&gt;
=Ausführen=&lt;br /&gt;
&lt;br /&gt;
==#exec==&lt;br /&gt;
&lt;br /&gt;
Führt ein anderes Kommando aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Names des (Primär- oder Sub-) Kommandos, das ausgeführt werden soll.&lt;br /&gt;
* ex (&amp;quot;exception&amp;quot;) - Name oder Nummer des Kommandos, das ausgeführt wird, wenn bei der Ausführung von cmd eine Exception auftritt; siehe Beispiele&lt;br /&gt;
* fin (&amp;quot;finally&amp;quot;) - Name oder Nummer des Kommandos, das nach der Ausführung von cmd ausgeführt wird - egal ob eine Exception aufgetreten ist oder nicht. Wird nur berücksichtigt, wenn der Parameter ex nicht gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel löst das Problem, dass ein neues PDF unter demselben Dateinamen nicht erstellt werden kann, wenn beim vorherigen Versuche der Erstellung eine Exception aufgetreten ist. In einem solchen Fall wurde ein #pdf_start, aber kein #pdf_stop ausgeführt, und die geöffnete Datei sperrt diesen Dateiname, bis der BAF-Client geschlossen wird. Lösung dieses Problems ist es, im Parameter ex ein #pdf stop auszuführen; auf das Öffnen der Datei kann in einem solchen Fall verzichtet werden. Mit der Funktion $DATA() wird hier im Beispiel gezielt eine Exception ausgelöst.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test_pdf&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #pdf_text  c=&amp;quot;Hello World&amp;quot;&lt;br /&gt;
 -- #cmd #pdf_text  c=&amp;quot;Hello World $DATA(dat,test)&amp;quot;&lt;br /&gt;
 #cmd #pdf_stop   o=Y&lt;br /&gt;
 &lt;br /&gt;
 #pdf_start  fn=$DIR(doc)\test.pdf&lt;br /&gt;
 #exec   cmd=1   ex=&amp;quot;#pdf_stop   o=N&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test_pdf executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#batchexec==&lt;br /&gt;
&lt;br /&gt;
Speichert den Text n in der Datei batch.bat und führt diese aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clr (&amp;quot;clear&amp;quot;) - Wenn Y, wird der Text nach Ausführung des Batch-Datei gelöscht; Default Y; Funktionen werden ersetzt;&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes; der mit #text gespeicherte Text hat die Nummer 1 &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #batchexec   n=1&lt;br /&gt;
&lt;br /&gt;
==#file_open==&lt;br /&gt;
&lt;br /&gt;
Öffnet eine Datei (oder auch eine Webseite)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder die URL der Webseite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_open  fn=c:\temp\test.csv&lt;br /&gt;
 #file_open  fn=https://www.google.de&lt;br /&gt;
&lt;br /&gt;
==#loop==&lt;br /&gt;
&lt;br /&gt;
BAL kennt keine Schleifen als Sprachelement. Um Schleifen mit einer fest Schleifenzahl auszuführen, wird die Prozedur #loop verwendet. lf muss nicht kleiner als lt sein, #loop kann auch von oben nach unten zählen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* lf (&amp;quot;loop from&amp;quot;) - Anfangswert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* lt (&amp;quot;loop to&amp;quot;) - Endwert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in der die Schleifenvariable gespeichert wird (damit sie an anderer Stelle gelesen werden kann); Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #loop   lf=42   lt=1337   er=test_line&lt;br /&gt;
&lt;br /&gt;
==#exit==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #exit bricht die Ausführung auf der jeweiligen Code-Ebene (Kommando bzw. Sub-Kommando) ab&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 ~ $EMPTY($PVAL(vl,id))   and   $PVAL(vl,status) &amp;gt; 20&lt;br /&gt;
 #sql select nextval('ausza_id') as id&lt;br /&gt;
 #sql_openval   f_id=1&lt;br /&gt;
 #page_val   i=vl   f=id   z=$VAL(1)&lt;br /&gt;
 #save&lt;br /&gt;
 #exit&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Der Beispiel-Code befindet sich auf der Seite xausza_page_ausza und baut die entsprechende Seite auf. Er prüft, ob bereits eine ID-Gesetzt ist - wenn nicht, wird über eine Datenbank-Sequenz die nächste ID abgefragt, in das VL-Segment geschrieben und die Seite gespeichert. Beim Speichern der Seite wird sie jedoch neu aufgerufen, also komplett neu aufgebaut, was erst einmal kein Problem ist. Danach würde aber die Ausführung auf der Code-Ebene, auf der sich #save befindet, fortgeführt, was zur Folge hat, dass die dann folgenden Segmente doppelt erscheinen (zunächst die aus dem Neu-Aufbau der Seite, dann die, die von der Fortsetzung des Codes her stammen).&lt;br /&gt;
&lt;br /&gt;
Um dies zu vermeiden muss die Ausführung des Codes nach #save abgebrochen werden.&lt;br /&gt;
&lt;br /&gt;
==$EXEC==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando. Im ausgeführten Kommando kann eine Variable gesetzt werden, die dann als Funktionsergebnis von $EXEC zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll&lt;br /&gt;
# optional: Der Name der Variablen, in der das Ergebnis steht; default ist ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;test_funkexec&amp;quot;   y=console&lt;br /&gt;
 #cout   c=$EXEC(test_funkexec_line)&lt;br /&gt;
&lt;br /&gt;
 -- test_funkexec_line&lt;br /&gt;
 #var_set   n=result   z=42&lt;br /&gt;
&lt;br /&gt;
=Dateien und Verzeichnisse=&lt;br /&gt;
&lt;br /&gt;
==#file_op==&lt;br /&gt;
&lt;br /&gt;
Führt eine Operation mit einer Datei oder einem Verzeichnis aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder des Verzeichnisses&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in die/den das Ergebnis der Operation (Y oder N) geschrieben wird.&lt;br /&gt;
* on (&amp;quot;old name) - der bisherige Dateiname bei RenameFile&lt;br /&gt;
* y - Typ der Operation&lt;br /&gt;
** cd / createdir - Erzeugt ein Verzeichnis&lt;br /&gt;
** cf / copyfile - Kopiert eine Datei (von on zu fn)&lt;br /&gt;
** df / deletefile - Löscht eine Datei&lt;br /&gt;
** fd / forcedirectories - Stellt sicher, dass ein Pfad vorhanden ist&lt;br /&gt;
** rd / removedir - Entfernt ein Verzeichnis&lt;br /&gt;
** rf / renamefile - Benennt eine Datei um, kann auch dazu verwendet werden, eine Datei zu verschieben&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #file_op   y=renamefile   on=c:\temp\debug.txt   fn=c:\temp\test\debug.txt   n=1&lt;br /&gt;
 #cout   c=$VAL(1)&lt;br /&gt;
 &lt;br /&gt;
 #file_op   y=fd   fn=c:\eins\zwei\drei\vier&lt;br /&gt;
&lt;br /&gt;
==#file_search==&lt;br /&gt;
&lt;br /&gt;
Sucht Dateien und schreibt die Ergebnisliste in einen Text.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* clr - (&amp;quot;clear&amp;quot;) wenn Y, wird der Text vor der Suche geleert. Default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, in den die Ergebnisliste geschrieben wird; default 1, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_search   fn=c:\*.ini   n=1   y=0   all_=Y&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==#file_wait==&lt;br /&gt;
&lt;br /&gt;
Wartet, bis zumindest eine Datei vorhanden ist, die den Kriterien entspricht, und führt dann cmd aus. Wird nach der in to eingestellten Zeit keine Datei gefunden, dann wird mit dem in cmdto eingestellten Kommando abgebrochen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* cmd - Kommando, das ausgeführt wird, sobald eine Datei gefunden wird; Funktionen werden ersetzt&lt;br /&gt;
* cmdto - Kommando, das ausgeführt wird, sobald die Prozedur wegen eines TimeOuts abgebrochen wird; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* sleep - Zeit in ms zwischen den einzelnen Suchen nach einer Datei, die den Kriterien entspricht; Default 1000, Funktionen werden ersetzt&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in ms, nach der die Ausführung abgebrochen wird; Default 15000, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #cout c=&amp;quot;Gefunden&amp;quot;&lt;br /&gt;
 #cmd_clear2 #cout c=&amp;quot;TimeOut&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #file_wait   fn=C:\temp\test\*.txt   cmd=1   cmdto=2&lt;br /&gt;
&lt;br /&gt;
==#dir_force==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass es den spezifizierten Verzeichnispfad gibt, indem erforderlichenfalls Verzeichnisse angelegt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Names des Pfads&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_force   n=c:\temp\pdf&lt;br /&gt;
&lt;br /&gt;
==#dir_proc==&lt;br /&gt;
&lt;br /&gt;
Durchsucht ein Verzeichnis nach Dateien, die den angegebenen Kriterien entsprechen, und führt für jede gefundene Datei ''cmd'' aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das für jede gefundene Datei ausgeführt wird&lt;br /&gt;
* dn (&amp;quot;DirectoryName&amp;quot;) - Pfad des Verzeichnisses, in dem die Dateien gesucht werden; Funktionen werden ersetzt.&lt;br /&gt;
* done - Verzeichnis, in das die Dateien nach Abarbeitung verschoben werden (sofern der Parameter nicht leer ist). Funktionen werden ersetzt.&lt;br /&gt;
* fn (&amp;quot;filename&amp;quot;) - Suchkriterium für den Dateinamen; Funktionen werden ersetzt; Default *&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in welcher der Dateiname der aktuell zu bearbeitenden Datei inklusive Pfad gespeichert wird; Funktionen werden ersetzt; Default dir_proc&lt;br /&gt;
* ndone(&amp;quot;name done&amp;quot;) - Name der Variablen, die bestimmt, ob eine Datei in das Done-Verzeichnis verschoben wird. Vor jedem Aufruf von cmd wird diese Variable auf 'Y' gesetzt. Sie kann während der Bearbeitung auf N gesetzt werden - damit wird verhindert, dass die Datei in das Done-Verzeichnis verschoben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_proc   dn=c:\temp\in   done=c:\temp\done   fn=*.csv   cmd=importcsv_line&lt;br /&gt;
&lt;br /&gt;
==$FILEINFO()==&lt;br /&gt;
&lt;br /&gt;
Liefert Infos über eine Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Dateiname&lt;br /&gt;
# Typ der Information, es stehen dabei folgende Optionen zur Verfügung&lt;br /&gt;
#* size - Dateigröße in Byte&lt;br /&gt;
#* size_point - Dateigröße in Byte, Punkte alle drei Zeichen von rechts&lt;br /&gt;
#* size_auto - Dateigröße in Byte, kB, MB oder GB, je nach Größe; mit Einheit&lt;br /&gt;
#* size_kb - Dateigröße in kB (analog Windows-Explorer)&lt;br /&gt;
#* date - Datum im Format dd.mm.yyyy&lt;br /&gt;
#* date_yyyy - Datum im Format yyyymmdd&lt;br /&gt;
#* datetime - Datum und Uhrzeit im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
#* datetime_yyyy - Datum im Format yyyymmddhhmmss&lt;br /&gt;
#* exists - Y, wenn die Datei existiert, sonst N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=fn   z=&amp;quot;T:\Tools Gruppenrechte\BC3 light\BafClientFM.exe&amp;quot;&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_point)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_auto)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_kb)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),exists)&lt;br /&gt;
&lt;br /&gt;
Ergebnis&lt;br /&gt;
&lt;br /&gt;
 27668480&lt;br /&gt;
 27.668.480&lt;br /&gt;
 26,39 MB&lt;br /&gt;
 27.020 kB&lt;br /&gt;
 02.05.2023&lt;br /&gt;
 20230502&lt;br /&gt;
 02.05.2023 12:20:09&lt;br /&gt;
 20230502122009&lt;br /&gt;
 Y&lt;br /&gt;
&lt;br /&gt;
==$DIR()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Verzeichnisnamen. Trailing Path Delimiter (\ bei Windows) wird immer angehängt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bezeichnung des Verzeichnisses&lt;br /&gt;
## appdata - Verzeichnis für Anwendungsdaten des Users&lt;br /&gt;
## cappdata - gemeinsames Verzeichnis für Anwendungsdaten aller User&lt;br /&gt;
## cdoc - gemeinsames Dokumentenverzeichnis  aller User&lt;br /&gt;
## cfav / cfavorites - gemeinsames Favoritenverzeichnis aller User&lt;br /&gt;
## cmusic - gemeinsames Musikverzeichnis aller User&lt;br /&gt;
## cpic / cpictures - gemeinsames Bilderverzeichnis aller User&lt;br /&gt;
## cvideo - gemeinsames Videoverzeichnis aller User&lt;br /&gt;
## desktop - Desktopverzeichnis des Rechners&lt;br /&gt;
## '''doc''' / docdir - Dokumentenverzeichnis des Users&lt;br /&gt;
## downloads - Downloadsverzeichnis des Users&lt;br /&gt;
## fav / favorites - Favoritenverzeichnis des Users&lt;br /&gt;
## fonts - Fontsverzeichnis des Rechners&lt;br /&gt;
## music - Musikverzeichnis des Users&lt;br /&gt;
## pic / pictures - Bilderverzeichnis des Users&lt;br /&gt;
## prog / program - Programmverzeichnis des Rechners&lt;br /&gt;
## prog86 / program86 - Programm86-Verzeichnis des Rechners&lt;br /&gt;
## '''root''' - Root-Verzeichnis des BAF-Clients bzw. des BAF-Servers&lt;br /&gt;
## '''userroot''' / usrroot - User-Verzeichnis des BAF-Clients&lt;br /&gt;
## video - Videoverzeichnis des Users&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=$DIR(doc)test.txt&lt;br /&gt;
&lt;br /&gt;
==$FILEDIALOG()==&lt;br /&gt;
&lt;br /&gt;
Führt einen Dateiauswahl-Dialog aus und gibt den gewählten Dateinamen zurück. Im Falle des Abbruchs wird ''abort'' zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wenn der erste Parameter ''save'' lautet, wird ein Speichern-Dialog, sonst ein Öffnen-Dialog aufgerufen.&lt;br /&gt;
# Filter-Statement, immer Kombinationen aus Text (Text-Dateien *.txt) und Filter-Statement(*.txt), getrennt durch Pipes.&lt;br /&gt;
# Standard-Dateierweiterung&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=&amp;quot;$FILEDIALOG(save,Text-Dateien *.txt|*.txt|Alle Dateien *.*|*.*,txt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Bitte beachten: Wegen der Leerzeichen im Filter-Statement muss der ganze Parameter in doppelte Anführungszeichen gesetzt werden.)&lt;br /&gt;
&lt;br /&gt;
=ZIP=&lt;br /&gt;
&lt;br /&gt;
==#zip_create==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine ZIP-Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Dateien, die der ZIP-Datei hinzugefügt werden; Funktionen werden ersetzt&lt;br /&gt;
* dir (&amp;quot;directory&amp;quot;) - Verzeichnis, wenn das nicht bei allen fn1, fn2... angegeben werden soll&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Der Dateiname, unter dem die ZIP-Datei gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* fn1, fn2,... (&amp;quot;FileName&amp;quot;) - Die Dateien, die in der ZIP-Datei gespeichert werden; die Anzahl wird mit dem Parameter cnt bestimmt; Funktionen werden ersetzt&lt;br /&gt;
* list - Nummer eines Textes (#text, #text2...), in dem die Dateien gelistet sind, die der ZIP-Datei hinzugefügt werden sollen. Wenn list ein Wert größer 0 hat, werden cnt und fn1, fn2... ignoriert. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* pw (&amp;quot;PassWord&amp;quot;) - Password der erzeugten ZIP-Datei; Funktionen werden ersetzt.&lt;br /&gt;
* pwc (&amp;quot;PassWordCrypted&amp;quot;) - Wenn Y, dann ist das Passwort mit der Verschlüsselungsfunktion auf der Seite Tools des Code-Dialogs verschlüsselt. Hinweis: Mit dieser Verschlüsselung verhindert man lediglich, dass das Passwort direkt aus dem Code ausgelesen werden kann. Wird der BAF-Client mit dem Delphi-Debugger ausgeführt, lässt sich leicht an die betreffende Stelle ein Breakpoint setzen und das Passwort dann im Klartext auslesen (dieselbe Unit uBafCrypt vorausgesetzt).&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #zip_create   fn=$VAR(root).zip   list=1&lt;br /&gt;
 &lt;br /&gt;
 #var_set   n=fn_zip   z=tt_mail_$VAR(reise)-$VAR(reisename)_$PAD($VAR(lfdnr),4,L,0)_$NOWFMT(yyyymmdd).zip&lt;br /&gt;
 #file_op   y=df   fn=$VAR(path)\$VAR(fn_zip)&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=$VAR(filename).txt&lt;br /&gt;
 #code fn2=$VAR(filename).sab&lt;br /&gt;
 #zip_create   dir=$VAR(path)   fn=$VAR(path)\$VAR(fn_zip)    pw=$VAR(pw)   $CODE$&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #zip_create ersetzt nicht vorherige Dateien. Von daher im Zweifelsfall wie im zweiten Beispiel vorher eine Datei dieses Namens löschen.&lt;br /&gt;
&lt;br /&gt;
=Ini-Dateien=&lt;br /&gt;
&lt;br /&gt;
Der BAF-Client verwendet eine Ini-Datei im Root-Verzeichnis (vor allem für die Datenbankverbindungen) und eine Ini-Datei ''BafClientFM.ini'' im User-Anwendungsverzeichnis (vor allem für die Formularpositionen). Es können aber auch weitere Ini-Dateien verwendet werden.&lt;br /&gt;
&lt;br /&gt;
==#ini_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Ini-Datei. #ini_val ist eine nummerierte Prozedur: #ini_val schreibt in die erste Ini-Datei, #ini_val2 in die zweite Ini-Datei und so weiter. Diese Ini-Dateien werden zunächst nur im Speicher gehalten und müssen explizit aus einer Datei geladen oder in eine Datei gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;item&amp;quot; / &amp;quot;ident&amp;quot;) - Name des Eintrags in der Ini-Datei; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Wenn der Parameter n den Wert ''usr'' oder ''user'' hat, dann bleibt die Nummer der Ini-Datei unberücksichtigt und der Wert wird in die Datei ''BafClientFM.ini'' im im User-Anwendungsverzeichnis geschrieben.&lt;br /&gt;
* sec (&amp;quot;section&amp;quot;) - Abschnitt in der Ini-Datei; Funktionen werden ersetzt; default ''values''&lt;br /&gt;
* z - Wert, der in die Ini-Datei geschrieben wird; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_val  i=date_last   z=$NOW()&lt;br /&gt;
&lt;br /&gt;
==#ini_load==&lt;br /&gt;
&lt;br /&gt;
Lädt eine Ini-Datei aus einer Datei. Es handelt sich um eine nummerierte Prozedur: #ini_load lädt die Ini-Datei 1, #ini_load2 lädt die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, die geladen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_load   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==#ini_save==&lt;br /&gt;
&lt;br /&gt;
Speichert eine Ini-Datei ineine Datei. Es handelt sich um eine nummerierte Prozedur: #ini_save speichert die Ini-Datei 1, #ini_save2 speichert die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, in die gespeichert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_save   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==$INI()==&lt;br /&gt;
&lt;br /&gt;
Liest einen Wert aus einer Ini-Datei.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
# Item (Ident)&lt;br /&gt;
# optional: Sektion; wenn nicht vorhanden, dann ''values''. Wenn ''db!'', dann wird als Sektion die aktuell gewählte Datenbankverbindung verwendet (in diesem Fall sollte als erster Parameter ''root'' verwendet werden).&lt;br /&gt;
# optional: Default-Wert; wenn nicht vorhanden, dann ein leerer String&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum)&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum,bearbeitung,$TODAY())&lt;br /&gt;
&lt;br /&gt;
==$INITEXT()==&lt;br /&gt;
&lt;br /&gt;
Gibt die komplette Ini-Datei zurück. Wird vor allem beim Debugging verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $INITEXT(usr)&lt;br /&gt;
&lt;br /&gt;
=Zwischenablage=&lt;br /&gt;
&lt;br /&gt;
Das BAF-Framework unterstützt die Zwischenablage nur für Text.&lt;br /&gt;
&lt;br /&gt;
==#clipboard==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Text in die Zwischenablage&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* z - Wert, der in der Zwischenablage gespeichert werden soll; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #clipboard   z=$TEXT()&lt;br /&gt;
 #clipboard   z=$CHR(dquote)$PVAL(test,zahl,allsel,$CHR(crlf))$CHR(dquote)&lt;br /&gt;
&lt;br /&gt;
==$CLIPBOARD()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Text aus der Zwischenablage zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setvar   n=clp   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
=String-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben einen String zurück.&lt;br /&gt;
&lt;br /&gt;
==$BASE64()==&lt;br /&gt;
&lt;br /&gt;
En- oder Decodiert einen Text im Base64-Code&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Encoding oder Decoding:&lt;br /&gt;
## e - Encoding&lt;br /&gt;
## d - Decoding&lt;br /&gt;
# Text, der en-oder decodet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $BASE64(e,Dies ist ein Test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$CHR()==&lt;br /&gt;
&lt;br /&gt;
Gibt ein Zeichen (ggf zwei Zeichen) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Ansi-Zeichennummer oder eine der folgenden Bezeichnungen:&lt;br /&gt;
## crlf - Zeilenumbruch #13#10&lt;br /&gt;
## cr - Zeichen #13&lt;br /&gt;
## lf - Zeichen #10&lt;br /&gt;
## tab - Tabulator&lt;br /&gt;
## quote - ' (einfache Anführungszeichen)&lt;br /&gt;
## dquote - &amp;quot; (doppelte Anführungszeichen)&lt;br /&gt;
## space / leer - Leerzeichen&lt;br /&gt;
## comma / komma - , (Komma)&lt;br /&gt;
## questionmark / qmark / frage / fragezeichen - ?&lt;br /&gt;
## bro / bracket_open - (&lt;br /&gt;
## brc / bracket_close - )&lt;br /&gt;
## dollar - $&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CONVERT()==&lt;br /&gt;
&lt;br /&gt;
Konvertiert einen String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Konvertierungsfunktion&lt;br /&gt;
## isodate&lt;br /&gt;
## isodatetime&lt;br /&gt;
## truefalse&lt;br /&gt;
## pointfloat&lt;br /&gt;
## urlcode&lt;br /&gt;
## utf8&lt;br /&gt;
# String, der konvertiert werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $CONVERT(isodate,2025-03-12)&lt;br /&gt;
 #coutl $CONVERT(isodatetime,2025-03-12 12:03:17)&lt;br /&gt;
 #coutl $CONVERT(truefalse,true)&lt;br /&gt;
 #coutl $CONVERT(pointfloat,12.3)&lt;br /&gt;
 #coutl $CONVERT(urlcode,Für schönen Ärger)&lt;br /&gt;
 #coutl $CONVERT(utf8,Für schönen Ärger)&lt;br /&gt;
&lt;br /&gt;
(Ergebnis)&lt;br /&gt;
 12.03.2025&lt;br /&gt;
 12.03.2025 12:03:17&lt;br /&gt;
 Y&lt;br /&gt;
 12,3&lt;br /&gt;
 F%C3%BCr%20sch%C3%B6nen%20%C3%84rger&lt;br /&gt;
 Für schönen Ärger&lt;br /&gt;
&lt;br /&gt;
==$COPY()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$COPY($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$EXEC()==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando aus und gibt ein Funktionsergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll.&lt;br /&gt;
# optional: Name der Variable, die als Funktionsergebnis zurück gegeben werden soll; default ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=test   z=$EXEC(testkommando)&lt;br /&gt;
&lt;br /&gt;
==$GUID()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine GUID und gibt sie zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# optional: Name einer Variablen, in welcher die GUID zusätzlich gespeichert wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kid=$GUID()&lt;br /&gt;
&lt;br /&gt;
==$HASH()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt einen Hash-Wert vom String im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, von welchem der Hash gebildet werden soll.&lt;br /&gt;
# zu verwendender Hash-Algorithmus:&lt;br /&gt;
## sha512&lt;br /&gt;
## sha512_256&lt;br /&gt;
## sha512_224&lt;br /&gt;
## sha384&lt;br /&gt;
## sha256&lt;br /&gt;
## sha224&lt;br /&gt;
## sha1&lt;br /&gt;
## md5 (Hinweis: MD5 gilt seit Längerem als nicht mehr sicher. Verwenden Sie ihn nur, wenn dies aus Gründen der Abwärts-Kompatbilität zwingend ist.)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$HASH($PVAL(vl,1,2),sha512)&lt;br /&gt;
&lt;br /&gt;
==$INCLUDE()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass der als dritter Parameter übergebene Text am Anfang oder am Ende steht, gegebenenfalls wird er dort eingefügt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## lead(oder leading) - Text muss am Anfang stehen&lt;br /&gt;
## leadci(oder leadingci oder leadingcaseinsensitive) - Text muss am Anfang stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
## trail(oder trailing) - Text muss am Ende stehen&lt;br /&gt;
## trailci(oder trailci oder trailingcaseinsensitive) - Text muss am Ende stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
# Text, in den gegebenenfalls eingefügt wird&lt;br /&gt;
# Text, der gegebenenfalls eingefügt wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCLUDE(trailci,test.PDF,.pdf)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$INVLOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Key aus einer Nachschlageliste bei Übergabe des Values.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Value des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$INVLOOKUP(general_status,aktiv,Wert nicht vorhanden)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus einer Nachschlageliste.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Key des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$LOOKUP(general_status,1,Status nicht gesetzt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOW()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Kleinbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Kleinbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LOW($EDT(edt1)) = bus&lt;br /&gt;
&lt;br /&gt;
==$LOWNOSPACE()==&lt;br /&gt;
&lt;br /&gt;
Wandelt einen String in Kleinbuchstaben und ersetzt alle Leerzeichen durch Unterstriche.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der gewandelt werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$LOWNOSPACE($PVAL(vl,1,2))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$NOCRLF()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Zeilenumbrüche&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem die Zeilenumbrüche entfernt werden sollen&lt;br /&gt;
# optional: Zeichenfolge, die an Stelle der Zeilenumbrüche eingefügt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=2   z=$NOCRLF($VAL(1),;)&lt;br /&gt;
&lt;br /&gt;
==$NVL()==&lt;br /&gt;
&lt;br /&gt;
Liefert einen Ersatzwert, wenn der Wert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird, wenn der erste Parameter leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   where ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0)&lt;br /&gt;
&lt;br /&gt;
Liefert $PVAL einen leeren Wert zurück (z.B., weil die Gridzeile neu angelegt wurde und daher noch keine Nummer eingetragen ist), so wird statt dessen 0 verwendet, damit die WHERE-Klausel syntaktisch korrekt ist.&lt;br /&gt;
&lt;br /&gt;
==$ONLYCHAR()==&lt;br /&gt;
&lt;br /&gt;
Entfernt unerwünschte Zeichen aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# optional: Typ der Funktion&lt;br /&gt;
## (leer) - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z', 'ä', 'ö', 'ü', 'Ä','Ö', 'Ü', 'ß']) sind&lt;br /&gt;
## charnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind&lt;br /&gt;
## low - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## upp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## charnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## charnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## uml - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z') sind, Umlaute werden konvertiert (ä -&amp;gt; ae, ö -&amp;gt; oe, ü -&amp;gt; ue, Ä -&amp;gt; Ae, Ö -&amp;gt; Oe, Ü -&amp;gt; Ue, ß -&amp;gt; ss)&lt;br /&gt;
## umlcharnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Umlaute werden konvertiert&lt;br /&gt;
## umllow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## no191 / not191 - Es werden alle Zeichen mit der ANSI-Nummer 191 (¿) entfernt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg)&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg,umllow)&lt;br /&gt;
&lt;br /&gt;
==$PAD()==&lt;br /&gt;
&lt;br /&gt;
Füllt links oder rechts bis zur vorgegebenen Länge mit Zeichen auf.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# Soll-Länge. Ist der ursprüngliche String bereits länger, wird er nicht gekürzt, es werden aber auch keine weiteren Zeichen hinzugefügt&lt;br /&gt;
# Wenn L, werden die Zeichen vorne hinzugefügt, andernfalls hinten&lt;br /&gt;
# Zeichen, die soweit und so oft hinzugefügt werden, bis die Soll-Länge erreicht ist. Umfasst der Parameter mehrere Zeichen, werden diese ggf. nicht alle hinzugefügt.&lt;br /&gt;
# optional: Länge, auf die der ursprüngliche String vor der weiteren Verarbeitung gekürzt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   text1 = '$PAD($VAR(text1),70,R, )'&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ des Ergebnisses&lt;br /&gt;
## curr - Zahl mit zwei Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## curr4 - Zahl mit vier Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## date - Datum in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## int - ganze Zahl  in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## ld - Key einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ldv - Value einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ls - Key eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## lsv - Value eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## text, text2, text3... - Zeile eines Textes&lt;br /&gt;
# untere Grenze bzw. Name der Nachschlageliste oder des Specials&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $RANDOM(date,01.01.2022,31.12.2022)&lt;br /&gt;
 #coutl $RANDOM(text2)&lt;br /&gt;
&lt;br /&gt;
==$SUBSTR()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Selbe Funktionalität wie $COPY())&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$SUBSTR($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$STREP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string replace&amp;quot;) Ersetzt Zeichen im String durch andere Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, in welchen Zeichen ersetzt werden sollen.&lt;br /&gt;
# Zeichen, die ersetzt werden sollen&lt;br /&gt;
# Zeichen, die an deren Stelle treten sollen&lt;br /&gt;
# optional: Optionen (kombinierbar)&lt;br /&gt;
## i - Groß- und Kleinschreibung ignorieren &lt;br /&gt;
## a - Alle Vorkommen ersetzen (andernfalls wird nur das erste Vorkommen ersetzt)&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=&amp;quot;$STREP($PVAL(vl,1,2), ,_,a)&amp;quot;&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$STREP($PVAL(vl,1,2),$CHR(space),_,a)&lt;br /&gt;
&lt;br /&gt;
Hinweis: Beide Beispiele haben exakt dieselbe Funktion. Im oberen Beispiel steht das Leerzeichen direkt im Text, dafür muss der komplette Parameter in doppelte Anführungszeichen, im unteren Beispiel wird das Leerzeichen durch $CHR(space) eingefügt, dafür können die Leerzeichen unterbleiben.&lt;br /&gt;
&lt;br /&gt;
==$STROP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string operation&amp;quot;) Sammelsurium von String-Operationen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## trim - entfernt führende und folgende Leerzeichen&lt;br /&gt;
## trimleft - entfernt führende Leerzeichen&lt;br /&gt;
## trimright - entferne folgende Leerzeichen&lt;br /&gt;
## quote - setzt den String in einfache Anführungszeichen&lt;br /&gt;
## unquote - entfernt einschließende einfache Anführungszeichen&lt;br /&gt;
## dquote - setzt den String in doppelte Anführungszeichen&lt;br /&gt;
## unqduote - entfernt einschließende doppelte Anführungszeichen&lt;br /&gt;
## ex_filepath - entspricht der Delphi-Funktion ExtractFilePath&lt;br /&gt;
## ex_filedir - entspricht der Delphi-Funktion ExtractFileDir&lt;br /&gt;
## ex_filedrive - entspricht der Delphi-Funktion ExtractFileDrive&lt;br /&gt;
## ex_filename - entspricht der Delphi-Funktion ExtractFileName&lt;br /&gt;
## ex_fileext - entspricht der Delphi-Funktion ExtractFileExt&lt;br /&gt;
# String, der bearbeitet werden soll&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$STROP(quote,Test)&lt;br /&gt;
&lt;br /&gt;
==$STREXTR()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string extract&amp;quot;) Extrahiert einen Teil aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem extrahiert werden soll&lt;br /&gt;
# Extraktionstyp&lt;br /&gt;
## ffe (&amp;quot;from first exclude&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## ffi (&amp;quot;from first include&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tfe (&amp;quot;to first exclude&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tfi (&amp;quot;to first include&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## fle (&amp;quot;from last exclude&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## fli (&amp;quot;from last include&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tle (&amp;quot;to last  exclude&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tli (&amp;quot;to last include&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Trennzeichen&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffe,;)&amp;quot;    -- Ergebnis: test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffi,;)&amp;quot;    -- Ergebnis: ;test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfe,;)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfi,;)&amp;quot;    -- Ergebnis: test;&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;!§§test2,tfe,;!§§)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
&lt;br /&gt;
==$TRIM()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Leerzeichen und Zeilenumbrüche am Rand des Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der getrimmt werden soll&lt;br /&gt;
# optional&lt;br /&gt;
## L - trimmt nur auf der linken Seite&lt;br /&gt;
## R - trimmt nur auf der rechten Seite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$TRIM($VAL(1),R)&lt;br /&gt;
&lt;br /&gt;
==$UPP()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Großbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Großbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $UPP($EDT(edt1)) = BUS&lt;br /&gt;
&lt;br /&gt;
==$VT()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VT (&amp;quot;Value Translate&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Vergleichswert 1&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 1 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 2&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 2 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 3&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 3 dem ersten Parameter entspricht &lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VT(Frau,1,Herr,2,Frau,3)&lt;br /&gt;
 -- Frau -&amp;gt; 3&lt;br /&gt;
 -- Herr -&amp;gt; 2&lt;br /&gt;
 -- Test -&amp;gt; 1&lt;br /&gt;
 -- Firma -&amp;gt; 1&lt;br /&gt;
&lt;br /&gt;
==$VTVL()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VTVL (&amp;quot;Value Translate ValueList&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu $VT werden die zu prüfenden Werte und deren Entsprechungen nicht über Parameter übergeben, sondern aus einer Werte-Liste geholt, die in einem Text gespeichert sein muss.&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich wie folgt aufbauen&lt;br /&gt;
&lt;br /&gt;
 key1=value1&lt;br /&gt;
 key2=value2&lt;br /&gt;
 key3=value3&lt;br /&gt;
 key4=value4&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich auch mit #sql_opentvl erzeugen, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Nummer des Textes, in dem sich die Werteliste befindet.&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select userid as ckey, shortname as cvalue from user_user&lt;br /&gt;
 #sql_opentvl n=1&lt;br /&gt;
 #coutl $VTVL(591,(nicht gefunden),1)&lt;br /&gt;
&lt;br /&gt;
==$XR()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $XR (&amp;quot;XmlReplace&amp;quot;) ersetzt in XML nicht zulässige Zeichen:&lt;br /&gt;
* aus &amp;amp; wird $amp ;&lt;br /&gt;
* aus &amp;lt; wird &amp;amp;lt ;&lt;br /&gt;
* aus &amp;gt; wird &amp;amp;gt ;&lt;br /&gt;
* aus &amp;quot; wird &amp;amp;quot ;&lt;br /&gt;
* aus ' wird &amp;amp;apos ;&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Das Leerzeichen vor dem Semikolon soll verhindern, dass die Zeichen hier in der Darstellung ersetzt werden und wird nicht eingefügt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text &amp;lt;firmenname&amp;gt;$XR($DATA(dat,firmenname))&amp;lt;/firmenname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==$XRR()==&lt;br /&gt;
&lt;br /&gt;
Umkehrfunktion von $XR()&lt;br /&gt;
* aus $amp ; wird &amp;amp;&lt;br /&gt;
* aus &amp;amp;lt ; wird &amp;lt;&lt;br /&gt;
* aus &amp;amp;gt ; wird &amp;gt;&lt;br /&gt;
* aus &amp;amp;quot ; wird &amp;quot;&lt;br /&gt;
* aus &amp;amp;apos ; wird '&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
=Integer-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben eine ganze Zahl zurück&lt;br /&gt;
&lt;br /&gt;
==$DEC()==&lt;br /&gt;
&lt;br /&gt;
Verringert die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die verringert werden soll.&lt;br /&gt;
# optional: Zahl, um die verringert werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$DEC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ICALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit ganzzahligen Werten durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator, es stehen zur Verfügung&lt;br /&gt;
## +&lt;br /&gt;
## -&lt;br /&gt;
## *&lt;br /&gt;
## div&lt;br /&gt;
## mod&lt;br /&gt;
# Erste Zahl&lt;br /&gt;
# Zweite Zahl&lt;br /&gt;
# optional beim Operator +: weitere Summanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$ICALC(mod,17,5)&lt;br /&gt;
&lt;br /&gt;
==$INC()==&lt;br /&gt;
&lt;br /&gt;
Erhöht die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die erhöht werden soll.&lt;br /&gt;
# optional: Zahl, um die erhöht werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$INC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$INTLEN()==&lt;br /&gt;
&lt;br /&gt;
Ist der String im Parameter eine ganz Zahl, dann wird deren Länge in Zeichen zurückgegeben, andernfalls -1; ein leerer String im ersten Parameter ergibt 0.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, deren Länge ermittelt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTLEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Länge eines Strings in Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Länge ermittelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEVENSHTEIN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Levenshtein-Distanz (https://de.wikipedia.org/wiki/Levenshtein-Distanz) der beiden übergebenen Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# erster String&lt;br /&gt;
# zweiter String&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $LEVENSHTEIN(alpha,beta)&lt;br /&gt;
&lt;br /&gt;
==$POS()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Position des Substrings in einem String. Das Funktionsergebnis ist die Position, das erste Zeichen ist 1. 0 wird zurück gegeben, wenn der Substring im String nicht vorkommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Substring (nach dem gesucht wird)&lt;br /&gt;
# String (in dem gesucht wird)&lt;br /&gt;
# optional: Wenn ic (ignore case), dann wird bei der Suche die Groß- und Kleinschreibung nicht beachtet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $POS($EDT(edt1),$VAR(1),ic) &amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert zwischen der oberen und unteren Grenze&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ&lt;br /&gt;
## int - zufällige Ganzzahl &lt;br /&gt;
## date - zufälliges Datum &lt;br /&gt;
## curr - zufällige Zahl mit zwei Nachkommastellen&lt;br /&gt;
## curr4 - zufällige Zahl mit vier Nachkommastellen&lt;br /&gt;
## text1, text2, text3... - zufällige Zeile aus dem jeweiligen Text; text ist text1; untere und obere Grenze bleiben unberücksichtigt&lt;br /&gt;
## ld - zufälliger Schlüssel-Wert aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ldv - zufälliger Text aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ls - zufälliger Schlüssel-Wert aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## lsv - zufälliger Text aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
# untere Grenze&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $RANDOM(int,1,6)&lt;br /&gt;
&lt;br /&gt;
=Datumsfunktionen=&lt;br /&gt;
&lt;br /&gt;
==$INCDATE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktione  $INCDATE() verändert das Datum im ersten Parameter um die Anzahl Tage im zweiten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das verändert werden soll&lt;br /&gt;
# optional: Die Tage, um die verändert werden soll; wenn leer, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCDATE($NOW(),-3)   clr=Y&lt;br /&gt;
&lt;br /&gt;
==$INT2TIME()==&lt;br /&gt;
&lt;br /&gt;
Macht aus z.B. 1130 die Zeit 11:30&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zeit im Integer-Format&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_time=$INT2TIME($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$NOW()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit im Format dd.mm.yyyy hh:mm:ss zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #execsql   k_datechg=$NOW()&lt;br /&gt;
&lt;br /&gt;
==$NOWFMT()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und/oder die aktuelle Uhrzeit im angegebenen Format zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Formatierungsstring (Syntax wie FormatDateTime in Delphi)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$NOWFMT(yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$NOWMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit ohne Sekunden (also dd.mm.yyyy hh:mm) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$NOWMIN()&lt;br /&gt;
&lt;br /&gt;
==$TODAY()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum im Format dd.mm.yyyy zurück.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Wenn das Datum in einem anderen Format benötigt wird, ist $NOWFMT() das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$TODAY()&lt;br /&gt;
&lt;br /&gt;
==$DFMT()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;date formated&amp;quot;) Formatiert das übergebene Datum. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, ggf. mit Uhrzeit, das formatiert werden soll.&lt;br /&gt;
# Formatierungsstring wie in Delphi&lt;br /&gt;
# optional: Wenn hn (&amp;quot;hide null&amp;quot;), dann wird ein leerer String zurück gegeben, wenn das Datum kleiner/gleich 1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$DFMT($NOW(),yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Bool'sche Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
==$BFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert einen bool'schen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'scher Wert&lt;br /&gt;
# optional: Ergebnis, wenn Wert Y ('y', 'J', 'j', '1') ist, default Y&lt;br /&gt;
# optional: Ergebnis, wenn Wert N (also nicht 'Y', 'y', 'J', 'j', '1') ist, default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cout   c=$BFMT($VAR(test),x,)&lt;br /&gt;
&lt;br /&gt;
==$BOOL()==&lt;br /&gt;
&lt;br /&gt;
Wertet das bool'sche Statement im Parameter aus.&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
* = gleich&lt;br /&gt;
* == gleich ohne Berücksichtigung der Groß- und Kleinschreibung&lt;br /&gt;
* &amp;lt;&amp;gt; ungleich&lt;br /&gt;
* != ungleich&lt;br /&gt;
* &amp;gt; größer&lt;br /&gt;
* &amp;gt;= größer gleich&lt;br /&gt;
* &amp;lt; kleiner&lt;br /&gt;
* &amp;lt;= kleiner gleich &lt;br /&gt;
* and Und-Verknüpfung&lt;br /&gt;
* or ODER-Verknüpfung&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Statements werden von links nach rechts ausgewertet, and und or sind gleichwetig, gegebenenfalls müssen Klammern eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'sches Statement, das ausgewertet wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL((17 &amp;gt; 22) or (5 &amp;gt; 3))&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL(17 &amp;gt; 22 or 5 &amp;gt; 3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATECOMP()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn Datum 2 Operator Datum 1 zutreffend ist. Ansonsten wird N zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Wird kein Operator angegeben, dann wird die Anzahl der Tage Datum 2 - Datum 1 als Zahl zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum 1&lt;br /&gt;
# Datum 2&lt;br /&gt;
# Operator&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024,&amp;lt;)&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATEMINREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMINREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEMAXREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMAXREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in ein Datum wandeln lassen, werden zu 0 (30.12.1899) konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter diesem Datum entspricht. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;Test $DATEBETWEEN($TODAY(),1.1.2020,2.2.2022)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$EMPTY()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Parameter ein leerer String ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTY($DATE(n,grpname))&lt;br /&gt;
&lt;br /&gt;
==$EMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable ein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTYVAR(buchungsnr)&lt;br /&gt;
&lt;br /&gt;
==$IN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INIC() beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die erste Anweisung gibt Y und die zweite N zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INIC()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $IN() nicht beachtet beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen geben Y zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$ISCURR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen Currency-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISCURR($DATA(n,rechnungssumme))&lt;br /&gt;
&lt;br /&gt;
==$ISDATE()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in ein Datums- oder DatumsZeit-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Prüfoperation, default ist date&lt;br /&gt;
## date - prüft, ob in ein Datum gewandelt werden kann&lt;br /&gt;
## datetime - prüft, ob in ein Datums-Zeit-Wert gewandelt werden kann&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISDATE($DATA(n,beginn))&lt;br /&gt;
&lt;br /&gt;
==$ISINT()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen ganzzahligen Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISINT($DATA(n,tage))&lt;br /&gt;
&lt;br /&gt;
==$INTMAX()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMAX($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$INTMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMIN($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$NEMPTY()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;not empty&amp;quot;) Gibt Y zurück, wenn der Parameter nicht leer ist. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalt geprüft wird. Leerzeichen gelten als leerer String.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 &lt;br /&gt;
 ~ $NEMPTY($EDT(edt1))&lt;br /&gt;
&lt;br /&gt;
==$NEMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable kein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $NEMPTYVAR(kundennr)&lt;br /&gt;
&lt;br /&gt;
==$NOT==&lt;br /&gt;
&lt;br /&gt;
Invertiert einen bool'schen Wert. Aus Y (y, J, j, 1) wird N und aus N wird Y.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der invertiert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $NOT(2)&lt;br /&gt;
&lt;br /&gt;
==$NUMBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in eine Zahl wandeln lassen, werden zu 0 konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter dieser Zahl entspricht. Siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56,)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die beiden Beispiele unterscheiden sich auf den ersten Blick kaum. Bei der ersten Zeile muss jedoch eine Schuhgröße eingegeben werden. Bleibt das Feld im VL-Segment leer, so wird dieser fehlende Wert nach 0 konvertiert und liegt nicht zwischen 28 und 56.&lt;br /&gt;
&lt;br /&gt;
Anders bei der zweiten Zeile: Das Komma vor der schließenden Klammer sorgt für einen vierten Parameter, der ebenfalls leer ist und damit nach 0 gewandelt wird. Auf diese Weise werden die leere Eingaben (und die Eingabe von 0) gültig.&lt;br /&gt;
&lt;br /&gt;
==$REGEX()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $REGEX() (&amp;quot;regular expressions&amp;quot;) prüft, ob der String in Parameter 1 den Anforderungen von Parameter 2 entspricht (Ergebnis Y) oder nicht (Ergebnis N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft werden soll&lt;br /&gt;
# Regulärer Ausdruck, mit dem der String in Parameter 2 geprüft wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $REGEX($VAR(med),^[A-Z]{3}$)&lt;br /&gt;
&lt;br /&gt;
==$TEXT_HASLINE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $TEXT_HASLINE() prüft, ob die als Parameter 2 übergebene Textzeile in einem Text vorkommt. Es wird nur auf komplette Textzeilen geprüft. Wird zum Beispiel verwendet, um eine Liste von Kundennummern zu erstellen, und dann auf einzelne Nummern zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# Textzeile, deren Vorkommen geprüft wird&lt;br /&gt;
# Ergebnis, wenn die Textzeile vorkommt; default Y&lt;br /&gt;
# Ergebnis, wenn die Textzeile nicht vorkommt; default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $TEXT_HASLINE(1,990000018,1,0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$VIBAN()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VIBAN() (&amp;quot;validate IBAN&amp;quot;) prüft eine IBAN anhand der Prüfziffern (3. und 4. Stelle).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# IBAN, die geprüft werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VIBAN(DE12345)&lt;br /&gt;
&lt;br /&gt;
=Currency-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==$CCALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit Festkommawerten durch&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
** + - Addition&lt;br /&gt;
** - - Subtraktion&lt;br /&gt;
** * - Multiplikation&lt;br /&gt;
** / - Division&lt;br /&gt;
** % - Division und Multiplikation des Ergebnisses mit 100&lt;br /&gt;
** +4 - Addition und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** -4 - Subtraktion und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** *4 - Multiplikation und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** /4 - Division und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** %4 - Division, Multiplikation des Ergebnisses mit 100 und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
** B, b, B4, b4 - Bruttobetrag, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** E, e, E4, e4 - Enthaltene MWSt, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** M, m, M4, m4 - MWSt, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** N, n, N4, n4 - Nettobetrag, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator&lt;br /&gt;
# und weitere: Operanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 10&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(+,1,2,3,4)&amp;quot;&lt;br /&gt;
 -- Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #val_set   n=1   z=1038,87&lt;br /&gt;
 #coutl $CCALC(N,$VAL(1),19)  -  $CCALC(E,$VAL(1),19)  -&lt;br /&gt;
&lt;br /&gt;
==$CURR()==&lt;br /&gt;
&lt;br /&gt;
Currency-Werte müssen in Funktionen mit einem Punkt als Dezimaltrennzeichen eingegeben werden, da das Komma die Parameter trennt. Sofern Konstanten verwendet werden, lässt sich das einfach so eingeben, sobald aber die Werte aus anderen Funktionen kommen (zum Beispiel $DATA()), müssen sie dann mit $CURR() in dieses Format umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Vorkommastellen&lt;br /&gt;
# Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 43,48&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,$CURR(2,3))&amp;quot;&lt;br /&gt;
 -- zum Vergleich; Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert Curreny-Werte&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert&lt;br /&gt;
# optional: Formatierungsstring, default 0.00&lt;br /&gt;
# optional: wenn hn (&amp;quot;hide null&amp;quot;), dann werden leere Strings als Wert auch als leerer String ausgegeben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=###,###,###,##0.00&lt;br /&gt;
 #val_set   n=2   z=1337,42&lt;br /&gt;
 #cout   c=$CFMT($VAL(2),$VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ONLYNUM()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass in einem String nur Zahlen (ggf. auch Kommas oder Punkte) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl&lt;br /&gt;
# Art der Operation; default numkomma&lt;br /&gt;
## flnnc (&amp;quot;from last not numeric character&amp;quot;) - Ab dem letzten Zeichen, das keine Ziffer ist&lt;br /&gt;
## num - Nur Ziffern, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numkomma - Nur Ziffern und Kommata, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numpoint - Nur Ziffern und Punkte, alle anderen Zeichen werden entfernt&lt;br /&gt;
## ufnnc (&amp;quot;until first not numeric character&amp;quot;) - vom Anfang bis zum ersten Zeichen, das keine Ziffer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 -- Ergebnis 123456&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,num)&lt;br /&gt;
 -- Ergebnis 123&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,ufnnc)&lt;br /&gt;
 -- Ergebnis 456 &lt;br /&gt;
 #coutl   $ONLYNUM(123-456,flnnc)&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22518</id>
		<title>Modul VAR neu</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22518"/>
		<updated>2025-05-02T11:26:02Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #text_act */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das Modul Var sammelt neben den Variablen auch die grundlegenden Prozeduren und Funktionen.&lt;br /&gt;
&lt;br /&gt;
=Variable=&lt;br /&gt;
&lt;br /&gt;
==#var_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#setvar setzt den Wert einer Variablen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis: Variable sind global, auf sie kann auch in Sub-Kommandos zugegriffen werden. Values sind dagegen lokal.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*rf (replace functions) - Wenn Y, dann werden nach der Zuweisung auf die Variable nochmals die Funktionen ersetzt. Wird zum Beispiel benötigt, wenn Code mit Funktionen mittels $DATA() aus der Datenbank geladen wird; Funktionen werden ersetzt, default N; siehe Beispiel&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_set   n=test2  z=$GUID()&lt;br /&gt;
 #var_set   n=edt    z=$EDT(edt1)   ie=42&lt;br /&gt;
 #var_set   n=_page_kunde_adressänderung_ro   z=N   zn=Y   zr=Y   r=kundenservice&lt;br /&gt;
&lt;br /&gt;
Zum Parameter rf: $NOW() in die Zwischenablage kopieren und dann ausführen:&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=N&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=Y&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_setempty==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_setempty setzt den Wert einer Variablen, sofern sie (noch) leer ist.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Besteht der Variableninhalt aus Leerzeichen, gilt die Variable auch als leer.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_setempty   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_setempty   n=test2  z=$GUID()&lt;br /&gt;
 #var_setempty   n=edt    z=$EDT(edt1)    ie=42&lt;br /&gt;
&lt;br /&gt;
==#var_add==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_add fügt einer Variablen einen Wert hinzu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. &lt;br /&gt;
* y -Typ der Operation; default ''text''&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** month - Es wird dem Datum eine Anzahl von Monaten hinzugefügt&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
*z - Wert, welcher der Variablen hinzugefügt wird, Funktionen werden ersetzt, default ist ein leerer String oder eine 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$NOW()&lt;br /&gt;
 #var_add   n=test   z=1   y=datetime&lt;br /&gt;
 #cout   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_log==&lt;br /&gt;
&lt;br /&gt;
Schreibt den Inhalt aller Variablen in das Debug-Log.&lt;br /&gt;
&lt;br /&gt;
Wird nur zur Fehlersuche verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_log&lt;br /&gt;
&lt;br /&gt;
==$VAR()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $VAR() wird auf den Inhalt der Variable zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
# optional: Der Wert wird vor oder nach der Rückgabe als Funktionsergebnis verändert; nur für ganzzahlige Werte&lt;br /&gt;
## ib (&amp;quot;increment before&amp;quot;) - Der Wert wird vor der Rückgabe um eins erhöht&lt;br /&gt;
## db (&amp;quot;decrement before&amp;quot;) - Der Wert wird vor der Rückgabe um eins verringert&lt;br /&gt;
## ia (&amp;quot;increment after&amp;quot;) - Der Wert wird nach der Rückgabe um eins erhöht&lt;br /&gt;
## da (&amp;quot;decrement after&amp;quot;) - Der Wert wird nach der Rückgabe um eins verringert&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #message  c=$VAR(test)&lt;br /&gt;
 #var_set  n=neuer_wert   z=$VAR(wert)   ie=$VAR(alternativwert)&lt;br /&gt;
 #execsql   k_lfdnr=$VAR(lfdnr,ib)&lt;br /&gt;
&lt;br /&gt;
=Kommandos=&lt;br /&gt;
&lt;br /&gt;
(Primär- und Sub) Kommandos sind üblicherweise benannt und werden im Code-Dialog eingegeben.&lt;br /&gt;
&lt;br /&gt;
Es besteht jedoch auch die Möglichkeit, lokale Kommandos innerhalb eines anderen Kommandos zu definieren. Diese Kommandos haben statt eines Kommando-Namens dann dann eine Kommando-Nummer.&lt;br /&gt;
&lt;br /&gt;
Lokale Kommandos werden üblicherweise für folgende Zwecke verwendet:&lt;br /&gt;
&lt;br /&gt;
* Bei der Verwendung von xlive werden bisweilen Prozeduren eingesetzt, die ihrerseits ein Kommando aufrufen (z.B. #sql_open). Wenn dieses Kommando nichts bereits existiert, kann es nur als lokales Kommando erstellt werden.&lt;br /&gt;
&lt;br /&gt;
* Wenn das auszuführende Kommando auf derselben Seite stehen soll wie die aufrufende Prozedur.&lt;br /&gt;
&lt;br /&gt;
Siehe als Beispiel: [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd fügt dem Kommando eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd fügt dem ersten Kommando eine Zeile hinzu, #cmd2 fügt dem zweiten Kommando eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd hat keine benannten Parameter. Die ganze Zeile nach dem #cmd und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd3 #text $DATA(n,login);$DATA(n,shortname);$DATA(n,firstname);$DATA(n,lastname);$DATA(n,userid);&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clear löscht ein Kommando&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd_clear löscht das erste Kommando, #cmd_clear2 löscht das zweite Kommando, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #cmd_clear Zeichen, so werden die dem gerade gelöschten Kommando hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear3&lt;br /&gt;
 #cmd_clear #grd_add   i=grid   f_logtext=&amp;quot;Kunde angerufen und nicht erreicht.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#cmd_clearall==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clearall löscht alle Kommandos&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clearall&lt;br /&gt;
&lt;br /&gt;
=CSV=&lt;br /&gt;
&lt;br /&gt;
Die CSV-Routinen werden verwendet, um CSV-Dateien einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==#csv_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_open öffnet eine CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_open öffnet die erste CSV-Datei, #csv_open2 öffnet die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*ber - wenn Y, werden die Zeilenumbrüche innerhalb von Feldern durch Leerzeichen ersetzt. Die Felder müssen dabei in doppelten Anführungszeichen eingeschlossen sein.&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - (&amp;quot;Filename&amp;quot;) Dateiname der CSV-Datei&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich. Muss bereits hier gesetzt werden, wenn mit $CSV_LINE auf den Header zugegriffen werden soll, bevor #csv_line ausgeführt wird.&lt;br /&gt;
*txt (&amp;quot;Text&amp;quot;) - alternativ zum Dateinamen fn die Nummer eines Textes, der als CSV-Datei verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open  fn=c:\temp\text.csv&lt;br /&gt;
&lt;br /&gt;
==#csv_line==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_line geht zeilenweise durch die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_line geht durch die erste CSV-Datei, #csv_line2 geht durch die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;database&amp;quot;) - Die Datenbank, für welche die Transaktion ausgeführt wird, wenn ert=Y gesetzt ist. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
*er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
*ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt, Funktionen werden ersetzt&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich.&lt;br /&gt;
*m (&amp;quot;maximum&amp;quot;) - Maximale Anzahl der Zeilen, die verarbeitet wird. Wird gerne bei der Entwicklung verwendet, um die Bearbeitungsgeschwindigkeit zu erhöhen. Funktionen werden ersetzt&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird im Falle einer Exception die Bearbeitung nicht abgebrochen, sondern lediglich Warnungen geloggt; Default N, Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Semikolon, Funktionen werden ersetzt&lt;br /&gt;
*trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_line  er=test_csv_line   hhr=Y   m=3&lt;br /&gt;
&lt;br /&gt;
==#csv_check==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_check prüft die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnt (&amp;quot;count&amp;quot;) - Anzahl der Header-Einträge, die geprüft wird; Funktionen werden ersetzt&lt;br /&gt;
*h1, h2... (&amp;quot;header&amp;quot;) - Eintrag im Header, der auf existenz geprüft wird; Groß und Kleinschreibung ist unerheblich, Funktionen werden ersetzt.&lt;br /&gt;
*n (&amp;quot;name&amp;quot; / &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in die/den das Ergebnis (Y oder N) geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*res (&amp;quot;result&amp;quot;) - Name der Variable oder Nummer des Values, in die/den der Ergebnistext geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwischen den einzelnen Spalten; Funktionen werden ersetzt&lt;br /&gt;
*y - Typ der Prüfung; Funktionen werden ersetzt, default header&lt;br /&gt;
** header - Prüft die Existenz von Spaltennamen im Header. Die zu prüfenden Spaltennamen werden als h1, h2... übergeben, cnt ist entsprechend zu setzen. Wenn alle geprüften Spaltennamen vorhanden sind, wird Y zurück gegeben, ansonsten N. Die fehlenden Spaltennamen werden als Ergebnistext zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open   fn=C:\temp\mad\done\MTF3108_ET2607_selektion.CSV&lt;br /&gt;
 #csv_check   n=1   res=2   cnt=3   h1=eins   h2=zwei   h3=drei&lt;br /&gt;
 #coutl $VAL(1) - $VAL(2)&lt;br /&gt;
&lt;br /&gt;
==#csv_paste==&lt;br /&gt;
&lt;br /&gt;
Übernimmt eine CSV-Datei aus der Zwischenablage. Auf die Werte kann mit $SEPLINE() zugegriffen werden, siehe [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
'''Multi-Row'''&lt;br /&gt;
&lt;br /&gt;
Mit dem Multi-Row-Modus können Daten eingelesen werden, die in einer Zeile mehrere gleichartige Werte haben.&lt;br /&gt;
&lt;br /&gt;
Daten, die im Single-Row-Modus wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465&lt;br /&gt;
 01.01.2020     8574&lt;br /&gt;
 01.01.2020     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     3456&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     4457&lt;br /&gt;
 03.01.2020     7658&lt;br /&gt;
&lt;br /&gt;
Würden im Multi-Row-Modus wie folgt aussehen (und könnten auch so eingelesen werden):&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465     8574     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436     6578     3456     6578     4457     7658&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Wenn dieser Parameter einen Wert hat, dann muss die kopierte CSV-Datei in der ersten Zeile auch diesen Wert haben, oder die Aktion wird abgebrochen; Funktionen werden ersetzt&lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden.&lt;br /&gt;
* mrs (&amp;quot;multi row start&amp;quot;) - Erste Spalte für den Multi-Row-Bereich&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Tabulatorzeichen&lt;br /&gt;
* trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ; default s&lt;br /&gt;
** m - multi; siehe Abschnitt Multi-Row&lt;br /&gt;
** s - single; die CSV-Datei wird Zeile für Zeile eingelesen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
* [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
 #csv_paste   er=imp_line   hhr=Y&lt;br /&gt;
 #csv_paste   er=imp_line   y=m   mrs=1&lt;br /&gt;
&lt;br /&gt;
==$CSV()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV() greift auf einen Feldinhalt der aktuellen CSV-Zeile zu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Spalte oder 0-relative Spaltennummer. Name der Spalte setzt voraus, dass bei #csv_line der Parameter hhr gleich Y ist.&lt;br /&gt;
# optional: Stelle der Zeichens, ab dem der Inhalt des CSV-Feldes zurück gegeben wird&lt;br /&gt;
# optional: Anzahl der Zeichen, die maximal zurück gegeben werden; wird meist dafür verwendet, damit die maximale Länge von Datenbankfeldern nicht überschritten wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0)&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird in der ersten CSV-Datei (#csv_open) auf die erste Spalte (0, da 0-relativ) zugegriffen.&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0,1,30)&lt;br /&gt;
&lt;br /&gt;
Wie oben, nur werden nur die ersten 30 Zeichen zurück gegeben&lt;br /&gt;
&lt;br /&gt;
==$CSV_LINE()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV_LINE() Gibt eine ganze Zeile einer CSV-Datei zurück&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Zeile: header gibt die Header-Zeile zurück, current die aktuelle Zeile in #csv_line&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CSV_LINE wird insbesondere dafür verwendet, um CSV-Dateien mit Daten zu ergänzen. Hier im Beispiel wird jede Zeile mit einer GUID ergänzt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #text $CSV_LINE(1,current)$GUID();&lt;br /&gt;
 &lt;br /&gt;
 #csv_open   fn=c:\temp\ex.csv   hhr=Y&lt;br /&gt;
 #text_clear $CSV_LINE(1,header)guid;&lt;br /&gt;
 #csv_line   er=1   hhr=Y&lt;br /&gt;
 &lt;br /&gt;
 #text_save   fn=c:\temp\ex2.csv&lt;br /&gt;
&lt;br /&gt;
Nach dem Öffnen der bestehenden CSV-Datei (es muss hier bereits hhr gesetzt werden) wird zunächst der Header in Text 1 eingefügt, ergänzt um die Spalte ''guid'' und das abschließende Semikolon. Danach gehen wir mit #csv_line durch alle Zeile, fügen diese komplett in Text 1 ein und hängen eine GUID hinten dran. Danach wird die Datei gespeichert.&lt;br /&gt;
&lt;br /&gt;
=Text=&lt;br /&gt;
&lt;br /&gt;
==#text==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text fügt dem Text eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text fügt dem ersten Text eine Zeile hinzu, #text2 fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Und jetzt noch eine GUID: $GUID()&lt;br /&gt;
 #text Der folgende Text kommt in Großbuchstaben: $UPP(hello world)&lt;br /&gt;
&lt;br /&gt;
==#textn==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#textn fügt dem Text eine Zeile hinzu. Im Unterschied zu #text werden dabei keine Funktionen ersetzt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #textn fügt dem ersten Text eine Zeile hinzu, #text2n fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #textn und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden dabei '''nicht''' ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #textn Zeile 1&lt;br /&gt;
 #textn Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_clear löscht einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_clear löscht den ersten Text, #text_clear2 löscht den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #text_clear Zeichen, so werden die dem gerade gelöschten Text hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear7&lt;br /&gt;
 #text7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
Das vorangestellt #text_clear stellt sicher, dass Text7 leer ist. Alternativ könnte man formulieren:&lt;br /&gt;
&lt;br /&gt;
 #text_clear7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_save==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_save speichert einen Text in einer Datei.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_save speichert den ersten Text, #text_save2 speichert den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* bom (&amp;quot;Byte order mark&amp;quot;) - Wenn Y, dann wird die Datei mit BOM geschrieben; default Y&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu speichernden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname, unter dem die Datei gespeichert wird. Bestehende Dateien werden überschrieben, sofern das Betriebssystem das nicht verhindert (z.B, weil die Datei gerade geöffnet ist)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Öffnet die gespeicherte Datei gleich anschließend.&lt;br /&gt;
*sort - Wenn Y, dann wird die Datei vor dem Speichern sortiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Hello world&lt;br /&gt;
 #text_save  fn=$DIR(userroot)hello_world.txt&lt;br /&gt;
 #text_save  fn=c:\temp\export_vert_export.prepared_.csv   e=utf8   bom=N&lt;br /&gt;
&lt;br /&gt;
==#text_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_open öffnet einen Text aus einer Datei, der bisherige Inhalt der Datei wird überschrieben.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_open öffnet den ersten Text, #text_open2 öffnet den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname der Datei, die geöffnet wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_open  fn=$DIR(userroot)test.txt&lt;br /&gt;
 #text Eine weitere Zeile, $GUID()&lt;br /&gt;
 #text_save  fn=$DIR(userroot)test.txt&lt;br /&gt;
&lt;br /&gt;
==#text_props==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_props stellt Eigenschaften des Textes ein.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_props bezieht sich auf den ersten Text, #text_props2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* dub (&amp;quot;duplicates&amp;quot;) - Verhalten einer sortierten Liste bezüglich Dubletten&lt;br /&gt;
** acc (&amp;quot;accept&amp;quot;) - Dubletten werden akzeptiert&lt;br /&gt;
** err (&amp;quot;error&amp;quot;) - Dubletten führen zu Fehlern&lt;br /&gt;
** ign (&amp;quot;ignore) - Dubletten werden ignoriert&lt;br /&gt;
* srt (&amp;quot;sorted&amp;quot;) - Wenn ja, dann ist die Liste sortiert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_props   srt=Y   dup=ign&lt;br /&gt;
&lt;br /&gt;
==#text_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_set setzt eine bestimmte Zeile eines Textes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_set bezieht sich auf den ersten Text, #text_set2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;index&amp;quot;) - 0-relativer Index der Zeile, die geschrieben werden soll. Mit ''last'' kann die letzte Zeile geschrieben werden, mit ''all'' werden alle Zeilen ersetzt, das wird dann gebraucht, wenn mehrzeiliger Text zugewiesen werden soll; Funktionen werden ersetzt&lt;br /&gt;
* z - Text, der geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text_set   i=2   z=&amp;quot;dritte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=last   z=&amp;quot;letzte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=all   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
==#text_sort==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_sort sortiert einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_sort bezieht sich auf den ersten Text, #text_sort2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* y - Typ, default alpha, Funktionen werden ersetzt&lt;br /&gt;
** alpha - sortiert alphanumerisch&lt;br /&gt;
** inv - invertiert die gegebene Reihenfolge&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=&amp;quot;,OU=2nd_Level_T1,OU=Kundenservice,OU=Benutzer,OU=Testtours,OU=Travel&amp;quot;&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text_dissect   z=$VAL(1)   sep=&amp;quot;,OU=&amp;quot;&lt;br /&gt;
 #coutl  $TEXT(1)&lt;br /&gt;
 #text_sort   y=inv&lt;br /&gt;
 #text_compose   n=1   sep=.&lt;br /&gt;
 #val_set   n=1   z=tt.$VAL(1)&lt;br /&gt;
 #coutl $VAL(1)&lt;br /&gt;
&lt;br /&gt;
 Ergebnis ist:&lt;br /&gt;
 2nd_Level_T1&lt;br /&gt;
 Kundenservice&lt;br /&gt;
 Benutzer&lt;br /&gt;
 Testtours&lt;br /&gt;
 tt.Testtours.Benutzer.Kundenservice.2nd_Level_T1.&lt;br /&gt;
&lt;br /&gt;
==#text_dissect==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_dissect zerteilt einen String anhand einer vorgegebenen Trennzeichenfolge und fügt das Ergebnis dem betreffenden Text hinzu. Gegebenenfalls muss der Text vorher mit #text_clear geleert werden.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_dissect bezieht sich auf den ersten Text, #text_dissect bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - wenn Y, wird die sep-Zeichenfolge noch mal dem String angehängt; default N, Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, anhand der String zerteilt wird; Funktionen werden ersetzt&lt;br /&gt;
* z - String, der zerlegt wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_compose==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_compose setzt einen Text mithilfe eines Trennzeichens zu einem String zusammen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_compose bezieht sich auf den ersten Text, #text_compose bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - Wenn Y, wird die Trennzeichenfolge auch noch mal am Ende des Strings eingefügt; default N, Funktionen werden ersetzt&lt;br /&gt;
* n - Nummer des Values oder Name der Variable, in welche der String geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichenfolge, die beim Zusammenfügen des Textes verwendet wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_act==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_act bearbeitet einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_act bezieht sich auf den ersten Text, #text_act2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text der Zeile, die bei insert eingefügt werden soll; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* cu (&amp;quot;current&amp;quot;) - 0-relative Zeilennummer der Operation; default 0, Funktionen werden ersetzt&lt;br /&gt;
* ne (&amp;quot;new&amp;quot;) - 0-relative Zeilennummer als Ziel bei move; default 0, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt&lt;br /&gt;
** delete - Löscht die Zeile an Position cu (&amp;quot;current&amp;quot;)&lt;br /&gt;
** insert - Fügt den Text c an der Position cu (&amp;quot;current&amp;quot;) ein&lt;br /&gt;
** move - verschiebt die Zeile cu (&amp;quot;current&amp;quot;) nach Zeile ne (&amp;quot;new&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #text_act   y=move   cu=0&lt;br /&gt;
&lt;br /&gt;
==#text_loop==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_loop geht durch die Zeilen eines Textes und ruft für jede Zeile ''er'' auf&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_loop  bezieht sich auf den ersten Text, #text_loop2  bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich ert bezieht&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m - (&amp;quot;maximum&amp;quot;) Es wird maximal für die Anzahl der angegebenen Zeilen das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* n - Name der Variable, in welche die 0-relative Schleifenvariable geschrieben wird. (Es würde auch in einen Value geschrieben, wenn es sich um eine Nummer handelt, das ergibt in der Praxis aber meist nicht viel Sinn) Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear eins&lt;br /&gt;
 #text zwei&lt;br /&gt;
 #text drei&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear #coutl - $TEXT(1,$VAR(eins))&lt;br /&gt;
 #text_loop   er=1   n=eins&lt;br /&gt;
&lt;br /&gt;
==#tvl_add==&lt;br /&gt;
&lt;br /&gt;
Addiert dem Wert in einer Text-Valueliste einen Wert hinzu. Es handelt sich dabei um eine nummerierte Prozedur: #tvl_add arbeitet mit Text 1, #tvl_add2 mit Text 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Zeile, der ein Wert hinzugefügt wird; Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Operation, Funktionen werden ersetzt, default text&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
* z - Der Wert, der hinzugefügt wird&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text eins=1&lt;br /&gt;
 #text zwei=2&lt;br /&gt;
 #text drei=3&lt;br /&gt;
 #tvl_add   y=int   n=zwei   z=1&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==$TEXT()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $TEXT() wird auf den Inhalt des Textes zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# optional Zeile des Textes (0-relativ). Wenn es keinen zweiten Parameter gibt, wird der komplette Text zurück gegeben. Alternativ als zweiter Parameter eine Sonderfunktion:&lt;br /&gt;
## cnt / count - Gibt die Anzahl der Zeilen zurück&lt;br /&gt;
## last - Gibt die letzte Zeile zurück&lt;br /&gt;
## ix - Gibt die Position des Textes im dritten Parameter zurück&lt;br /&gt;
## as_line - Gibt den Text als eine Zeile zurück, Zeilenumbrüche werden durch den dritten Parameter ersetzt&lt;br /&gt;
# optional in abhängigkeit vom zweiten Paremeter&lt;br /&gt;
## wenn zweiter Parameter ix: Textzeile, nach der mit ix gesucht wird&lt;br /&gt;
## wenn zweiter Parameter as_line: Zeichenfolge, mit der die Zeilenumbrüche ersetzt werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Zeile 3&lt;br /&gt;
 #message  c=$TEXT(1)&lt;br /&gt;
&lt;br /&gt;
 #code url=$TEXT(1,as_line,&amp;amp;)&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich gilt in BAL: Eine Prozedur - eine Zeile.&lt;br /&gt;
&lt;br /&gt;
Bei vielen und/oder langen Parametern führt das zu recht langen Code-Zeilen und zu Unübersichtlichkeit. Hier können nun Teile der Parameter mit #code in weitere Zeile ausgelagert werden, deren Inhalt dann mit $CODE$ oder $CODE$ der eigentlichen Code-Zeile hinzugefügt wird.&lt;br /&gt;
&lt;br /&gt;
==#code==&lt;br /&gt;
&lt;br /&gt;
Fügt Text dem Code-Speicher hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#code hat keine benannten Parameter. Die ganze Zeile nach dem #code und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=G:\pics\pic5d68865cdaba62_62767562.jpg&lt;br /&gt;
 #code fn2=G:\pics\pic5d913c48682128_67979256.jpg&lt;br /&gt;
 #email_send   from=test@****.de   to=info@*****************.de   bcc=info@*****.de   subject=Testmail   text=$TEXT(1)   $CODE$&lt;br /&gt;
&lt;br /&gt;
==$CODE$ / $CODEN$==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CODE$ und $CODEN$ sind keine Funktionen, auch wenn sie auf den ersten Blick ähnlich aussehen. Sie haben keine Parameter und auch keine Klammern, dafür ein abschließendes $.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen fügen den Code-Speicher der jeweiligen Zeile hinzu. $CODE$ löscht danach den Code-Speicher, $CODEN$ tut das nicht, so dass dieselben Parameter wiederholt eingefügt werden können (beim letzten Einfügen sollte dann $CODE$ verwendet werden).&lt;br /&gt;
&lt;br /&gt;
=Separierte Zeile=&lt;br /&gt;
&lt;br /&gt;
Eine separierte Zeile ist eine Textzeile, die mehrere gleichartige Werte enthält, die durch Trennzeichen getrennt sind.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 3244,4465,7763,4536,4356,7777&lt;br /&gt;
&lt;br /&gt;
Solche Zeilen können mit #sepline aufgetrennt werden.&lt;br /&gt;
&lt;br /&gt;
==#sepline==&lt;br /&gt;
&lt;br /&gt;
Trennt eine separierte Zeile auf und führt für jeden Wert das mit er angegebene Kommando aus.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur (#sepline, #sepline2...)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y; Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, für welche die Transaktion gestartet wird, wenn ert=Y. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern (&amp;quot;each row no&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Wenn Y, wird für jeden Wert der separierten Zeile eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Es wird maximal für die Anzahl der angegebenen Werte das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten; Funktionen werden ersetzt.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N; Funktionen werden ersetzt.&lt;br /&gt;
* nn (&amp;quot;not null&amp;quot;) - Wenn Y, dann wird er nur für Werte der separierten Zeile aufgerufen, die nicht leer sind. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Das oder die Trennzeichen; default ist das Semikolon, Funktionen werden ersetzt.&lt;br /&gt;
* z - Der Inhalt der separierten Zeile; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(1)&lt;br /&gt;
 #sepline z=3244,4465,7763,4536,4356,7777   sep=,   er=1&lt;br /&gt;
&lt;br /&gt;
==$SEPLINE()==&lt;br /&gt;
&lt;br /&gt;
Greift auf den einzelnen Wert einer mit #sepline getrennten Zeile zu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der separierten Zeile&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(3)&lt;br /&gt;
 #sepline3 z=3244;4465;7763;4536;4356;7777     er=1&lt;br /&gt;
&lt;br /&gt;
=User und Rechte=&lt;br /&gt;
&lt;br /&gt;
Aus Gründen der Übersichtlichkeit ist die Rechtevergabe zweistufig:&lt;br /&gt;
&lt;br /&gt;
# Es werden (meist am Anfang eines Primär-Kommandos) Rechte-Definitionen erstellt, die einer oder mehreren Benutzergruppen Rechte (lesen oder lesen und schreiben) zuweisen. Die Rechte werden dabei implizit auch allen Untergruppen der angegebenen Benutzergruppe erteilt (Zum Beispiel: Rechte der Gruppe ''user'' hat auch implizit die Gruppe ''user.admin'').&lt;br /&gt;
# Dem Parameter r verschiedener Prozeduren kann dann eine Rechte-Definition zugewiesen werden.&lt;br /&gt;
&lt;br /&gt;
Den Parameter r als Rechte-Definition berücksichtigen die folgenden Prozeduren:&lt;br /&gt;
&lt;br /&gt;
* #frm&lt;br /&gt;
* Buttons (#btn, #btns_btn)&lt;br /&gt;
* Alle Segmente (#text_seg, #memo_seg, #btns_seg, vl_seg, #grd_seg, #xgrd_seg)&lt;br /&gt;
* Tree (#tree_add, #tree_fill, #tree_fillsql, Lese-Recht reicht)&lt;br /&gt;
* Grid-Spalten (#grd_col, #xgrd_col)&lt;br /&gt;
* #vl_line (für die komplette Zeile (r) und die einzelne Zelle (r1, r2, r3...))&lt;br /&gt;
&lt;br /&gt;
Wo der Parameter r nicht gesetzt ist, wird die Rechte-Definition der Formulars verwendet.&lt;br /&gt;
&lt;br /&gt;
==#rights==&lt;br /&gt;
&lt;br /&gt;
Setzt eine Rechte-Definition im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Rechte-Definition; default ist ''frm'', also dsa Default-Recht für das Formular.&lt;br /&gt;
* r_ (&amp;quot;right&amp;quot;) - Prefix für die Benutzergruppe. Für die Rechte-Definition sind die folgenden Werte zulässig&lt;br /&gt;
** n (&amp;quot;no&amp;quot;) - kein Recht&lt;br /&gt;
** r (&amp;quot;read&amp;quot;) - nur lesen&lt;br /&gt;
** w (&amp;quot;write&amp;quot;) - lesen und schreiben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights  n=frm   r_user=r   r_user.admin=w&lt;br /&gt;
&lt;br /&gt;
Setzt für alle User das Lese-Recht und für Administratoren das Lese- und Schreibrecht.&lt;br /&gt;
&lt;br /&gt;
==#rights_clear==&lt;br /&gt;
&lt;br /&gt;
Löscht alle Rechte-Definitionen im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
(Wird in der Praxis selten benötigt, weil Kommandos mit leerer Rechte-Definition starten.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights_clear&lt;br /&gt;
&lt;br /&gt;
==$USERID()==&lt;br /&gt;
&lt;br /&gt;
Die ID des angemeldeten Users&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kusr=$USERID()&lt;br /&gt;
&lt;br /&gt;
==$RIGHTUSERID()==&lt;br /&gt;
&lt;br /&gt;
Administratoren können andere User einstellen (Userliste links unten im BAF-Client), vor allem um deren Rechte zu prüfen. Die UserID dieses ausgewählten Users kann mit der Funktion $RIGHTUSERID() ermittelt werden.&lt;br /&gt;
&lt;br /&gt;
In fast allen Fällen gilt der folgende Grundsatz: Lesende Operationen mit $RIGHTUSERID(), schreibende Operationen mit $USERID().&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_open   kusr=$RIGHTUSERID()&lt;br /&gt;
&lt;br /&gt;
==$ADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der angemeldete User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $ADM()&lt;br /&gt;
&lt;br /&gt;
==$RADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der ausgewählte User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $RADM()&lt;br /&gt;
&lt;br /&gt;
=Ausführen=&lt;br /&gt;
&lt;br /&gt;
==#exec==&lt;br /&gt;
&lt;br /&gt;
Führt ein anderes Kommando aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Names des (Primär- oder Sub-) Kommandos, das ausgeführt werden soll.&lt;br /&gt;
* ex (&amp;quot;exception&amp;quot;) - Name oder Nummer des Kommandos, das ausgeführt wird, wenn bei der Ausführung von cmd eine Exception auftritt; siehe Beispiele&lt;br /&gt;
* fin (&amp;quot;finally&amp;quot;) - Name oder Nummer des Kommandos, das nach der Ausführung von cmd ausgeführt wird - egal ob eine Exception aufgetreten ist oder nicht. Wird nur berücksichtigt, wenn der Parameter ex nicht gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel löst das Problem, dass ein neues PDF unter demselben Dateinamen nicht erstellt werden kann, wenn beim vorherigen Versuche der Erstellung eine Exception aufgetreten ist. In einem solchen Fall wurde ein #pdf_start, aber kein #pdf_stop ausgeführt, und die geöffnete Datei sperrt diesen Dateiname, bis der BAF-Client geschlossen wird. Lösung dieses Problems ist es, im Parameter ex ein #pdf stop auszuführen; auf das Öffnen der Datei kann in einem solchen Fall verzichtet werden. Mit der Funktion $DATA() wird hier im Beispiel gezielt eine Exception ausgelöst.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test_pdf&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #pdf_text  c=&amp;quot;Hello World&amp;quot;&lt;br /&gt;
 -- #cmd #pdf_text  c=&amp;quot;Hello World $DATA(dat,test)&amp;quot;&lt;br /&gt;
 #cmd #pdf_stop   o=Y&lt;br /&gt;
 &lt;br /&gt;
 #pdf_start  fn=$DIR(doc)\test.pdf&lt;br /&gt;
 #exec   cmd=1   ex=&amp;quot;#pdf_stop   o=N&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test_pdf executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#batchexec==&lt;br /&gt;
&lt;br /&gt;
Speichert den Text n in der Datei batch.bat und führt diese aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clr (&amp;quot;clear&amp;quot;) - Wenn Y, wird der Text nach Ausführung des Batch-Datei gelöscht; Default Y; Funktionen werden ersetzt;&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes; der mit #text gespeicherte Text hat die Nummer 1 &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #batchexec   n=1&lt;br /&gt;
&lt;br /&gt;
==#file_open==&lt;br /&gt;
&lt;br /&gt;
Öffnet eine Datei (oder auch eine Webseite)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder die URL der Webseite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_open  fn=c:\temp\test.csv&lt;br /&gt;
 #file_open  fn=https://www.google.de&lt;br /&gt;
&lt;br /&gt;
==#loop==&lt;br /&gt;
&lt;br /&gt;
BAL kennt keine Schleifen als Sprachelement. Um Schleifen mit einer fest Schleifenzahl auszuführen, wird die Prozedur #loop verwendet. lf muss nicht kleiner als lt sein, #loop kann auch von oben nach unten zählen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* lf (&amp;quot;loop from&amp;quot;) - Anfangswert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* lt (&amp;quot;loop to&amp;quot;) - Endwert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in der die Schleifenvariable gespeichert wird (damit sie an anderer Stelle gelesen werden kann); Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #loop   lf=42   lt=1337   er=test_line&lt;br /&gt;
&lt;br /&gt;
==#exit==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #exit bricht die Ausführung auf der jeweiligen Code-Ebene (Kommando bzw. Sub-Kommando) ab&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 ~ $EMPTY($PVAL(vl,id))   and   $PVAL(vl,status) &amp;gt; 20&lt;br /&gt;
 #sql select nextval('ausza_id') as id&lt;br /&gt;
 #sql_openval   f_id=1&lt;br /&gt;
 #page_val   i=vl   f=id   z=$VAL(1)&lt;br /&gt;
 #save&lt;br /&gt;
 #exit&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Der Beispiel-Code befindet sich auf der Seite xausza_page_ausza und baut die entsprechende Seite auf. Er prüft, ob bereits eine ID-Gesetzt ist - wenn nicht, wird über eine Datenbank-Sequenz die nächste ID abgefragt, in das VL-Segment geschrieben und die Seite gespeichert. Beim Speichern der Seite wird sie jedoch neu aufgerufen, also komplett neu aufgebaut, was erst einmal kein Problem ist. Danach würde aber die Ausführung auf der Code-Ebene, auf der sich #save befindet, fortgeführt, was zur Folge hat, dass die dann folgenden Segmente doppelt erscheinen (zunächst die aus dem Neu-Aufbau der Seite, dann die, die von der Fortsetzung des Codes her stammen).&lt;br /&gt;
&lt;br /&gt;
Um dies zu vermeiden muss die Ausführung des Codes nach #save abgebrochen werden.&lt;br /&gt;
&lt;br /&gt;
==$EXEC==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando. Im ausgeführten Kommando kann eine Variable gesetzt werden, die dann als Funktionsergebnis von $EXEC zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll&lt;br /&gt;
# optional: Der Name der Variablen, in der das Ergebnis steht; default ist ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;test_funkexec&amp;quot;   y=console&lt;br /&gt;
 #cout   c=$EXEC(test_funkexec_line)&lt;br /&gt;
&lt;br /&gt;
 -- test_funkexec_line&lt;br /&gt;
 #var_set   n=result   z=42&lt;br /&gt;
&lt;br /&gt;
=Dateien und Verzeichnisse=&lt;br /&gt;
&lt;br /&gt;
==#file_op==&lt;br /&gt;
&lt;br /&gt;
Führt eine Operation mit einer Datei oder einem Verzeichnis aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder des Verzeichnisses&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in die/den das Ergebnis der Operation (Y oder N) geschrieben wird.&lt;br /&gt;
* on (&amp;quot;old name) - der bisherige Dateiname bei RenameFile&lt;br /&gt;
* y - Typ der Operation&lt;br /&gt;
** cd / createdir - Erzeugt ein Verzeichnis&lt;br /&gt;
** cf / copyfile - Kopiert eine Datei (von on zu fn)&lt;br /&gt;
** df / deletefile - Löscht eine Datei&lt;br /&gt;
** fd / forcedirectories - Stellt sicher, dass ein Pfad vorhanden ist&lt;br /&gt;
** rd / removedir - Entfernt ein Verzeichnis&lt;br /&gt;
** rf / renamefile - Benennt eine Datei um, kann auch dazu verwendet werden, eine Datei zu verschieben&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #file_op   y=renamefile   on=c:\temp\debug.txt   fn=c:\temp\test\debug.txt   n=1&lt;br /&gt;
 #cout   c=$VAL(1)&lt;br /&gt;
 &lt;br /&gt;
 #file_op   y=fd   fn=c:\eins\zwei\drei\vier&lt;br /&gt;
&lt;br /&gt;
==#file_search==&lt;br /&gt;
&lt;br /&gt;
Sucht Dateien und schreibt die Ergebnisliste in einen Text.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* clr - (&amp;quot;clear&amp;quot;) wenn Y, wird der Text vor der Suche geleert. Default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, in den die Ergebnisliste geschrieben wird; default 1, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_search   fn=c:\*.ini   n=1   y=0   all_=Y&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==#file_wait==&lt;br /&gt;
&lt;br /&gt;
Wartet, bis zumindest eine Datei vorhanden ist, die den Kriterien entspricht, und führt dann cmd aus. Wird nach der in to eingestellten Zeit keine Datei gefunden, dann wird mit dem in cmdto eingestellten Kommando abgebrochen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* cmd - Kommando, das ausgeführt wird, sobald eine Datei gefunden wird; Funktionen werden ersetzt&lt;br /&gt;
* cmdto - Kommando, das ausgeführt wird, sobald die Prozedur wegen eines TimeOuts abgebrochen wird; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* sleep - Zeit in ms zwischen den einzelnen Suchen nach einer Datei, die den Kriterien entspricht; Default 1000, Funktionen werden ersetzt&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in ms, nach der die Ausführung abgebrochen wird; Default 15000, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #cout c=&amp;quot;Gefunden&amp;quot;&lt;br /&gt;
 #cmd_clear2 #cout c=&amp;quot;TimeOut&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #file_wait   fn=C:\temp\test\*.txt   cmd=1   cmdto=2&lt;br /&gt;
&lt;br /&gt;
==#dir_force==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass es den spezifizierten Verzeichnispfad gibt, indem erforderlichenfalls Verzeichnisse angelegt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Names des Pfads&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_force   n=c:\temp\pdf&lt;br /&gt;
&lt;br /&gt;
==#dir_proc==&lt;br /&gt;
&lt;br /&gt;
Durchsucht ein Verzeichnis nach Dateien, die den angegebenen Kriterien entsprechen, und führt für jede gefundene Datei ''cmd'' aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das für jede gefundene Datei ausgeführt wird&lt;br /&gt;
* dn (&amp;quot;DirectoryName&amp;quot;) - Pfad des Verzeichnisses, in dem die Dateien gesucht werden; Funktionen werden ersetzt.&lt;br /&gt;
* done - Verzeichnis, in das die Dateien nach Abarbeitung verschoben werden (sofern der Parameter nicht leer ist). Funktionen werden ersetzt.&lt;br /&gt;
* fn (&amp;quot;filename&amp;quot;) - Suchkriterium für den Dateinamen; Funktionen werden ersetzt; Default *&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in welcher der Dateiname der aktuell zu bearbeitenden Datei inklusive Pfad gespeichert wird; Funktionen werden ersetzt; Default dir_proc&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_proc   dn=c:\temp\in   done=c:\temp\done   fn=*.csv   cmd=importcsv_line&lt;br /&gt;
&lt;br /&gt;
==$FILEINFO()==&lt;br /&gt;
&lt;br /&gt;
Liefert Infos über eine Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Dateiname&lt;br /&gt;
# Typ der Information, es stehen dabei folgende Optionen zur Verfügung&lt;br /&gt;
#* size - Dateigröße in Byte&lt;br /&gt;
#* size_point - Dateigröße in Byte, Punkte alle drei Zeichen von rechts&lt;br /&gt;
#* size_auto - Dateigröße in Byte, kB, MB oder GB, je nach Größe; mit Einheit&lt;br /&gt;
#* size_kb - Dateigröße in kB (analog Windows-Explorer)&lt;br /&gt;
#* date - Datum im Format dd.mm.yyyy&lt;br /&gt;
#* date_yyyy - Datum im Format yyyymmdd&lt;br /&gt;
#* datetime - Datum und Uhrzeit im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
#* datetime_yyyy - Datum im Format yyyymmddhhmmss&lt;br /&gt;
#* exists - Y, wenn die Datei existiert, sonst N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=fn   z=&amp;quot;T:\Tools Gruppenrechte\BC3 light\BafClientFM.exe&amp;quot;&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_point)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_auto)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_kb)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),exists)&lt;br /&gt;
&lt;br /&gt;
Ergebnis&lt;br /&gt;
&lt;br /&gt;
 27668480&lt;br /&gt;
 27.668.480&lt;br /&gt;
 26,39 MB&lt;br /&gt;
 27.020 kB&lt;br /&gt;
 02.05.2023&lt;br /&gt;
 20230502&lt;br /&gt;
 02.05.2023 12:20:09&lt;br /&gt;
 20230502122009&lt;br /&gt;
 Y&lt;br /&gt;
&lt;br /&gt;
==$DIR()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Verzeichnisnamen. Trailing Path Delimiter (\ bei Windows) wird immer angehängt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bezeichnung des Verzeichnisses&lt;br /&gt;
## appdata - Verzeichnis für Anwendungsdaten des Users&lt;br /&gt;
## cappdata - gemeinsames Verzeichnis für Anwendungsdaten aller User&lt;br /&gt;
## cdoc - gemeinsames Dokumentenverzeichnis  aller User&lt;br /&gt;
## cfav / cfavorites - gemeinsames Favoritenverzeichnis aller User&lt;br /&gt;
## cmusic - gemeinsames Musikverzeichnis aller User&lt;br /&gt;
## cpic / cpictures - gemeinsames Bilderverzeichnis aller User&lt;br /&gt;
## cvideo - gemeinsames Videoverzeichnis aller User&lt;br /&gt;
## desktop - Desktopverzeichnis des Rechners&lt;br /&gt;
## '''doc''' / docdir - Dokumentenverzeichnis des Users&lt;br /&gt;
## downloads - Downloadsverzeichnis des Users&lt;br /&gt;
## fav / favorites - Favoritenverzeichnis des Users&lt;br /&gt;
## fonts - Fontsverzeichnis des Rechners&lt;br /&gt;
## music - Musikverzeichnis des Users&lt;br /&gt;
## pic / pictures - Bilderverzeichnis des Users&lt;br /&gt;
## prog / program - Programmverzeichnis des Rechners&lt;br /&gt;
## prog86 / program86 - Programm86-Verzeichnis des Rechners&lt;br /&gt;
## '''root''' - Root-Verzeichnis des BAF-Clients bzw. des BAF-Servers&lt;br /&gt;
## '''userroot''' / usrroot - User-Verzeichnis des BAF-Clients&lt;br /&gt;
## video - Videoverzeichnis des Users&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=$DIR(doc)test.txt&lt;br /&gt;
&lt;br /&gt;
==$FILEDIALOG()==&lt;br /&gt;
&lt;br /&gt;
Führt einen Dateiauswahl-Dialog aus und gibt den gewählten Dateinamen zurück. Im Falle des Abbruchs wird ''abort'' zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wenn der erste Parameter ''save'' lautet, wird ein Speichern-Dialog, sonst ein Öffnen-Dialog aufgerufen.&lt;br /&gt;
# Filter-Statement, immer Kombinationen aus Text (Text-Dateien *.txt) und Filter-Statement(*.txt), getrennt durch Pipes.&lt;br /&gt;
# Standard-Dateierweiterung&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=&amp;quot;$FILEDIALOG(save,Text-Dateien *.txt|*.txt|Alle Dateien *.*|*.*,txt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Bitte beachten: Wegen der Leerzeichen im Filter-Statement muss der ganze Parameter in doppelte Anführungszeichen gesetzt werden.)&lt;br /&gt;
&lt;br /&gt;
=ZIP=&lt;br /&gt;
&lt;br /&gt;
==#zip_create==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine ZIP-Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Dateien, die der ZIP-Datei hinzugefügt werden; Funktionen werden ersetzt&lt;br /&gt;
* dir (&amp;quot;directory&amp;quot;) - Verzeichnis, wenn das nicht bei allen fn1, fn2... angegeben werden soll&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Der Dateiname, unter dem die ZIP-Datei gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* fn1, fn2,... (&amp;quot;FileName&amp;quot;) - Die Dateien, die in der ZIP-Datei gespeichert werden; die Anzahl wird mit dem Parameter cnt bestimmt; Funktionen werden ersetzt&lt;br /&gt;
* list - Nummer eines Textes (#text, #text2...), in dem die Dateien gelistet sind, die der ZIP-Datei hinzugefügt werden sollen. Wenn list ein Wert größer 0 hat, werden cnt und fn1, fn2... ignoriert. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* pw (&amp;quot;PassWord&amp;quot;) - Password der erzeugten ZIP-Datei; Funktionen werden ersetzt.&lt;br /&gt;
* pwc (&amp;quot;PassWordCrypted&amp;quot;) - Wenn Y, dann ist das Passwort mit der Verschlüsselungsfunktion auf der Seite Tools des Code-Dialogs verschlüsselt. Hinweis: Mit dieser Verschlüsselung verhindert man lediglich, dass das Passwort direkt aus dem Code ausgelesen werden kann. Wird der BAF-Client mit dem Delphi-Debugger ausgeführt, lässt sich leicht an die betreffende Stelle ein Breakpoint setzen und das Passwort dann im Klartext auslesen (dieselbe Unit uBafCrypt vorausgesetzt).&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #zip_create   fn=$VAR(root).zip   list=1&lt;br /&gt;
 &lt;br /&gt;
 #var_set   n=fn_zip   z=tt_mail_$VAR(reise)-$VAR(reisename)_$PAD($VAR(lfdnr),4,L,0)_$NOWFMT(yyyymmdd).zip&lt;br /&gt;
 #file_op   y=df   fn=$VAR(path)\$VAR(fn_zip)&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=$VAR(filename).txt&lt;br /&gt;
 #code fn2=$VAR(filename).sab&lt;br /&gt;
 #zip_create   dir=$VAR(path)   fn=$VAR(path)\$VAR(fn_zip)    pw=$VAR(pw)   $CODE$&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #zip_create ersetzt nicht vorherige Dateien. Von daher im Zweifelsfall wie im zweiten Beispiel vorher eine Datei dieses Namens löschen.&lt;br /&gt;
&lt;br /&gt;
=Ini-Dateien=&lt;br /&gt;
&lt;br /&gt;
Der BAF-Client verwendet eine Ini-Datei im Root-Verzeichnis (vor allem für die Datenbankverbindungen) und eine Ini-Datei ''BafClientFM.ini'' im User-Anwendungsverzeichnis (vor allem für die Formularpositionen). Es können aber auch weitere Ini-Dateien verwendet werden.&lt;br /&gt;
&lt;br /&gt;
==#ini_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Ini-Datei. #ini_val ist eine nummerierte Prozedur: #ini_val schreibt in die erste Ini-Datei, #ini_val2 in die zweite Ini-Datei und so weiter. Diese Ini-Dateien werden zunächst nur im Speicher gehalten und müssen explizit aus einer Datei geladen oder in eine Datei gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;item&amp;quot; / &amp;quot;ident&amp;quot;) - Name des Eintrags in der Ini-Datei; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Wenn der Parameter n den Wert ''usr'' oder ''user'' hat, dann bleibt die Nummer der Ini-Datei unberücksichtigt und der Wert wird in die Datei ''BafClientFM.ini'' im im User-Anwendungsverzeichnis geschrieben.&lt;br /&gt;
* sec (&amp;quot;section&amp;quot;) - Abschnitt in der Ini-Datei; Funktionen werden ersetzt; default ''values''&lt;br /&gt;
* z - Wert, der in die Ini-Datei geschrieben wird; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_val  i=date_last   z=$NOW()&lt;br /&gt;
&lt;br /&gt;
==#ini_load==&lt;br /&gt;
&lt;br /&gt;
Lädt eine Ini-Datei aus einer Datei. Es handelt sich um eine nummerierte Prozedur: #ini_load lädt die Ini-Datei 1, #ini_load2 lädt die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, die geladen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_load   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==#ini_save==&lt;br /&gt;
&lt;br /&gt;
Speichert eine Ini-Datei ineine Datei. Es handelt sich um eine nummerierte Prozedur: #ini_save speichert die Ini-Datei 1, #ini_save2 speichert die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, in die gespeichert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_save   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==$INI()==&lt;br /&gt;
&lt;br /&gt;
Liest einen Wert aus einer Ini-Datei.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
# Item (Ident)&lt;br /&gt;
# optional: Sektion; wenn nicht vorhanden, dann ''values''. Wenn ''db!'', dann wird als Sektion die aktuell gewählte Datenbankverbindung verwendet (in diesem Fall sollte als erster Parameter ''root'' verwendet werden).&lt;br /&gt;
# optional: Default-Wert; wenn nicht vorhanden, dann ein leerer String&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum)&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum,bearbeitung,$TODAY())&lt;br /&gt;
&lt;br /&gt;
==$INITEXT()==&lt;br /&gt;
&lt;br /&gt;
Gibt die komplette Ini-Datei zurück. Wird vor allem beim Debugging verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $INITEXT(usr)&lt;br /&gt;
&lt;br /&gt;
=Zwischenablage=&lt;br /&gt;
&lt;br /&gt;
Das BAF-Framework unterstützt die Zwischenablage nur für Text.&lt;br /&gt;
&lt;br /&gt;
==#clipboard==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Text in die Zwischenablage&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* z - Wert, der in der Zwischenablage gespeichert werden soll; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #clipboard   z=$TEXT()&lt;br /&gt;
 #clipboard   z=$CHR(dquote)$PVAL(test,zahl,allsel,$CHR(crlf))$CHR(dquote)&lt;br /&gt;
&lt;br /&gt;
==$CLIPBOARD()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Text aus der Zwischenablage zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setvar   n=clp   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
=String-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben einen String zurück.&lt;br /&gt;
&lt;br /&gt;
==$BASE64()==&lt;br /&gt;
&lt;br /&gt;
En- oder Decodiert einen Text im Base64-Code&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Encoding oder Decoding:&lt;br /&gt;
## e - Encoding&lt;br /&gt;
## d - Decoding&lt;br /&gt;
# Text, der en-oder decodet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $BASE64(e,Dies ist ein Test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$CHR()==&lt;br /&gt;
&lt;br /&gt;
Gibt ein Zeichen (ggf zwei Zeichen) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Ansi-Zeichennummer oder eine der folgenden Bezeichnungen:&lt;br /&gt;
## crlf - Zeilenumbruch #13#10&lt;br /&gt;
## cr - Zeichen #13&lt;br /&gt;
## lf - Zeichen #10&lt;br /&gt;
## tab - Tabulator&lt;br /&gt;
## quote - ' (einfache Anführungszeichen)&lt;br /&gt;
## dquote - &amp;quot; (doppelte Anführungszeichen)&lt;br /&gt;
## space / leer - Leerzeichen&lt;br /&gt;
## comma / komma - , (Komma)&lt;br /&gt;
## questionmark / qmark / frage / fragezeichen - ?&lt;br /&gt;
## bro / bracket_open - (&lt;br /&gt;
## brc / bracket_close - )&lt;br /&gt;
## dollar - $&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CONVERT()==&lt;br /&gt;
&lt;br /&gt;
Konvertiert einen String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Konvertierungsfunktion&lt;br /&gt;
## isodate&lt;br /&gt;
## isodatetime&lt;br /&gt;
## truefalse&lt;br /&gt;
## pointfloat&lt;br /&gt;
## urlcode&lt;br /&gt;
## utf8&lt;br /&gt;
# String, der konvertiert werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $CONVERT(isodate,2025-03-12)&lt;br /&gt;
 #coutl $CONVERT(isodatetime,2025-03-12 12:03:17)&lt;br /&gt;
 #coutl $CONVERT(truefalse,true)&lt;br /&gt;
 #coutl $CONVERT(pointfloat,12.3)&lt;br /&gt;
 #coutl $CONVERT(urlcode,Für schönen Ärger)&lt;br /&gt;
 #coutl $CONVERT(utf8,Für schönen Ärger)&lt;br /&gt;
&lt;br /&gt;
(Ergebnis)&lt;br /&gt;
 12.03.2025&lt;br /&gt;
 12.03.2025 12:03:17&lt;br /&gt;
 Y&lt;br /&gt;
 12,3&lt;br /&gt;
 F%C3%BCr%20sch%C3%B6nen%20%C3%84rger&lt;br /&gt;
 Für schönen Ärger&lt;br /&gt;
&lt;br /&gt;
==$COPY()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$COPY($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$EXEC()==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando aus und gibt ein Funktionsergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll.&lt;br /&gt;
# optional: Name der Variable, die als Funktionsergebnis zurück gegeben werden soll; default ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=test   z=$EXEC(testkommando)&lt;br /&gt;
&lt;br /&gt;
==$GUID()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine GUID und gibt sie zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# optional: Name einer Variablen, in welcher die GUID zusätzlich gespeichert wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kid=$GUID()&lt;br /&gt;
&lt;br /&gt;
==$HASH()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt einen Hash-Wert vom String im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, von welchem der Hash gebildet werden soll.&lt;br /&gt;
# zu verwendender Hash-Algorithmus:&lt;br /&gt;
## sha512&lt;br /&gt;
## sha512_256&lt;br /&gt;
## sha512_224&lt;br /&gt;
## sha384&lt;br /&gt;
## sha256&lt;br /&gt;
## sha224&lt;br /&gt;
## sha1&lt;br /&gt;
## md5 (Hinweis: MD5 gilt seit Längerem als nicht mehr sicher. Verwenden Sie ihn nur, wenn dies aus Gründen der Abwärts-Kompatbilität zwingend ist.)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$HASH($PVAL(vl,1,2),sha512)&lt;br /&gt;
&lt;br /&gt;
==$INCLUDE()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass der als dritter Parameter übergebene Text am Anfang oder am Ende steht, gegebenenfalls wird er dort eingefügt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## lead(oder leading) - Text muss am Anfang stehen&lt;br /&gt;
## leadci(oder leadingci oder leadingcaseinsensitive) - Text muss am Anfang stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
## trail(oder trailing) - Text muss am Ende stehen&lt;br /&gt;
## trailci(oder trailci oder trailingcaseinsensitive) - Text muss am Ende stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
# Text, in den gegebenenfalls eingefügt wird&lt;br /&gt;
# Text, der gegebenenfalls eingefügt wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCLUDE(trailci,test.PDF,.pdf)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$INVLOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Key aus einer Nachschlageliste bei Übergabe des Values.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Value des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$INVLOOKUP(general_status,aktiv,Wert nicht vorhanden)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus einer Nachschlageliste.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Key des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$LOOKUP(general_status,1,Status nicht gesetzt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOW()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Kleinbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Kleinbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LOW($EDT(edt1)) = bus&lt;br /&gt;
&lt;br /&gt;
==$LOWNOSPACE()==&lt;br /&gt;
&lt;br /&gt;
Wandelt einen String in Kleinbuchstaben und ersetzt alle Leerzeichen durch Unterstriche.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der gewandelt werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$LOWNOSPACE($PVAL(vl,1,2))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$NOCRLF()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Zeilenumbrüche&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem die Zeilenumbrüche entfernt werden sollen&lt;br /&gt;
# optional: Zeichenfolge, die an Stelle der Zeilenumbrüche eingefügt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=2   z=$NOCRLF($VAL(1),;)&lt;br /&gt;
&lt;br /&gt;
==$NVL()==&lt;br /&gt;
&lt;br /&gt;
Liefert einen Ersatzwert, wenn der Wert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird, wenn der erste Parameter leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   where ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0)&lt;br /&gt;
&lt;br /&gt;
Liefert $PVAL einen leeren Wert zurück (z.B., weil die Gridzeile neu angelegt wurde und daher noch keine Nummer eingetragen ist), so wird statt dessen 0 verwendet, damit die WHERE-Klausel syntaktisch korrekt ist.&lt;br /&gt;
&lt;br /&gt;
==$ONLYCHAR()==&lt;br /&gt;
&lt;br /&gt;
Entfernt unerwünschte Zeichen aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# optional: Typ der Funktion&lt;br /&gt;
## (leer) - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z', 'ä', 'ö', 'ü', 'Ä','Ö', 'Ü', 'ß']) sind&lt;br /&gt;
## charnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind&lt;br /&gt;
## low - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## upp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## charnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## charnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## uml - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z') sind, Umlaute werden konvertiert (ä -&amp;gt; ae, ö -&amp;gt; oe, ü -&amp;gt; ue, Ä -&amp;gt; Ae, Ö -&amp;gt; Oe, Ü -&amp;gt; Ue, ß -&amp;gt; ss)&lt;br /&gt;
## umlcharnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Umlaute werden konvertiert&lt;br /&gt;
## umllow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## no191 / not191 - Es werden alle Zeichen mit der ANSI-Nummer 191 (¿) entfernt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg)&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg,umllow)&lt;br /&gt;
&lt;br /&gt;
==$PAD()==&lt;br /&gt;
&lt;br /&gt;
Füllt links oder rechts bis zur vorgegebenen Länge mit Zeichen auf.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# Soll-Länge. Ist der ursprüngliche String bereits länger, wird er nicht gekürzt, es werden aber auch keine weiteren Zeichen hinzugefügt&lt;br /&gt;
# Wenn L, werden die Zeichen vorne hinzugefügt, andernfalls hinten&lt;br /&gt;
# Zeichen, die soweit und so oft hinzugefügt werden, bis die Soll-Länge erreicht ist. Umfasst der Parameter mehrere Zeichen, werden diese ggf. nicht alle hinzugefügt.&lt;br /&gt;
# optional: Länge, auf die der ursprüngliche String vor der weiteren Verarbeitung gekürzt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   text1 = '$PAD($VAR(text1),70,R, )'&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ des Ergebnisses&lt;br /&gt;
## curr - Zahl mit zwei Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## curr4 - Zahl mit vier Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## date - Datum in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## int - ganze Zahl  in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## ld - Key einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ldv - Value einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ls - Key eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## lsv - Value eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## text, text2, text3... - Zeile eines Textes&lt;br /&gt;
# untere Grenze bzw. Name der Nachschlageliste oder des Specials&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $RANDOM(date,01.01.2022,31.12.2022)&lt;br /&gt;
 #coutl $RANDOM(text2)&lt;br /&gt;
&lt;br /&gt;
==$SUBSTR()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Selbe Funktionalität wie $COPY())&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$SUBSTR($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$STREP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string replace&amp;quot;) Ersetzt Zeichen im String durch andere Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, in welchen Zeichen ersetzt werden sollen.&lt;br /&gt;
# Zeichen, die ersetzt werden sollen&lt;br /&gt;
# Zeichen, die an deren Stelle treten sollen&lt;br /&gt;
# optional: Optionen (kombinierbar)&lt;br /&gt;
## i - Groß- und Kleinschreibung ignorieren &lt;br /&gt;
## a - Alle Vorkommen ersetzen (andernfalls wird nur das erste Vorkommen ersetzt)&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=&amp;quot;$STREP($PVAL(vl,1,2), ,_,a)&amp;quot;&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$STREP($PVAL(vl,1,2),$CHR(space),_,a)&lt;br /&gt;
&lt;br /&gt;
Hinweis: Beide Beispiele haben exakt dieselbe Funktion. Im oberen Beispiel steht das Leerzeichen direkt im Text, dafür muss der komplette Parameter in doppelte Anführungszeichen, im unteren Beispiel wird das Leerzeichen durch $CHR(space) eingefügt, dafür können die Leerzeichen unterbleiben.&lt;br /&gt;
&lt;br /&gt;
==$STROP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string operation&amp;quot;) Sammelsurium von String-Operationen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## trim - entfernt führende und folgende Leerzeichen&lt;br /&gt;
## trimleft - entfernt führende Leerzeichen&lt;br /&gt;
## trimright - entferne folgende Leerzeichen&lt;br /&gt;
## quote - setzt den String in einfache Anführungszeichen&lt;br /&gt;
## unquote - entfernt einschließende einfache Anführungszeichen&lt;br /&gt;
## dquote - setzt den String in doppelte Anführungszeichen&lt;br /&gt;
## unqduote - entfernt einschließende doppelte Anführungszeichen&lt;br /&gt;
## ex_filepath - entspricht der Delphi-Funktion ExtractFilePath&lt;br /&gt;
## ex_filedir - entspricht der Delphi-Funktion ExtractFileDir&lt;br /&gt;
## ex_filedrive - entspricht der Delphi-Funktion ExtractFileDrive&lt;br /&gt;
## ex_filename - entspricht der Delphi-Funktion ExtractFileName&lt;br /&gt;
## ex_fileext - entspricht der Delphi-Funktion ExtractFileExt&lt;br /&gt;
# String, der bearbeitet werden soll&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$STROP(quote,Test)&lt;br /&gt;
&lt;br /&gt;
==$STREXTR()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string extract&amp;quot;) Extrahiert einen Teil aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem extrahiert werden soll&lt;br /&gt;
# Extraktionstyp&lt;br /&gt;
## ffe (&amp;quot;from first exclude&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## ffi (&amp;quot;from first include&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tfe (&amp;quot;to first exclude&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tfi (&amp;quot;to first include&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## fle (&amp;quot;from last exclude&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## fli (&amp;quot;from last include&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tle (&amp;quot;to last  exclude&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tli (&amp;quot;to last include&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Trennzeichen&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffe,;)&amp;quot;    -- Ergebnis: test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffi,;)&amp;quot;    -- Ergebnis: ;test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfe,;)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfi,;)&amp;quot;    -- Ergebnis: test;&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;!§§test2,tfe,;!§§)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
&lt;br /&gt;
==$TRIM()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Leerzeichen und Zeilenumbrüche am Rand des Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der getrimmt werden soll&lt;br /&gt;
# optional&lt;br /&gt;
## L - trimmt nur auf der linken Seite&lt;br /&gt;
## R - trimmt nur auf der rechten Seite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$TRIM($VAL(1),R)&lt;br /&gt;
&lt;br /&gt;
==$UPP()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Großbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Großbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $UPP($EDT(edt1)) = BUS&lt;br /&gt;
&lt;br /&gt;
==$VT()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VT (&amp;quot;Value Translate&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Vergleichswert 1&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 1 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 2&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 2 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 3&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 3 dem ersten Parameter entspricht &lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VT(Frau,1,Herr,2,Frau,3)&lt;br /&gt;
 -- Frau -&amp;gt; 3&lt;br /&gt;
 -- Herr -&amp;gt; 2&lt;br /&gt;
 -- Test -&amp;gt; 1&lt;br /&gt;
 -- Firma -&amp;gt; 1&lt;br /&gt;
&lt;br /&gt;
==$VTVL()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VTVL (&amp;quot;Value Translate ValueList&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu $VT werden die zu prüfenden Werte und deren Entsprechungen nicht über Parameter übergeben, sondern aus einer Werte-Liste geholt, die in einem Text gespeichert sein muss.&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich wie folgt aufbauen&lt;br /&gt;
&lt;br /&gt;
 key1=value1&lt;br /&gt;
 key2=value2&lt;br /&gt;
 key3=value3&lt;br /&gt;
 key4=value4&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich auch mit #sql_opentvl erzeugen, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Nummer des Textes, in dem sich die Werteliste befindet.&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select userid as ckey, shortname as cvalue from user_user&lt;br /&gt;
 #sql_opentvl n=1&lt;br /&gt;
 #coutl $VTVL(591,(nicht gefunden),1)&lt;br /&gt;
&lt;br /&gt;
==$XR()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $XR (&amp;quot;XmlReplace&amp;quot;) ersetzt in XML nicht zulässige Zeichen:&lt;br /&gt;
* aus &amp;amp; wird $amp ;&lt;br /&gt;
* aus &amp;lt; wird &amp;amp;lt ;&lt;br /&gt;
* aus &amp;gt; wird &amp;amp;gt ;&lt;br /&gt;
* aus &amp;quot; wird &amp;amp;quot ;&lt;br /&gt;
* aus ' wird &amp;amp;apos ;&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Das Leerzeichen vor dem Semikolon soll verhindern, dass die Zeichen hier in der Darstellung ersetzt werden und wird nicht eingefügt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text &amp;lt;firmenname&amp;gt;$XR($DATA(dat,firmenname))&amp;lt;/firmenname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==$XRR()==&lt;br /&gt;
&lt;br /&gt;
Umkehrfunktion von $XR()&lt;br /&gt;
* aus $amp ; wird &amp;amp;&lt;br /&gt;
* aus &amp;amp;lt ; wird &amp;lt;&lt;br /&gt;
* aus &amp;amp;gt ; wird &amp;gt;&lt;br /&gt;
* aus &amp;amp;quot ; wird &amp;quot;&lt;br /&gt;
* aus &amp;amp;apos ; wird '&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
=Integer-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben eine ganze Zahl zurück&lt;br /&gt;
&lt;br /&gt;
==$DEC()==&lt;br /&gt;
&lt;br /&gt;
Verringert die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die verringert werden soll.&lt;br /&gt;
# optional: Zahl, um die verringert werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$DEC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ICALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit ganzzahligen Werten durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator, es stehen zur Verfügung&lt;br /&gt;
## +&lt;br /&gt;
## -&lt;br /&gt;
## *&lt;br /&gt;
## div&lt;br /&gt;
## mod&lt;br /&gt;
# Erste Zahl&lt;br /&gt;
# Zweite Zahl&lt;br /&gt;
# optional beim Operator +: weitere Summanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$ICALC(mod,17,5)&lt;br /&gt;
&lt;br /&gt;
==$INC()==&lt;br /&gt;
&lt;br /&gt;
Erhöht die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die erhöht werden soll.&lt;br /&gt;
# optional: Zahl, um die erhöht werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$INC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$INTLEN()==&lt;br /&gt;
&lt;br /&gt;
Ist der String im Parameter eine ganz Zahl, dann wird deren Länge in Zeichen zurückgegeben, andernfalls -1; ein leerer String im ersten Parameter ergibt 0.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, deren Länge ermittelt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTLEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Länge eines Strings in Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Länge ermittelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEVENSHTEIN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Levenshtein-Distanz (https://de.wikipedia.org/wiki/Levenshtein-Distanz) der beiden übergebenen Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# erster String&lt;br /&gt;
# zweiter String&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $LEVENSHTEIN(alpha,beta)&lt;br /&gt;
&lt;br /&gt;
==$POS()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Position des Substrings in einem String. Das Funktionsergebnis ist die Position, das erste Zeichen ist 1. 0 wird zurück gegeben, wenn der Substring im String nicht vorkommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Substring (nach dem gesucht wird)&lt;br /&gt;
# String (in dem gesucht wird)&lt;br /&gt;
# optional: Wenn ic (ignore case), dann wird bei der Suche die Groß- und Kleinschreibung nicht beachtet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $POS($EDT(edt1),$VAR(1),ic) &amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert zwischen der oberen und unteren Grenze&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ&lt;br /&gt;
## int - zufällige Ganzzahl &lt;br /&gt;
## date - zufälliges Datum &lt;br /&gt;
## curr - zufällige Zahl mit zwei Nachkommastellen&lt;br /&gt;
## curr4 - zufällige Zahl mit vier Nachkommastellen&lt;br /&gt;
## text1, text2, text3... - zufällige Zeile aus dem jeweiligen Text; text ist text1; untere und obere Grenze bleiben unberücksichtigt&lt;br /&gt;
## ld - zufälliger Schlüssel-Wert aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ldv - zufälliger Text aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ls - zufälliger Schlüssel-Wert aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## lsv - zufälliger Text aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
# untere Grenze&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $RANDOM(int,1,6)&lt;br /&gt;
&lt;br /&gt;
=Datumsfunktionen=&lt;br /&gt;
&lt;br /&gt;
==$INCDATE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktione  $INCDATE() verändert das Datum im ersten Parameter um die Anzahl Tage im zweiten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das verändert werden soll&lt;br /&gt;
# optional: Die Tage, um die verändert werden soll; wenn leer, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCDATE($NOW(),-3)   clr=Y&lt;br /&gt;
&lt;br /&gt;
==$INT2TIME()==&lt;br /&gt;
&lt;br /&gt;
Macht aus z.B. 1130 die Zeit 11:30&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zeit im Integer-Format&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_time=$INT2TIME($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$NOW()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit im Format dd.mm.yyyy hh:mm:ss zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #execsql   k_datechg=$NOW()&lt;br /&gt;
&lt;br /&gt;
==$NOWFMT()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und/oder die aktuelle Uhrzeit im angegebenen Format zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Formatierungsstring (Syntax wie FormatDateTime in Delphi)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$NOWFMT(yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$NOWMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit ohne Sekunden (also dd.mm.yyyy hh:mm) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$NOWMIN()&lt;br /&gt;
&lt;br /&gt;
==$TODAY()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum im Format dd.mm.yyyy zurück.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Wenn das Datum in einem anderen Format benötigt wird, ist $NOWFMT() das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$TODAY()&lt;br /&gt;
&lt;br /&gt;
==$DFMT()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;date formated&amp;quot;) Formatiert das übergebene Datum. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, ggf. mit Uhrzeit, das formatiert werden soll.&lt;br /&gt;
# Formatierungsstring wie in Delphi&lt;br /&gt;
# optional: Wenn hn (&amp;quot;hide null&amp;quot;), dann wird ein leerer String zurück gegeben, wenn das Datum kleiner/gleich 1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$DFMT($NOW(),yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Bool'sche Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
==$BFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert einen bool'schen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'scher Wert&lt;br /&gt;
# optional: Ergebnis, wenn Wert Y ('y', 'J', 'j', '1') ist, default Y&lt;br /&gt;
# optional: Ergebnis, wenn Wert N (also nicht 'Y', 'y', 'J', 'j', '1') ist, default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cout   c=$BFMT($VAR(test),x,)&lt;br /&gt;
&lt;br /&gt;
==$BOOL()==&lt;br /&gt;
&lt;br /&gt;
Wertet das bool'sche Statement im Parameter aus.&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
* = gleich&lt;br /&gt;
* == gleich ohne Berücksichtigung der Groß- und Kleinschreibung&lt;br /&gt;
* &amp;lt;&amp;gt; ungleich&lt;br /&gt;
* != ungleich&lt;br /&gt;
* &amp;gt; größer&lt;br /&gt;
* &amp;gt;= größer gleich&lt;br /&gt;
* &amp;lt; kleiner&lt;br /&gt;
* &amp;lt;= kleiner gleich &lt;br /&gt;
* and Und-Verknüpfung&lt;br /&gt;
* or ODER-Verknüpfung&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Statements werden von links nach rechts ausgewertet, and und or sind gleichwetig, gegebenenfalls müssen Klammern eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'sches Statement, das ausgewertet wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL((17 &amp;gt; 22) or (5 &amp;gt; 3))&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL(17 &amp;gt; 22 or 5 &amp;gt; 3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATECOMP()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn Datum 2 Operator Datum 1 zutreffend ist. Ansonsten wird N zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Wird kein Operator angegeben, dann wird die Anzahl der Tage Datum 2 - Datum 1 als Zahl zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum 1&lt;br /&gt;
# Datum 2&lt;br /&gt;
# Operator&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024,&amp;lt;)&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATEMINREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMINREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEMAXREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMAXREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in ein Datum wandeln lassen, werden zu 0 (30.12.1899) konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter diesem Datum entspricht. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;Test $DATEBETWEEN($TODAY(),1.1.2020,2.2.2022)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$EMPTY()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Parameter ein leerer String ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTY($DATE(n,grpname))&lt;br /&gt;
&lt;br /&gt;
==$EMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable ein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTYVAR(buchungsnr)&lt;br /&gt;
&lt;br /&gt;
==$IN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INIC() beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die erste Anweisung gibt Y und die zweite N zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INIC()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $IN() nicht beachtet beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen geben Y zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$ISCURR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen Currency-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISCURR($DATA(n,rechnungssumme))&lt;br /&gt;
&lt;br /&gt;
==$ISDATE()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in ein Datums- oder DatumsZeit-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Prüfoperation, default ist date&lt;br /&gt;
## date - prüft, ob in ein Datum gewandelt werden kann&lt;br /&gt;
## datetime - prüft, ob in ein Datums-Zeit-Wert gewandelt werden kann&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISDATE($DATA(n,beginn))&lt;br /&gt;
&lt;br /&gt;
==$ISINT()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen ganzzahligen Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISINT($DATA(n,tage))&lt;br /&gt;
&lt;br /&gt;
==$INTMAX()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMAX($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$INTMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMIN($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$NEMPTY()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;not empty&amp;quot;) Gibt Y zurück, wenn der Parameter nicht leer ist. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalt geprüft wird. Leerzeichen gelten als leerer String.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 &lt;br /&gt;
 ~ $NEMPTY($EDT(edt1))&lt;br /&gt;
&lt;br /&gt;
==$NEMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable kein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $NEMPTYVAR(kundennr)&lt;br /&gt;
&lt;br /&gt;
==$NOT==&lt;br /&gt;
&lt;br /&gt;
Invertiert einen bool'schen Wert. Aus Y (y, J, j, 1) wird N und aus N wird Y.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der invertiert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $NOT(2)&lt;br /&gt;
&lt;br /&gt;
==$NUMBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in eine Zahl wandeln lassen, werden zu 0 konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter dieser Zahl entspricht. Siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56,)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die beiden Beispiele unterscheiden sich auf den ersten Blick kaum. Bei der ersten Zeile muss jedoch eine Schuhgröße eingegeben werden. Bleibt das Feld im VL-Segment leer, so wird dieser fehlende Wert nach 0 konvertiert und liegt nicht zwischen 28 und 56.&lt;br /&gt;
&lt;br /&gt;
Anders bei der zweiten Zeile: Das Komma vor der schließenden Klammer sorgt für einen vierten Parameter, der ebenfalls leer ist und damit nach 0 gewandelt wird. Auf diese Weise werden die leere Eingaben (und die Eingabe von 0) gültig.&lt;br /&gt;
&lt;br /&gt;
==$REGEX()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $REGEX() (&amp;quot;regular expressions&amp;quot;) prüft, ob der String in Parameter 1 den Anforderungen von Parameter 2 entspricht (Ergebnis Y) oder nicht (Ergebnis N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft werden soll&lt;br /&gt;
# Regulärer Ausdruck, mit dem der String in Parameter 2 geprüft wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $REGEX($VAR(med),^[A-Z]{3}$)&lt;br /&gt;
&lt;br /&gt;
==$TEXT_HASLINE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $TEXT_HASLINE() prüft, ob die als Parameter 2 übergebene Textzeile in einem Text vorkommt. Es wird nur auf komplette Textzeilen geprüft. Wird zum Beispiel verwendet, um eine Liste von Kundennummern zu erstellen, und dann auf einzelne Nummern zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# Textzeile, deren Vorkommen geprüft wird&lt;br /&gt;
# Ergebnis, wenn die Textzeile vorkommt; default Y&lt;br /&gt;
# Ergebnis, wenn die Textzeile nicht vorkommt; default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $TEXT_HASLINE(1,990000018,1,0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$VIBAN()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VIBAN() (&amp;quot;validate IBAN&amp;quot;) prüft eine IBAN anhand der Prüfziffern (3. und 4. Stelle).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# IBAN, die geprüft werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VIBAN(DE12345)&lt;br /&gt;
&lt;br /&gt;
=Currency-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==$CCALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit Festkommawerten durch&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
** + - Addition&lt;br /&gt;
** - - Subtraktion&lt;br /&gt;
** * - Multiplikation&lt;br /&gt;
** / - Division&lt;br /&gt;
** % - Division und Multiplikation des Ergebnisses mit 100&lt;br /&gt;
** +4 - Addition und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** -4 - Subtraktion und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** *4 - Multiplikation und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** /4 - Division und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** %4 - Division, Multiplikation des Ergebnisses mit 100 und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
** B, b, B4, b4 - Bruttobetrag, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** E, e, E4, e4 - Enthaltene MWSt, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** M, m, M4, m4 - MWSt, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** N, n, N4, n4 - Nettobetrag, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator&lt;br /&gt;
# und weitere: Operanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 10&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(+,1,2,3,4)&amp;quot;&lt;br /&gt;
 -- Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #val_set   n=1   z=1038,87&lt;br /&gt;
 #coutl $CCALC(N,$VAL(1),19)  -  $CCALC(E,$VAL(1),19)  -&lt;br /&gt;
&lt;br /&gt;
==$CURR()==&lt;br /&gt;
&lt;br /&gt;
Currency-Werte müssen in Funktionen mit einem Punkt als Dezimaltrennzeichen eingegeben werden, da das Komma die Parameter trennt. Sofern Konstanten verwendet werden, lässt sich das einfach so eingeben, sobald aber die Werte aus anderen Funktionen kommen (zum Beispiel $DATA()), müssen sie dann mit $CURR() in dieses Format umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Vorkommastellen&lt;br /&gt;
# Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 43,48&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,$CURR(2,3))&amp;quot;&lt;br /&gt;
 -- zum Vergleich; Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert Curreny-Werte&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert&lt;br /&gt;
# optional: Formatierungsstring, default 0.00&lt;br /&gt;
# optional: wenn hn (&amp;quot;hide null&amp;quot;), dann werden leere Strings als Wert auch als leerer String ausgegeben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=###,###,###,##0.00&lt;br /&gt;
 #val_set   n=2   z=1337,42&lt;br /&gt;
 #cout   c=$CFMT($VAL(2),$VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ONLYNUM()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass in einem String nur Zahlen (ggf. auch Kommas oder Punkte) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl&lt;br /&gt;
# Art der Operation; default numkomma&lt;br /&gt;
## flnnc (&amp;quot;from last not numeric character&amp;quot;) - Ab dem letzten Zeichen, das keine Ziffer ist&lt;br /&gt;
## num - Nur Ziffern, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numkomma - Nur Ziffern und Kommata, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numpoint - Nur Ziffern und Punkte, alle anderen Zeichen werden entfernt&lt;br /&gt;
## ufnnc (&amp;quot;until first not numeric character&amp;quot;) - vom Anfang bis zum ersten Zeichen, das keine Ziffer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 -- Ergebnis 123456&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,num)&lt;br /&gt;
 -- Ergebnis 123&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,ufnnc)&lt;br /&gt;
 -- Ergebnis 456 &lt;br /&gt;
 #coutl   $ONLYNUM(123-456,flnnc)&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_Form&amp;diff=22517</id>
		<title>Modul Form</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_Form&amp;diff=22517"/>
		<updated>2025-03-28T14:28:21Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* #vl_line */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Das Modul Form=&lt;br /&gt;
&lt;br /&gt;
Im Modul Form werden die Routinen zur zur Formulargestaltung zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
=Das Formular=&lt;br /&gt;
&lt;br /&gt;
==#frm==&lt;br /&gt;
&lt;br /&gt;
Legt ein Formular an. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift des Formulars; Funktionen werden ersetzt &lt;br /&gt;
* flt (&amp;quot;Filter&amp;quot;) - Setzt das Filter-Kommando des Formulars. Dieses Kommando wird aufgerufen, wenn in einer der edt- oder chk-Komponenten eine Eingabe gemacht wird. Kann auch mit #filter ausgelöst werden.&lt;br /&gt;
* lhc (&amp;quot;LogHideCommand&amp;quot;) - Wenn Y, dann wird der Typ C (&amp;quot;Command&amp;quot;) nicht geloggt. Das kann bei Massenverarbeitung den Vorgang beschleunigen; Default N, Funktionen werden ersetzt.&lt;br /&gt;
* ncd (&amp;quot;no confirmation dialog&amp;quot;) - Wenn Y, dann wird beim Typ console kein Bestätigungsdialog verwendet. Das kann zum Beispiel dann sinnvoll sein, wenn ohnehin zu Beginn Daten per Dialog abgefragt werden und damit ggf. die Ausführung abgebrochen werden kann. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* prc (&amp;quot;PageRefreshCommand&amp;quot;) - Das Kommando, mit dem die Seite aktualisiert werden kann; nur bei Typ ''page''&lt;br /&gt;
* w (&amp;quot;Width&amp;quot;) - Breite der Baum-Komponente beim Typ treegrid und Höhe der Baum-Komponente bei treeovergrid&lt;br /&gt;
* y - Typ des Formulars; default ist treepage&lt;br /&gt;
** console - Eine Konsolen-Anwendung, bei der nur Ausgaben in Textform gemacht werden&lt;br /&gt;
** live - Oben ein Eingabefeld zur Eingabe von Kommandos, unten ein Ausgabebereich; wird nur für xlive verwendet. &lt;br /&gt;
** page - Eine Page-Komponenten, darüber ein Filter-Bereich&lt;br /&gt;
** treeoverpage - Von oben nach unten: Filter-Bereich, Baum, Button-Bereich, Page&lt;br /&gt;
** treepage - Links eins Baum-Komponente, rechts eine Page-Komponente, darüber einer Filter- und ein Button-Bereich; ist er Default-Wert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm   c=xlookup   flt=xlookup_flt   w=300&lt;br /&gt;
&lt;br /&gt;
==#cout==&lt;br /&gt;
&lt;br /&gt;
Gibt Text auf der Konsole aus. Wird bei den Form-Typen ''console'' und ''live'' verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Text der ausgegeben wird; Funktionen werden ersetzt; default ist ''#cout, Parameter c nicht gesetzt''&lt;br /&gt;
* cn (&amp;quot;Caption no double function&amp;quot;) - beim Parameter c werden zweimal Funktionen ersetzt, das erlaubt Funktionen von Funktionen (also zum Beispiel eine Funktion, die mittels $DATA aus einer Datenbank geladen wird). Bisweilen führt dieses Verhalten zu unerwünschten Ergebnissen, siehe unten im Beispiel. Wird statt c der Parameter cn verwendet, werden Funktionen nur einmal ersetzt.&lt;br /&gt;
* clr (&amp;quot;Clear&amp;quot;) - Y löscht vor der Ausgabe des Textes die Konsole; Funktionen werden ersetzt; default N&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - die maximale Anzahl der Zeilen; werden es mehr Zeilen, wird ab md gelöscht. Default MaxInt, Funktionen werden ersetzt&lt;br /&gt;
* md (&amp;quot;max delete&amp;quot;) - wenn wegen Überschreitung der mit m vorgegebenen Grenze Zeilen gelöscht werden, werden sie aber dieser Position gelöscht. Auf diese Weise kann erreicht werden, dass der Anfang eines Logs stehen bleibt, zum Beispiel, damit man sieht, wann die Ausführung eines Kommandos begonnen wurde. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* wts (&amp;quot;WithoutTimeStamp&amp;quot;) - Wenn Y, dann wird auf die Ausgabe der Datums- und Zeitangabe sowie des Typs verzichtet; Funktionen werden ersetzt; default N&lt;br /&gt;
* y - Typ der Ausgabe, üblicherweise ein einzelner Buchstabe (I &amp;quot;Info&amp;quot;, W &amp;quot;Warning&amp;quot; E &amp;quot;Error&amp;quot;); default I&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout  c=&amp;quot;Hello world&amp;quot;   &lt;br /&gt;
 #cout  c=&amp;quot; &amp;quot;   clr=Y   wts=Y&lt;br /&gt;
 &lt;br /&gt;
 #cout c=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
 #cout cn=DIR$CHR(dollar)RWC:2740_GFI_5555.pdf&lt;br /&gt;
&lt;br /&gt;
==#coutl==&lt;br /&gt;
&lt;br /&gt;
Fügt der Konsole eine Zeile ohne Datums- und Zeitangabe sowie ohne Typ hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#coutl hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird der Konsole hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl Hello World&lt;br /&gt;
&lt;br /&gt;
==#filter==&lt;br /&gt;
&lt;br /&gt;
Ruft das Standard-Filter-Kommando des Formulars auf. #filter wird meist ohne Parameter aufgerufen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (Field) - Wenn hier der Name eines Feldes angegeben wird, dann wird vor der Ausführung des Filter-Statements der Wert dieses Feldes in der NodeIni ermittelt. Nach der Ausführung des Filter-Statements wird dann der erste Baumeintrag selektiert, dessen Feldinhalt übereinstimmt. Dieses Parameter wird dazu verwendet, nach der Aktualisierung des Baums an dieselbe Stelle zurückzukehren. Dazu sollte der betreffende Baumeintrag eine GUID haben, die auch in der NodeIni steht, und die vom Filter-Statement (und nicht erst durch ein Open-Statement) geladen wird. Funktionen werden ersetzt.&lt;br /&gt;
* o (Open) - Wenn Y, wird der über den Parameter f selektierte Baumeintrag geöffnet. Default N, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filter&lt;br /&gt;
 #btns_btn  c=Filter   w=150   cmd=&amp;quot;#filter   f=data_list_id   o=Y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#save==&lt;br /&gt;
&lt;br /&gt;
Speichert alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #save&lt;br /&gt;
&lt;br /&gt;
==#cancel==&lt;br /&gt;
&lt;br /&gt;
Verwirft alle Änderungen auf der Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cancel&lt;br /&gt;
&lt;br /&gt;
=Dialoge=&lt;br /&gt;
&lt;br /&gt;
==#msg / #message==&lt;br /&gt;
&lt;br /&gt;
Gibt eine Meldung über ein Dialogfenster aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #msg c=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#progress_dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Fortschrittsdialog an, mit dem die Ausführung einer Schleife auch abgebrochen werden kann.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Prozeduren lassen sich über den Fortschrittsdialog abbrechen:&lt;br /&gt;
* #sql_open&lt;br /&gt;
* #loop&lt;br /&gt;
* #csv_paste&lt;br /&gt;
* #sepline&lt;br /&gt;
* #text_loop&lt;br /&gt;
* #xml_loop&lt;br /&gt;
* #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* acmd (&amp;quot;abort command&amp;quot;) - Kommando, das im Falle eines Abbruchs dann noch ausgeführt wird&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das ausgeführt wird&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* max - Die Gesamtzahl der Schleifendurchläufe (ohne Abbruch), Bezugspunkt (100%) für den Fortschrittsbalken; Funktionen werden ersetzt&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
[[file:progress.png|Fortschrittsdiakig]]&lt;br /&gt;
&lt;br /&gt;
Ein einfaches Konsolen-Programm, das die Tabelle cache_buchungen ausliest und den Inhalt von zwei Spalten ausgibt. Zunächst wird die Gesamtzahl ermittelt, damit die nach max geschrieben werden kann. #cmd2 ist ein lokales Kommando, das im Falle des Abbruchs ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
In #progress_dlg werden an die Caption c einige Leerzeichen angehängt, damit der Dialog breit genug dargestellt wird.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #sql select count(*) as cnt from cache_buchungen&lt;br /&gt;
 #sql_openval   f_cnt=1&lt;br /&gt;
 &lt;br /&gt;
 #cmd2 #coutl Vorgang abgebrochen&lt;br /&gt;
 &lt;br /&gt;
 #progress_dlg   cmd=c_test_cmd   title=Fortschritt   max=$VAL(1)   acmd=2   c=&amp;quot;Ausgeführte Datensätze:                                  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die Routine c_test_cmd führt die SQL-Abfrage aus und führt für jeden Datensatz das lokale Kommando #cmd aus. Dieses gibt die Daten auf der Konsole aus und erhöht den Fortschrittdialog.&lt;br /&gt;
&lt;br /&gt;
 #cmd #coutl $DATA(dat,customernumber) - $DATA(dat,servicecode)&lt;br /&gt;
 #cmd #progress   c=&amp;quot;Ausgeführte Datensätze:  &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from cache_buchungen&lt;br /&gt;
 #sql_open   n=dat   er=1   m_=3&lt;br /&gt;
&lt;br /&gt;
==#progress==&lt;br /&gt;
&lt;br /&gt;
Erhöht den Wert des Fortschritt-Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
siehe #progress_dlg&lt;br /&gt;
&lt;br /&gt;
==#dlg==&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Kommando als Dialog an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das aufgerufen wird&lt;br /&gt;
* d (&amp;quot;definition&amp;quot;) - Unter diesem Wert werden die Positionsdaten des Dialogs gespeichert (und wiederhergestellt); Funktionen werden ersetzt&lt;br /&gt;
* ini - Nummer der Ini-Datei, die an den Dialog übergeben und von dort wieder zurückgenommen wird. Über diese Ini-Datei können quasi beliebig viele Daten ausgetauscht werden. (Der Dialog läuft in einem anderen Interpreter, ein Zugriff auf die Daten des aufrufenden Interpreters ist nicht möglich.)&lt;br /&gt;
* n (&amp;quot;name&amp;quot; oder &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in dem das Ergebnis des Dialogs übergeben wird. Das Ergebnis des Dialogs ist üblicherweise Y oder N, abhängig davon, ob der Dialog mit einer Aktion geschlossen oder abgebrochen wird. Die eigentlichen Daten werden dann mittels der Ini-Datei übergeben.&lt;br /&gt;
* title - Titel des Dialogs, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #ini_val   n=1   i=pnr_number   z=$PVAL(vl,pnr_number)&lt;br /&gt;
 #cmd #ini_val   n=1   i=datum   z=$PVAL(umbuchen,datum)&lt;br /&gt;
 #cmd #ini_val   n=1   i=preis   z=$PVAL(vl,totalprice)&lt;br /&gt;
 #cmd #dlg   title=&amp;quot;Umbuchungsanfrage&amp;quot;  d=xverleg_dlg   cmd=xverleg_dlg   n=1   ini=1&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Umbuchungsanfrage stellen&amp;quot;   w=210   cmd=1&lt;br /&gt;
&lt;br /&gt;
==#dlg_close==&lt;br /&gt;
&lt;br /&gt;
Schließt einen Dialog&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Wert, der als Ergebnis des Dialogs zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #ini_val   n=1   i=adrnr   z=$PVAL(vl,adrnr)&lt;br /&gt;
 #cmd #dlg_close   z=Y&lt;br /&gt;
 &lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=&amp;quot;Kundennummer übernehmen und Dialog schließen&amp;quot;   w=350   cmd=1&lt;br /&gt;
&lt;br /&gt;
==$DLG_YESNO==&lt;br /&gt;
&lt;br /&gt;
Zeigt einen Dialog an, der mit Yes (Funktionsergebnis Y) oder No (Funktionsergebnis N) beantwortet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Titel des Dialogs&lt;br /&gt;
# Beschriftung des Dialogs&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DLG_YESNO(frei gewählter Titel,da steht ein beliebiger Text)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Die einfachen Komponenten=&lt;br /&gt;
&lt;br /&gt;
==#btn==&lt;br /&gt;
&lt;br /&gt;
Fügt einen Button in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando des Buttons, wenn s nicht gesetzt ist&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Buttons&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich der Button eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für den Button wird eine neue Zeile begonnen&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando des Buttons&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
* y (&amp;quot;type&amp;quot;) - wenn einer der folgenden Standard-Werte verwendet wird, dann erhält der Button ein Standard-Verhalten und die Parameter c und w bleiben unberücksichtigt. &lt;br /&gt;
** back - Button mit Back-Symbol (Pfeil nach links)&lt;br /&gt;
** cancel - Button mit Cancel-Symbol (Daumen nach unten)&lt;br /&gt;
** export - Button mit Export-Symbol&lt;br /&gt;
** fwd - Button mit Forward-Symbol (Pfeil nach rechts)&lt;br /&gt;
** import - Button mit Import-Symbol&lt;br /&gt;
** pdf - Button mit PDF-Symbol&lt;br /&gt;
** save - Button mit Disketten-Symbol&lt;br /&gt;
** xls - (Schreibt den Seiteninhalt in eine Excel-Datei; noch nicht implementiert)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=save   s=#save  se=c&lt;br /&gt;
 #btn  y=cancel   s=#cancel  se=cf&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=backback   s=#tree_fwd  se=b&lt;br /&gt;
 #btn  y=export   s=xlookup_eximport(ex)  se=b&lt;br /&gt;
 #btn  y=import   s=xlookup_eximport(im)  se=b&lt;br /&gt;
 #btn  c=$T(Add_list)  w=120  s=xlookup_add(list)  se=b&lt;br /&gt;
&lt;br /&gt;
==#chk==&lt;br /&gt;
&lt;br /&gt;
Fügt eine Checkbox in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung der Checkbox&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text der Checkbox&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich die Checkbox eingefügt wird.&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* n - Name der Checkbox, wird benötigt, um mit $EDT() auf den Check-Status zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für die Checkbox wird eine neue Zeile begonnen&lt;br /&gt;
* z - Wert der Checkbox (Y oder N)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==#edt==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Edit-Feld in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cy (&amp;quot;character type&amp;quot;) - Groß- und Kleinschreibung, default n&lt;br /&gt;
** l - lower case&lt;br /&gt;
** n - normal&lt;br /&gt;
** u - upper case&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Edit-Felds&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Edit-Feld eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* l (&amp;quot;length&amp;quot;) - maximale Länge; default unbegrenzt, Funktionen werden ersetzt&lt;br /&gt;
* n - Name des Edit-Feldes, wird benötigt, um mit $EDT() auf den Inhalt zugreifen zu können&lt;br /&gt;
* nl (&amp;quot;NewLine&amp;quot;) - Für das Edit-Feld wird eine neue Zeile begonnen&lt;br /&gt;
* sf (&amp;quot;SetFocus&amp;quot;) - Wenn Y, wird der Eingabefokus auf dieses Edit-Feld gesetzt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ, spezifiziert, welche Eingaben zulässig sind; default text, &lt;br /&gt;
** int&lt;br /&gt;
** curr, curr4&lt;br /&gt;
** date, datemin, datesec&lt;br /&gt;
** text&lt;br /&gt;
* z - Inhalt des Edit-Feldes&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #lbl   c=$T(lookup_filter)   w=140  &lt;br /&gt;
 #edt   n=edt1   w=135   h=&amp;quot;Hier den Text eingeben, nach dem gesucht werden soll.&amp;quot;   z=$INI(usr,edt1,xlookup)&lt;br /&gt;
&lt;br /&gt;
==#lbl==&lt;br /&gt;
&lt;br /&gt;
Fügt ein Label in den Button- oder den Filterbereich ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Labels&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Mouse-Over-Text des Labels&lt;br /&gt;
* p (&amp;quot;parent&amp;quot;) - legt fest, in welchem Bereich das Label eingefügt wird; default f&lt;br /&gt;
** b - Button-Bereich&lt;br /&gt;
** f - Filter-Bereich&lt;br /&gt;
* nl (&amp;quot;new line&amp;quot;) - Für das Label wird eine neue Zeile begonnen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$EDT()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Wert einer Edit- oder Checkbox-Komponente zurück. Eine Checkbox gibt Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Edit- oder Checkbox-Komponente&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
 #filltreesql   k_kuerzel=$EDT(edt1)&lt;br /&gt;
&lt;br /&gt;
=Tree=&lt;br /&gt;
&lt;br /&gt;
Der Tree ist eine Baumansicht, in welcher die einzelnen Einträge hierarchisch gegliedert werden können.&lt;br /&gt;
&lt;br /&gt;
Die Einträge können aus Tabelleninhalten und SQL-Statements gefüllt werden, es können auch einzelne Einträge hinzugefügt werden. Der Baum muss nicht von Anfang an komplett aufgebaut werden, sondern es können Inhalte beim Öffnen eines Eintrags dynamisch nachgeladen werden.&lt;br /&gt;
&lt;br /&gt;
Der gängigste Weg, einen Baum zu füllen, ist #tree_fillsql. Siehe Beispiel dort.&lt;br /&gt;
&lt;br /&gt;
==#tree_clear==&lt;br /&gt;
&lt;br /&gt;
Macht den Tree leer. Wird üblicherweise eingesetzt, bevor der Baum (neu) gefüllt wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #tree_clear&lt;br /&gt;
&lt;br /&gt;
==#tree_add==&lt;br /&gt;
&lt;br /&gt;
Für dem Baum einen einzelnen Eintrag hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* tf (&amp;quot;tree focus&amp;quot;) - wenn Y, wird der Eingabefokus nach Aufruf des Kommandos im Parameter s auf den Baum gesetzt. Default Y, Funktionen werden ersetzt. Muss auf N gesetzt werden, wenn im Kommando des Parameters s eine Seite gefüllt und dabei eine Zelle eines Grids selektiert werden soll. Siehe Beispiele&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #addtree   u=root   c=$T(change_passwort)   s=&amp;quot;#page_fill   d=xsettings_page_password&amp;quot;&lt;br /&gt;
 #addtree   u=root   c=$T(Set_language)   s=&amp;quot;#page_fill   d=xsettings_page_language&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #addtree  u=sel   c=$T(new_list)   t=data_list    s=&amp;quot;#page_fill  d=xlookup_page_list&amp;quot;   si=Y    f_category=$FND(category)&lt;br /&gt;
&lt;br /&gt;
 #tree_add   u=o   c=Angebote   s=&amp;quot;#page_fill   d=xbus_page_angebote&amp;quot;   tf=N&lt;br /&gt;
&lt;br /&gt;
==#tree_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten einer Datenbanktabelle. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der Parameter qw und qo kann das Ergebnis gefiltert und sortiert werden, es ist aber stets nur eine Ebene im Baum. Sollen mehrere Ebenen im Baum gefüllt werden, so ist die Prozedur #tree_fillsql das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
Üblicherweise wird das SQL-Statement aus den Parameters t, qw und qo zusammengesetzt. Dabei sind die Parameter qw und qo optional. Fehlen Sie, lautet das SQL-Statement SELECT * FROM tabllenname.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch mit #sql das Statement vorgegeben werden (zum Beispiel, wenn ein JOIN gebraucht wird). Dann werden die Parameter qw und qo nicht berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird nach dem Füllen des Baums der erste Eintrag selektiert. Default N, Funktionen werden ersetzt. &lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl der Baumeinträge, die erstellt werden&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* si (&amp;quot;select item&amp;quot;) - der neue Eintrag soll nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sii (&amp;quot;select item instantly&amp;quot;) - der neue Eintrag soll sofort und nicht erst nach Abschluss des Kommandos selektiert werden&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #filltree  u=exp   t=test_test   c1=zahl  c2=test_1&lt;br /&gt;
&lt;br /&gt;
==#tree_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #tree_node legt für #tree_fillsql und #tree_fillpath eine Ebenen-Definition an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - die Beschriftung des Eintrags&lt;br /&gt;
* c1, c2 (&amp;quot;caption&amp;quot;) - die Feldnamen in der Datenmenge, aus welcher die erste und zweite Beschriftung geladen werden&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* ld1, ld2, ls1, ls2 - sind die Feldnamen in der Datenmenge Schlüsselwerte für Nachschlagelisten, so können für die Beschriftung die Klartexte genutzt werden. Dazu muss die Nachschlageliste (ld1, ld2) beziehungsweise das Special (ls1, ls2) angegeben werden.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - das Schlüsselfeld für den Eintrag; wird dieser Parameter nicht gesetzt, dann wird das Schlüsselfeld aus dem Namen der Tabelle abgeleitet; Funktionen werden ersetzt&lt;br /&gt;
* nc (&amp;quot;node clear&amp;quot;) - Werden Einträge auf mehreren Ebenen angelegt, dann müssen meist bei einem Wechsel auf der übergeordneten Ebene die Werte der Ebenen darunter gelöscht werden. Mit nc=Y passiert eben dies.&lt;br /&gt;
* ne (&amp;quot;node expand&amp;quot;) - der neue Eintrag soll gleich expandiert werden.&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag expandiert wird; üblicherweise werden dabei Bauminhalte dynamisch nachgeladen.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition für den Eintrag&lt;br /&gt;
* s (&amp;quot;select&amp;quot;) - Kommando, das ausgeführt wird, wenn der Eintrag selektiert wird; üblicherweise wird dabei eine neue Seite geladen.&lt;br /&gt;
* sn (&amp;quot;special node&amp;quot;) - wenn Y, wird der Eintrag gekennzeichnet und kann mit u=spec referenziert werden; Funktionen werden ersetzt&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle; Funktionen werden ersetzt&lt;br /&gt;
* u - Übergeordneter Eintrag. Unter diesem Eintrag wird der neue Eintrag eingefügt.&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
Siehe #tree_fillsql&lt;br /&gt;
&lt;br /&gt;
==#tree_fillsql==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus den Werten eines SQL-Statements. Es können dabei Einträge auf mehreren Ebenen angelegt werden. Die einzelnen Ebenen sind mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Quelle der Daten; default ist sql. (Relevant, wenn weitere Datenquellen hinzugefügt werden.)&lt;br /&gt;
** sql - Das mit #sql erstellte SQL-Statement.&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle. Wird benötigt, wenn Werte in den Baum zurück geschrieben werden sollen.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select *    from data_special      order by category, name;&lt;br /&gt;
 #tree_node  u=root     k=category  c1=category   nc=Y   s=&amp;quot;#fillgrid  d=xspecial_page_category&amp;quot;&lt;br /&gt;
 #tree_node  u=last     t=data_special     c1=name     s=&amp;quot;#fillgrid  d=xspecial_page_list&amp;quot;  &lt;br /&gt;
 #tree_fillsql   mex=3&lt;br /&gt;
&lt;br /&gt;
 #sql select l.*    from data_list l  &lt;br /&gt;
 #sql    left outer join data_list_item i          on l.data_list_id = i.data_list_id&lt;br /&gt;
 #sql    left outer join translate_list_item t     on i.data_list_item_id = t.data_list_item_id &lt;br /&gt;
 #sql  where upper(l.name) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(i.value) like upper(:kedt)&lt;br /&gt;
 #sql     or upper(t.value) like upper(:kedt)&lt;br /&gt;
 #sql  order by l.name;&lt;br /&gt;
 #tree_node  u=root     t=data_list     c1=name     s=&amp;quot;#fillgrid  d=xlookup_page_list&amp;quot;   o=xlookup_open(list)&lt;br /&gt;
 #tree_fillsql   kedt=$EDT(edt1)%   mex=3&lt;br /&gt;
&lt;br /&gt;
==#tree_fillpath==&lt;br /&gt;
&lt;br /&gt;
Füllt den Baum aus der Pfad-Spalte eines SQL-Statements. Die Ebene ist mit #tree_node zu definieren.&lt;br /&gt;
&lt;br /&gt;
Das SQL-Statement kann mit #sql definiert werden, aber auch mit t, qw und qo zusammengesetzt werden. Das SQL-Statement muss nach dem Pfad sortiert sein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* fi (&amp;quot;first item&amp;quot;) - Wenn Y, wird der erste hinzugefügte Eintrag anschließend selektiert. Default ist N, Funktionen werden ersetzt.&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Die Parameter im SQL-Statement beginnen nach den Konventionen mit :k. Da keine weitere Parameter mit k beginnen, werden so Namenskonflikte vermieden. Siehe auch das zweite Beispiel.&lt;br /&gt;
* m (&amp;quot;max&amp;quot;) - Maximale Anzahl von Datensätzen in der Ergebnismenge, aus denen Baumeinträge erstellt werden&lt;br /&gt;
* mex (&amp;quot;max expand&amp;quot;) - Wenn die Zahl der hinzugefügten Einträge der obersten Ebene unter dieser Zahl liegt, dann werden die Einträge expandiert. Default 0.&lt;br /&gt;
* pfx (&amp;quot;prefix&amp;quot;) - Dem eigentlichen Pfad vorangehende Zeichenfolge.&lt;br /&gt;
* pn (&amp;quot;path name&amp;quot;) - Name der Pfad-Spalte in der SQL-Abfrage&lt;br /&gt;
* qo (&amp;quot;query order&amp;quot;) - ORDER-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* qw (&amp;quot;query where&amp;quot;) - WHERE-Klausel für das zu erstellende SQL-Statement&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - damit der Einträge dem Baum hinzu gefügt werden, muss zumindest das Leserecht vorliegen. Default sind die Rechte des Formulars.&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - der Tabellenname der für den Eintrag maßgeblichen Tabelle&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #sql select g.* from user_group g  where g.type = 'G'  order by path&lt;br /&gt;
 #tree_node  u=exp    t=user_group    c1=path     s=&amp;quot;#fillgrid  d=xuser_page_group&amp;quot;&lt;br /&gt;
 #tree_fillpath   t=user_group   pn=path&lt;br /&gt;
&lt;br /&gt;
==#tree_fillthread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt den Baum durch Daten aus einem Thread. Wird üblicherweise dazu verwendet, Daten aus einer anderen Datenbank zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbank, default ist die Default-Datenbank&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; in der Ini des Baums (Sektion DATA) muss es einen Eintrag mit diesem Feldnamen geben.&lt;br /&gt;
* u - Der übergeordnete Knoten, unterhalb dessen der Thread den Baum ergänzt; default r, Funktionen werden ersetzt &lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
** sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
** spp&lt;br /&gt;
** sppp&lt;br /&gt;
** o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
** lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
** lpp&lt;br /&gt;
** lppp&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
** spec (&amp;quot;special&amp;quot;) - Der Eintrag wird unter denjenigen Eintrag gehängt, der mit sn=Y als ''special node''  gekennzeichnet wurde.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql  select vorname || ' ' || nachname as kname from asd where adrnr = :adrnr&lt;br /&gt;
 #tree_fillthread   u=o   k=adrnr   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
==#tree_sel==&lt;br /&gt;
&lt;br /&gt;
Selektiert einen Eintrag.&lt;br /&gt;
&lt;br /&gt;
Bei den Typen rf, sf, rfa und sfa wird im Baum nach einem bestimmten Wert (oder zwei bestimmten Werten) durchsucht. An jedem Eintrag hängt eine Ini-Datei, in der verschiedene Werte gespeichert sind. Es wird dann der erste Eintrag selektiert, in dessen Ini-Feld f der Wert z steht. Die Groß- und Kleinschreibung wird dabei ignoriert.&lt;br /&gt;
&lt;br /&gt;
Neben f und z können auch noch f2 und z2 gesetzt werden. Bei rf und sf sind diese beiden Suchkriterien (f/z und f2/z2) oder-verknüpft. Die Typen rf und sf werden auch bei nur einem Suchkriterium verwendet, da bei einer oder-Verknüpfung das Ergebnis und damit die Existenz eines zweiten Suchkriteriums egal ist. Mit rfa und sfa werden die Suchkriterien und-verknüpft.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - nur wenn true, wir die Anweisung ausgeführt. Default true, Funktionen werden ersetzt.&lt;br /&gt;
* f, f2 (&amp;quot;field&amp;quot;) - der erste und zweite Feldname (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - wenn Y, wird der nach der Selektierung selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* op (&amp;quot;open paretns&amp;quot;) - wenn Y, werden nach der Selektierung alle übergeordneten Einträge des selektierten Eintrag expandiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* sic (&amp;quot;search in children&amp;quot;) - wnn Y, werden auch die Unterknoten durchsucht; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Prozedur&lt;br /&gt;
** c (&amp;quot;child&amp;quot;) - geht zum ersten untergeordneten Eintrag&lt;br /&gt;
** cc (&amp;quot;childchild&amp;quot;) - geht zum ersten untergeordneten Eintrag des ersten untergeordneten Eintrags&lt;br /&gt;
** ccc - geht in der Hierarchie drei Stufen nach unten&lt;br /&gt;
** cccc - geht in der Hierarchie vier Stufen nach unten&lt;br /&gt;
** ccccc - geht in der Hierarchie fünf Stufen nach unten&lt;br /&gt;
** p (&amp;quot;parent&amp;quot;) - geht zum direkt übergeordneten Eintrag&lt;br /&gt;
** pp (&amp;quot;parentparent&amp;quot;) - geht zum übergeordneten Eintrag des übergeordneten Eintrags&lt;br /&gt;
** ppp - geht in der Hierarchie drei Stufen nach oben&lt;br /&gt;
** pppp - geht in der Hierarchie vier Stufen nach oben&lt;br /&gt;
** ppppp - geht in der Hierarchie fünf Stufen nach oben&lt;br /&gt;
** rf (&amp;quot;rootfind&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** rfa (&amp;quot;rootfindand&amp;quot;) - Sucht im kompletten Baum, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sf (&amp;quot;selectedfind&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft&lt;br /&gt;
** s (&amp;quot;selected&amp;quot;) - Selektiert den selektierten Eintrag erneut, ruft damit das Selektionskommando erneut auf&lt;br /&gt;
** sas (&amp;quot;selected asynchronous&amp;quot;) - wie y=s, nur dass die Prozedur leicht verzögert über einen Timer aufgerufen wird, damit aufrufende Funktionalität bereits abgearbeitet ist. Übernimmt o, op und wsc.&lt;br /&gt;
** sfa (&amp;quot;selectedfindand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft&lt;br /&gt;
** sfo (&amp;quot;selectedfindopen&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind oder-verknüpft; zuvor wird der Eintrag expandiert&lt;br /&gt;
** sfoa (&amp;quot;selectedfindopenand&amp;quot;) - Sucht unterhalb des selektierten Eintrags, die Suchkriterien sind und-verknüpft; zuvor wird der Eintrag expandiert; funktioniert auch als sfao&lt;br /&gt;
* wsc (&amp;quot;without select command&amp;quot;) - Wenn Y, wird der Eintrag selektiert, ohne das Selection-Kommando auszuführen; default N. Wird üblicherweise dann verwendet, wenn mit mehreren #tree_sel-Prozeduren durch den Baum navigiert wird und aus Gründen der Geschwindigkeit dazwischenliegende Seitenaufrufe vermieden werden sollen.&lt;br /&gt;
* z, z2 - der erste und zweite Wert (nur für die Typen rf, sf, rfa und sfa)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#tree_sel  y=sf   f=data_list_id   z=7B0EC22C-8526-4FDB-8D10-0187ECF793C0   sic=Y&amp;quot;  se=b&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #tree_sel   y=c   o=Y&lt;br /&gt;
 #cmd #tree_sel   y=c&lt;br /&gt;
 #segbuttons  &lt;br /&gt;
 #segbutton  c=Test  w=150   cmd=1&lt;br /&gt;
&lt;br /&gt;
Im zweiten Beispiel soll in der Hierarchie zwei Stufen nach unten gegangen werden. Eigentlich würde das mit dem Typ cc gehen. Allerdings wird die unterste Ebene hier dynamisch nachgeladen, so dass eine Suche mit dem Typ cc ins Leere laufen würde. Die Lösung ist, zunächst mit dem Typ c eine Stufe nach unten zu gehen, dabei mit o=Y den Node zu expandieren und dabei dynamisch nachzuladen und dann mit dem Typ c eine weitere Stufe nach unten zu gehen.&lt;br /&gt;
&lt;br /&gt;
==#tree_back==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt zurück, also zum davor selektierten Eintrag.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_fwd==&lt;br /&gt;
&lt;br /&gt;
Geht in die Baum-Historie einen Schritt weiter. Kann zur aufgerufen werden, wenn zuvor zurück gegangen wurde.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  y=back   s=#tree_back  se=b&lt;br /&gt;
 #btn  y=fwd   s=#tree_fwd  se=b&lt;br /&gt;
&lt;br /&gt;
==#tree_clearnode==&lt;br /&gt;
&lt;br /&gt;
Entfernt als Unter-Einträge des aktuellen Baum-Eintrags. Kann dazu verwendet werden, um einen Zweig des Baums neu aufzubauen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$FND()==&lt;br /&gt;
&lt;br /&gt;
Sucht in der Ini-Datei des mit dem ersten Parameter spezifizierten Baum-Eintrags nach dem im zweiten Parameter übergebenen Feld und gibt dessen Inhalt zurück. Wird in der Ini-Datei kein entsprechender Eintrag gefunden, dann wird der Vorgang in den übergeordneten Einträgen so lange wiederholt, bis ein Eintrag mit diesem Feldnamen gefunden wurde oder es keine übergeordneten Einträge mehr gibt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Eintrag im Tree&lt;br /&gt;
## s (&amp;quot;selected&amp;quot;) - der selektierte Baum-Eintrag&lt;br /&gt;
## sp (&amp;quot;selected parent&amp;quot;) - Der übergeordnete Eintrag des selektierten Eintrags&lt;br /&gt;
## spp&lt;br /&gt;
## sppp&lt;br /&gt;
## o (&amp;quot;opening&amp;quot;) - der Baum-Eintrag, der gerade expandiert wird.&lt;br /&gt;
## l (&amp;quot;last&amp;quot;) - der zuletzt eingefügt Baum-Eintrag&lt;br /&gt;
## lp (&amp;quot;last parent&amp;quot;) - Der übergeordnete Eintrag des zuletzt eingefügten Eintrags&lt;br /&gt;
## lpp&lt;br /&gt;
## lppp&lt;br /&gt;
## r (&amp;quot;root&amp;quot;) - Der übergeordnete Eintrag der obersten Ebene&lt;br /&gt;
# Feldname (Name des Eintrags in der Ini-Datei)&lt;br /&gt;
# optional: NULL-Value-Wert, also Ergebniswert, wenn der Inhalt des Feldes leer sein sollte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grddata  q=sql   t=data_list   k_cat=$FND(s,category)&lt;br /&gt;
&lt;br /&gt;
=Page=&lt;br /&gt;
&lt;br /&gt;
==#page==&lt;br /&gt;
&lt;br /&gt;
Das Kommando #page setzt einige Eigenschaften auf Seiten-Ebene. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* asc (&amp;quot;after save command&amp;quot;) - Kommando, das ausgeführt wird, nachdem die Seite gespeichert wurde; Funktionen werden ersetzt&lt;br /&gt;
* bsc (&amp;quot;before save command&amp;quot;) - Kommando, das ausgeführt wird, bevor die Seite gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* n - Name der Page; kann mit $PAGE() dann ermittelt werden&lt;br /&gt;
* rar (&amp;quot;refresh after return&amp;quot;) - wenn von dem Tab auf einen anderen gesprungen wird, und dieser Tab wird geschlossen, dann wird die Page aktualisiert, sofern rar=Y. Beim Formulartyp ''treepage'' wird das Selektionskommando des selektierten Baumeintrags neu aufgerufen, beim Formulartyp ''page'' wird das Kommando im Parameter rar der Prozedur #frm angegeben.&lt;br /&gt;
* ras (&amp;quot;refresh after save&amp;quot;) - wenn Y, wird die Seite nach dem Speichern erneut geladen; default N, Funktionen werden ersetzt&lt;br /&gt;
* tac (&amp;quot;tab caption&amp;quot;) - setzt die Beschriftung des jeweiligen Tabs des BAF-Clients; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Seite; default ist ''normal''&lt;br /&gt;
** dashhor&lt;br /&gt;
** dashvert&lt;br /&gt;
** normal&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 #page   asc=&amp;quot;#tree_clearnode&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_fill==&lt;br /&gt;
&lt;br /&gt;
Füllt die Page neu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Das Kommando, das ausgeführt wird, um die Seite aufzubauen. (Alternativ d)&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #tree_fill   u=root   t=devtext   c1=name   f_parent=!   s=&amp;quot;#page_fill   d=xdevtext_page_text&amp;quot;  o=xdevtext_open   fi=Y&lt;br /&gt;
&lt;br /&gt;
==#page_prim / #prim==&lt;br /&gt;
&lt;br /&gt;
Seiten werden zunächst in Primärregionen unterteilt (die keine sichtbaren Elemente haben), die Primärregionen wiederum in die Kategorien, und diese wiederum in die Sektionen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Wenn Y, wird die Größe der Primärregion dem Inhalt angepasst; default Y, Funktionen werden ersetzt&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #prim  &lt;br /&gt;
 #prim  as=N  sz=500&lt;br /&gt;
&lt;br /&gt;
==#page_cat / #cat==&lt;br /&gt;
&lt;br /&gt;
Legt eine Kategorie an. Zuvor muss eine Primärregion angelegt worden sein. #page_cat und #cat sind äquivalente Bezeichner für dieselbe Prozedur.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung der Kategorie&lt;br /&gt;
* as (&amp;quot;AutoSize&amp;quot;) - Die Größe der Primärregion wird dem Inhalt angepasst&lt;br /&gt;
* o (&amp;quot;opened&amp;quot;) - wenn Y, dann wird die Kategorie geöffnet erzeugt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* oci (&amp;quot;open close ini&amp;quot;) - Wenn ein Wert gesetzt ist, wird der Open/Close-Status in der User-Ini gespeichert und beim nächsten Aufruf der Seite so wiederhergestellt. Dem Parameter oci wird der Name des Eintrags in der Ini-Datei zugewiesen; Funktionen werden ersetzt.&lt;br /&gt;
* sz (&amp;quot;size&amp;quot;) - Größe der Primärregion in Pixel&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cat  as=N   sz=360   c=$T(Languages)   oci=lamguages&lt;br /&gt;
&lt;br /&gt;
==#page_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Page, genauer gesagt in das mit i bezeichnete Segment. Zusätzlich oder alternativ kann eine Zelle selektiert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Text-, Memo- und Picture-Segmenten werden nur die Parameter i und z benötigt und beachtet. Die VL, Grid- und XGrid-Segmenten muss die Spalte und die Reihe spezifiziert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Picture-Segmenten wird die Eigenschaft Filename geschrieben, sie sollten q=file haben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Verändert die Beschriftung des Segments&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird mit der Änderung die Zelle auf Changed gesetzt; default Y; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;Condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* col (&amp;quot;Column&amp;quot;) - Index der Spalte, in welche der Wert geschrieben wird; wenn nicht gesetzt, dann wird der Parameter f verwendet&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Feldname der Zelle oder der Spalte, in welche der Wert geschrieben wird; wird nur verwendet, wenn col nicht gesetzt ost&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Segments, in welches der Wert geschrieben wird&lt;br /&gt;
* ie (&amp;quot;if empty&amp;quot;) - Wenn Y, wird der Wert nur in die Zelle geschrieben, wenn diese leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* inr (&amp;quot;ignore next row&amp;quot;) - Wenn über #page_val eine Zelle selektiert wird, die Prozedur aber über ein chg-Kommando desselben Grids aufgerufen wird, wird durch die Return-Taste die nächste Reihe selektiert und nicht diejenige, die über #page_val selektiert wurde. Um das zu vermeiden, wird inr auf Y gesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* row - Index der Reihe, in die geschrieben wird. Alternativ sind bei Grid-Segmenten folgende Reihenbezeichnungen möglich:&lt;br /&gt;
** all - der Wert wird in alle Reihen geschrieben&lt;br /&gt;
** allsel (&amp;quot;all selected&amp;quot;) - der Wert wird in alle Reihen geschrieben, die mit der in der Prozedur #grd_seg mit der Parameter sc (&amp;quot;selection column&amp;quot;) spezifizierten Zelle selektiert wurden&lt;br /&gt;
** looprow - die in der Ausführung der Prozedur #grd_loop gerade aktive Reihe&lt;br /&gt;
** sel (&amp;quot;selected&amp;quot;) - die aktuell selektierte Reihe&lt;br /&gt;
* sr (&amp;quot;segment refresh&amp;quot;) - Wenn Y, wird ein Refresh des Segments durchgeführt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt, default val&lt;br /&gt;
** allcol - Es werden alle Spalten auf Übereinstimmung mit dem Parameter f geprüft; wird vor allem in einem X-Grid verwendet&lt;br /&gt;
** sel - Die Zelle wird selektiert und das Grid bekommt den Focus&lt;br /&gt;
** val - Ein Wert wird geschrieben&lt;br /&gt;
** valsel oder selval - Ein Wert wir geschrieben und die Zelle wird selektiert.&lt;br /&gt;
* z - Wert, der geschrieben wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 #page_val   i=erfassen   f=kuerzel   z=   y=valsel   inr=Y&lt;br /&gt;
&lt;br /&gt;
==#page_check==&lt;br /&gt;
&lt;br /&gt;
Um Eingaben zu Validieren, können Checks definiert werden. Diese werden nach Benutzereingaben ausgeführt. Führen diese Checks zu Fehlern, so wird das Speichern der Daten verhindert. Die Fehlerliste wird statt des Trees angezeigt. Mit dem Beseitigen der Fehler oder dem verwerfen der Änderungen wird die Fehlerliste wieder ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text, der beim Scheitern der Prüfung in die Fehlerliste aufgenommen wird.&lt;br /&gt;
* chk (&amp;quot;check&amp;quot;) - Wenn nicht Y, dann gilt die Prüfung als gescheitert; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prüfung ausgeführt; Funktionen werden ersetzt&lt;br /&gt;
* y - Typ des Checks; default e&lt;br /&gt;
** e (&amp;quot;error&amp;quot;) - Fehler&lt;br /&gt;
** n (&amp;quot;none&amp;quot;) - Check wird geprüft, aber nicht angezeigt und verhindert auch nicht da Speichern&lt;br /&gt;
** w (&amp;quot;warning&amp;quot;) - Warnung; wird angezeigt, aber verhindert nicht das Speichern&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Das Passwort muss mindestens 6 Zeichen lang sein&amp;quot;   chk=&amp;quot;$BOOL($LEN($PVAL(vl,1,2)) &amp;gt; 5)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Bestätigung stimmt nicht mit dem Paswort überein&amp;quot;   chk=&amp;quot;$BOOL($PVAL(vl,1,2) = $PVAL(vl,1,3))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#page_ready==&lt;br /&gt;
&lt;br /&gt;
Wird eine Seite nicht über #page_fill erstellt, sondern dadurch, dass das Kommando direkt aufgerufen wird, so müssen die Routinen, welche nach Aufbau der Seite ausgeführt werden müssen, explizit aufgerufen werden; dazu dient #page_ready.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* rs (&amp;quot;resize&amp;quot;) - wenn Y, wird eine Größenänderungs-Nachricht an die Page gesendet, die bisweilen benötigt wird, damit die Seite korrekt aufgebaut wird; default N; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_ready&lt;br /&gt;
&lt;br /&gt;
==$PAGE()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Namen der aktuellen Page.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Art der Wertes; default ist name&lt;br /&gt;
* changecol - Der 0-relative Index der Spalte, in der gerade ein Wert geändert wird&lt;br /&gt;
* changerow - Der 0-relative Index der Reihe, in der gerade ein Wert geändert wird&lt;br /&gt;
* link - LinkValue&lt;br /&gt;
* debuginfos - Infos zum Debugging&lt;br /&gt;
* name - Name der Page&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btn  c=test  w=120  s=&amp;quot;#message  c=$PAGE()&amp;quot;  se=b     h=&amp;quot;Dies ist ein Test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$PVAL()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus der Page&lt;br /&gt;
&lt;br /&gt;
'''Text- und Memo-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Es muss nur der Name des Segments angegeben werden, $PVAL() gibt den kompletten Text zurück.&lt;br /&gt;
&lt;br /&gt;
'''Grid- und XGrid-Segmente'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter Parameter folgt entweder der Index der Spalte (0-relativ, die erste Spalte hat also den Index 0) oder der Feldname der Spalte.&lt;br /&gt;
&lt;br /&gt;
Als dritter Parameter wird 0-relativ der Index der Zeile angegeben, alternativ eine Sonderzeile oder eine Aggregatfunktion.&lt;br /&gt;
&lt;br /&gt;
'''Spaltenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Spaltenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter Index der Spalte oder Feldname, als dritter Parameter der Name der Aggregatfunktion:&lt;br /&gt;
* count - Anzahl der Datensätze&lt;br /&gt;
* sum - Summe der Werte&lt;br /&gt;
* max - Maximum der Werte&lt;br /&gt;
* min - Minimum der Werte&lt;br /&gt;
* avg - Durchschnitt der Werte&lt;br /&gt;
* med - Median der Werte&lt;br /&gt;
* countsel - Anzahl der selektierten Datensätze&lt;br /&gt;
* sumsel - Summe der Werte der selektierten Datensätze&lt;br /&gt;
* maxsel - Maximum der Werte der selektierten Datensätze&lt;br /&gt;
* minsel - Minimum der Werte der selektierten Datensätze&lt;br /&gt;
* avgsel - Durchschnitt der Werte der selektierten Datensätze&lt;br /&gt;
* medsel - Median der Werte der selektierten Datensätze&lt;br /&gt;
* countvis - Anzahl der sichtbaren Datensätze&lt;br /&gt;
* sumvis - Summe der Werte der sichtbaren Datensätze&lt;br /&gt;
* maxvis - Maximum der Werte der sichtbaren Datensätze&lt;br /&gt;
* minvis - Minimum der Werte der sichtbaren Datensätze&lt;br /&gt;
* avgvis - Durchschnitt der Werte der sichtbaren Datensätze&lt;br /&gt;
* medvis - Median der Werte der sichtbaren Datensätze&lt;br /&gt;
&lt;br /&gt;
'''Reihenaggregate'''&lt;br /&gt;
&lt;br /&gt;
Für Grid- und XGrid-Segmente können Reihenaggreagte gebildet werden. Erste Parameter ist der Name des Segments, zweiter Parameter die Funktion, die mit einem Fragezeichen beginnen muss, als dritter Parameter der Index der Reihe beziehungsweise eine Sonderreihe:&lt;br /&gt;
* ?count - Anzahl der Spalten&lt;br /&gt;
* ?sum - Summe der Werte&lt;br /&gt;
* ?max - Maximum der Werte&lt;br /&gt;
* ?min - Minimum der Werte&lt;br /&gt;
* ?avg - Durchschnitt der Werte&lt;br /&gt;
* ?all - Alle Zellenwerte, getrennt durch das Trennzeichen bzw. die Trennzeichenfolge in Parameter vier.&lt;br /&gt;
&lt;br /&gt;
In einem Grid sind üblicherweise Spalten, für welche die Aggregatfunktion gebildet werden soll, mit anderen Spalten kombiniert. Um diese Spalten unterscheiden zu können, kann der Parameter ''grp'' der Spalte gesetzt werden. Bei der Berechnung der Reihenaggregate wird dann geschaut, ob die Zeichenfolge im fünften Parameter im Parameter ''grp'' der Spalte vorkommt; nur dann wird die betreffende Spalte berücksichtigt. Hinweis: Der Parameter ''grp'' der Spalte kann mehrere Gruppenbezeichner enthalten, wenn die betreffende Spalte für verschiedene Reihenaggregate verwendet wird. Diese können durch frei gewählte Trennzeichen getrennt werden, müssen aber nicht, sofern sie hinreichend unterscheidbar sind. Groß- und Kleinschreibung wird unterschieden.&lt;br /&gt;
&lt;br /&gt;
Im sechsten Parameter kann der Ergebnistyp angegeben werden:&lt;br /&gt;
* bool&lt;br /&gt;
* curr&lt;br /&gt;
* curr4&lt;br /&gt;
* date&lt;br /&gt;
* datemin&lt;br /&gt;
* datesek&lt;br /&gt;
* int&lt;br /&gt;
&lt;br /&gt;
Die Funktion ?count wird jedoch immer als ganze Zahl dargestellt.&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Wie immer muss der Name des Segments als erster Parameter angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Als zweiter und dritter Parameter wird 0-relativ der Index der Spalte und der Zeile angegeben.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann als zweiter Parameter ein Feldname angegeben werden. $PVAL() durchsucht dann alle Reihen und Spalten des VL-Segments nach diesem Feldnamen.&lt;br /&gt;
&lt;br /&gt;
'''Sonderzeilen'''&lt;br /&gt;
&lt;br /&gt;
Statt der Bezeichnung über die Zeilennummer sind auch die folgenden Werte möglich:&lt;br /&gt;
&lt;br /&gt;
* change - die Zeile, in der die gerade geänderte Zelle liegt&lt;br /&gt;
* checkrow - die aktuelle Zeile bei der Ausführung von  $GRD_CHECK&lt;br /&gt;
* calcrow - die Zeile, die gerade bei grd_calc verwendet wird&lt;br /&gt;
* datarow - bezieht sich auf die aktuelle Zeile bei $PVAL&lt;br /&gt;
* data - dieselbe Zeile im Grid wie das Kommando, das in dieser Zeile ausgeführt wird&lt;br /&gt;
* linkrow - die Zeile eines ausgeführten Link-Kommandos&lt;br /&gt;
* lookuplive - die Zeile, die gerade in Lookup-Live verwendet wird&lt;br /&gt;
* looprow - die aktuelle Zeile bei der Ausführung von #grd_loop&lt;br /&gt;
* radio - die mit einem Radio-Button gewählte Zeile; sc des Grid-Segments muss auf diese Spalte zeigen&lt;br /&gt;
* saverow - beim Speichern des Grids die Zeile, die gerade gespeichert wird&lt;br /&gt;
* sel - die selektierte Zeile&lt;br /&gt;
&lt;br /&gt;
'''Sonderwerte'''&lt;br /&gt;
&lt;br /&gt;
Bei Grid-, XGrid- und VL-Segmenten können Sonderwerte ermittelt werden. Es ist als zweiter Parameter ein Ausrufezeichen und als dritter Parameter der Name des Sonderwertes einzugeben:&lt;br /&gt;
* calcrow - der 0-relative Index der aktuellen Reihe bei #grd_calc&lt;br /&gt;
* checkrow - der 0-relative Index der aktuellen Reihe bei Plausibilitätsprüfungen&lt;br /&gt;
* looprow - der 0-relative Index der aktuellen Reihe in #grd_loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
# Name des Segments&lt;br /&gt;
# Spaltenindex (0-relativ) oder Feldname; bei Sonderwerten ein Ausrufezeichen, ''!col'' bezieht sich auf die aktuelle Spalte, Reihenaggregate beginnen mit einem Fragezeichen&lt;br /&gt;
# Reihenindex (0-relativ), alternativ eine Sonderreihe:&lt;br /&gt;
## looprow - aktuelle Reihe in #grd_loop&lt;br /&gt;
## all - es werden alle Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
## allsel - es werden alle selektierten Reihen zurückgegeben, als Trennzeichen wird der vierte Parameter verwendet&lt;br /&gt;
# Trennzeichen(folge), wenn mehrere Zeilen zurückgegeben werden&lt;br /&gt;
# Spaltengruppe, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# Ergebnistyp, wird nur bei Reihenaggreagten gebraucht&lt;br /&gt;
# wenn ''display'', dann wird der angezeigte Text (z.B. bei Nachschlagelisten) verwendet&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #message c=$PVAL(item,value,1)&lt;br /&gt;
 #text $PVAL(item,name,looprow) - $PVAL(item,description,looprow)&lt;br /&gt;
 #clipboard   t=$PVAL(grid,adrnr,all,$CHR(crlf))&lt;br /&gt;
 #grdcol   c1=Summe   y=curr   nd=Y   cmdn=$PVAL(grid,?sum,data,,csum)&lt;br /&gt;
 #xgrd_col   c1=&amp;quot;Gesamt&amp;quot;   w=80   nd=Y   ro=Y   cmd=$PVAL(gridxy,?sum,datarow,,sumc,int)   y=int   a=r   fc1=$PVAL(gridxy,!col,sum)   fa1=r   fy1=int&lt;br /&gt;
&lt;br /&gt;
Wenn Spalten-Aggregate (zum Beispiel Spalten-Summen) von Spalten gebildet werden, die von einem Thread gefüllt werden, dann sind die Daten zu dem Zeitpunkt, zu dem die Summe gebildet wird, noch gar nicht vorhanden. In diesem Fall kann eine erneute Summenbildung angestoßen werden, indem man nach Beendigung des Threads #page_ready aufruft:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=provision   y=curr   w=60   a=d2   c1=&amp;quot;Provision&amp;quot;   q=thread   fc1=$PVAL(grid,!col,sum)   fy1=curr   fa1=d2&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 #sql select provision from rzl where code = :iso_extra_code&lt;br /&gt;
 #grd_thread   k=iso_extra_code   db=pg_prod   ready=#page_ready&lt;br /&gt;
&lt;br /&gt;
==$CCI()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Farbe für eine Zelle anhand eines ganzzahligen Wertes&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert. Wenn !, dann der Wert der Zelle, deren Farbe gerade gesetzt werden soll.&lt;br /&gt;
# Wenn L (lower), dann muss der Wert gleich oder unterhalb des Vergleichswertes sein; andernfalls muss er gleich oder über dem vergleichswert&lt;br /&gt;
# Vergleichswert für die Farbe rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe gelb - wird nur geprüft, wenn die Farbe nicht bereits rot&lt;br /&gt;
# optional: Vergleichswert für die Farbe grün - wird nur geprüft, wenn die Farbe nicht bereits rot oder gelb&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
Wenn die Anzahl der Dubletten 1 oder höher, wird die Farbe der Zelle auf rot gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Segmente=&lt;br /&gt;
&lt;br /&gt;
Eine Page ist in Primär-Regionen, diese in Kategorien und diese wiederum in Segmente eingeteilt.&lt;br /&gt;
&lt;br /&gt;
==Segment-Typen==&lt;br /&gt;
&lt;br /&gt;
'''VL-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein VL-Segment ist ein Grid zur Darstellung und Bearbeitung eines einzelnen Datensatzes. &lt;br /&gt;
&lt;br /&gt;
Das Standard-VL-Segment (VL für &amp;quot;value list&amp;quot;) ist zweispaltig: Links der Namen, rechts der Wert. Es können jedoch auch weitere Spalten ergänzt werden, so dass der zur Verfügung stehende Platz in der Horizontalen besser genutzt werden kann oder dass weitere Werte in unsichtbaren Spalten gespeichert werden können.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht vl seg.png|VL-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein Grid-Segment dient zur Darstellung und Bearbeitung mehrerer Datensätze.&lt;br /&gt;
&lt;br /&gt;
Ein Standard-Grid hat eine Kopfzeile, kann jedoch mehrere Kopf- und Fußzeilen haben.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht grd seg.png|Grid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XGrid-Segment ähnelt einem Grid-Segment. Allerdings besteht hier die Möglichkeit, Reihen einer Tabelle als Spalten zu ergänzen. &lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild gehören alle Spalte bis einschließlich Status zur Tabelle todo_todo, während die folgenden Spalten (und auch die Anzahl der folgenden Spalten) davon abhängt, welche Gruppen dem jeweiligen ToDo-Typ zugeordnet sind.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht xgrd seg.png|XGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''XXGrid-Segment'''&lt;br /&gt;
&lt;br /&gt;
Ein XXGrid-Segment (&amp;quot;Double-X-Grid&amp;quot;) ähnelt einem XGrid-Segment. Allerdings haben wir hier zwei Abfragen, die Spalten liefern.&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild haben wir einerseits die Kategorien für die Stichworte, und dahinter jeweils alle Reisenummern, die bei der betreffenden Reklamation bemängelt wurden. Somit kann schnell und übersichtlich angehakt werden, welches Stichwort für welche Reisenummer zutrifft.&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Button-Segment'''&lt;br /&gt;
&lt;br /&gt;
In ein Button-Segment können mehrere Buttons eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_btns_seg.png|Button-Segment mit zwei Buttons]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Memo-Segment'''&lt;br /&gt;
&lt;br /&gt;
Das Memo-Segment dient zu Anzeige und Bearbeitung von mehrzeiligem Text.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_memo_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Text-Segment'''&lt;br /&gt;
&lt;br /&gt;
Mit einem Text-Segment kann mehrzeiliger Text auf der Seite angezeigt werden. (Die zugrunde liegende Delphi-Komponente ist ein Memo, so dass der Text markiert und in die Zwischenablage kopiert werden kann.)&lt;br /&gt;
&lt;br /&gt;
Text-Segmente werden bisweilen auch einfach dafür eingesetzt, den Abstand zwischen anderen Segmenten zu vergrößern.&lt;br /&gt;
&lt;br /&gt;
[[file:Ssht_text_seg.png|Memo-Segment]]&lt;br /&gt;
&lt;br /&gt;
'''Picture-Segment'''&lt;br /&gt;
&lt;br /&gt;
Zeigt ein Bild an.&lt;br /&gt;
&lt;br /&gt;
==Gemeinsame Parameter aller Segmente==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Parameter können in allen Segmenten genutzt werden:&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann der Anwender die Daten im Segment nicht ändern; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #grd_seg    frc=1   fcc=1   clt=ss   mhc=300   n=test   c=&amp;quot; &amp;quot;   b=HAI   sc=0&lt;br /&gt;
&lt;br /&gt;
==Nachschlagelisten==&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl von Optionen werden häufig Nachschlagelisten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
[[file:Lookupliste.png|172px|Nachschlageliste]]&lt;br /&gt;
&lt;br /&gt;
'''Definierte Nachschlagelisten'''&lt;br /&gt;
&lt;br /&gt;
Mit xlookup können Nachschlagelisten definiert werden. Diese können in xlookup auch in die definierten Sprachen übersetzt werden.&lt;br /&gt;
&lt;br /&gt;
Diese werden dann mit dem Parameter ld eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=status   c1=&amp;quot;Status&amp;quot;   w=80   y=lookup   ld=srv_status&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
Nachschlagelisten können auch mittels SQL-Statement erzeugt werden. Hier gibt es zwei Möglichkeiten. &lt;br /&gt;
&lt;br /&gt;
Zum Einen können diese Statements in xspecial definiert werden. Sie werden dann mit dem Parameter ls eingebunden:&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(Group)   w=300    y=lookup   ls=system_groups_all&lt;br /&gt;
&lt;br /&gt;
Zum Anderen kann das SQL-Statement auch im Quelltext stehen. Das ist insbesondere dann hilfreich, wenn einzelne Werte noch gesetzt werden müssen. Diese Statements müssen mit dem Parameter ld eingebunden werden, dem der Name des SQL-Statements übergeben wird (Statements, die - wie hier im Beispiel - mit #sql2 definiert wurden, werden mit ld=sql2 eingebunden).&lt;br /&gt;
&lt;br /&gt;
 #sql2   select ctype as ckey, name as cvalue from todo_type where ctype like '$CP(0)%'&lt;br /&gt;
 ...&lt;br /&gt;
 xgrd_col   f=ctype   c1=$T(type)   y=lookup   ld=sql2   q=y2   w=150&lt;br /&gt;
&lt;br /&gt;
Beiden Möglichkeiten ist gemeinsam, dass die beiden Spalten mit ckey und cvalue benannt werden müssen. Weitere Spalten sind unschädlich, werden aber ignoriert.&lt;br /&gt;
&lt;br /&gt;
'''Nachschlagelisten aus Text-ValueLists'''&lt;br /&gt;
&lt;br /&gt;
Eine Text-ValueList in eine Value-Liste, die in einem Text (text, text2, text3...) aufgebaut ist nach dem Muster key=value. Die Text-ValueList wird dem Parameter ld als tvl (text), tvl2 (text2), tvl3 (text3) und so weiter zugewiesen. &lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=Lieferant   f2=vendor_id   ro2=Y   nd2=Y   c3=&amp;quot; &amp;quot;   c4=Name   f5=vendor_url   y5=lookup   ld5=tvl2&lt;br /&gt;
&lt;br /&gt;
'''LookupLive'''&lt;br /&gt;
&lt;br /&gt;
Den zuvor erwähnten Möglichkeiten ist gemeinsam, dass alle Nachschlagelisten in einer Spalte stets gleich aussehen. Es können zwar unterschiedliche Werte gewählt werden, aber die Optionen in der Liste sind stets dieselben.&lt;br /&gt;
&lt;br /&gt;
Manchmal benötigt man jedoch unterschiedliche Listen. Als Beispiel sei ein Grid genannt, in dem in einer Spalte eine Reise angegeben oder ausgewählt wird, und in einer anderen Spalte sollen in einer Nachschlageliste die Ausflüge gelistet werden, die zu dieser Reise buchbar sind. Und da die Reisen unterschiedliche Ausflüge haben, und auch unterschiedliche Reisen eingegeben werden können, sieht die Nachschlageliste in jeder Zeile unterschiedlich aus.&lt;br /&gt;
&lt;br /&gt;
So etwas zu bewerkstelligen ist in BAF nicht weiter schwer: Es wird der Typ y=lookuplive verwendet mit mit llc (LookupLiveCommand) ein Kommando (Name oder Nummer) angegeben, das immer dann ausgeführt wird, wenn die Liste geöffnet wird (sowie beim erstmaligen Anzeigen - damit der Wert im Grid korrekt dargestellt werden kann). Mit diesem Kommando wird dann die Nachschlageliste gefüllt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1   &lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird ein lokales Kommando verwendet, das mit #cmd definiert wird. Damit das sicher leer ist, wird es zuvor mit #cmd_clear geleert. Das Kommando ist im Prinzip ein SQL-Statement sowie die Prozedur #grd_lookuplivefill, welche die Nachschlageliste füllt.&lt;br /&gt;
&lt;br /&gt;
LookupLive-Nachschlagelisten wird meist unter Berücksichtigung von anderen Werten in derselben Zeile des Grids gefüllt - also muss auf diese zugegriffen werden. Dafür wird die Funktion $PVAL verwendet, welcher als dritter Parameter - nach Name des Grid und Name oder Nummer der Spalte - der Reihensonderbezeichner ''lookuplive'' mitgegeben wird, so dass immer dieselbe Zeile wie die jeweilige Nachschlageliste verwendet wird.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Bei neu angelegten Zeilen ist die betreffende Zelle in der Regel leer. Von daher wird üblicherweise $NVL eingesetzt, um einen Ersatzwert zu verwenden, damit zumindest das SQL-Statement syntaktisch korrekt ist und auf keine Fehlermeldung läuft. (Hinweis zum Beispiel: Es handelt sich hier um keine kurze Demonstration der Funktionalität ohne praktischen Sinn.)&lt;br /&gt;
&lt;br /&gt;
=Text-, Memo- und Button-Segmente=&lt;br /&gt;
&lt;br /&gt;
==#text_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Text-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Text-Segmente haben nur die gemeinsamen Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#text_line==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Text-Segment eine Zeile hinzu. Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die komplette Zeile nach dem Prozedurennamen und dem folgenden Leerzeichen wird als neue Zeile dem Segment hinzugefügt. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_seg  c=Test&lt;br /&gt;
 #textline Erste Zeile&lt;br /&gt;
 #textline Zweite Zeile&lt;br /&gt;
&lt;br /&gt;
==#memo_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Memo-Segment an, also ein Segment, in dem mehrzeiliger Text bearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Data'''&lt;br /&gt;
&lt;br /&gt;
Mit q=data werden die Texte in der Tabelle data_memo gespiechert. Diese Tabelle ist dafür vorgesehen, mal schnell ein Bemerkungsfeld zu beliebigen Daten hinzuzufügen, ohne die jeweilige Datenbak-Tabelle erweitern zu müssen.&lt;br /&gt;
&lt;br /&gt;
Der Datensatz in data_memo wird mit den Spalten item und ref referenziert. Item wird über den Parameter i gesetzt und ist zwingend. Für ref wird der Parameter k verwendet, der üblicherweise auf die ID-Spalte der Daten gesetzt wird, mit denen das Memo-Feld verbunden werden soll. Bleibt k leer, so wird none als Konstante eingefügt. &lt;br /&gt;
&lt;br /&gt;
'''File'''&lt;br /&gt;
&lt;br /&gt;
Mehrzeiliger Text kann auch einfach in einer Datei auf der Festplatte gespeichert werden. Dazu wird q=file und fn auf den gewünschten Dateinamen gesetzt. Möchte man für unterschiedliche Datensätze unterschiedliche Texte und damit unterschiedliche Dateinamen, so holt man einfach die ID oder eine andere eindeutige Spalte mit in den Dateinamen.&lt;br /&gt;
&lt;br /&gt;
'''Link'''&lt;br /&gt;
&lt;br /&gt;
Zellen in VL- und Grid-Segmente können problemlos mehrzeiligen Text speichern, sie können ihn aber nicht brauchbar anzeigen und bearbeiten. Mit q=link lässt sich ein Memo-Segment an ein VL- oder Grid-Segment hängen, so dass mehrzeiliger Text dort im Memo-Segment angezeigt und bearbeitet wird. Der Parameter i referenziert auf das VL- oder Grid-Segment, mit f wird die Datenbankspalte angegeben. Mit w=0 wird üblicherweise die entsprechende Spalte im VL- oder Grid-Segment ausgeblendet.&lt;br /&gt;
&lt;br /&gt;
In einem Grid-Segment wird der Feldinhalt der gerade aktuellen Zeile angezeigt. Bei einem Zeilenwechsel ändert sich dann auch der Inhalt der Memo-Segments.&lt;br /&gt;
&lt;br /&gt;
Datenänderungen werden über das VL- oder Grid-Segment gespeichert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - bei q=link der Feldname im verbundenen Segment&lt;br /&gt;
* fn (&amp;quot;file name&amp;quot;) - Dateiname, wird für q=file verwendet; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Wert für die Spalte ref in data_memo&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - bei q=link Name des Segments, bei q=data der Item-Name; bei letzterem werden Funktionen ersetzt&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Herkunft der Daten&lt;br /&gt;
** data - Daten werden in der Tabelle data_memo gespeichert; benötigt die Parameter i und meist auch k&lt;br /&gt;
** file - Daten werden in einer Datei gespeichert; benötigt den Parameter fn&lt;br /&gt;
** link - Daten werden in einem anderen Segment gespeichert; benötigt die Parameter i und vl&lt;br /&gt;
** none - Lädt und speichert keine Daten; der eingegebene Text kann mit $PVAL ermittelt oder mit #page_val gesetzt werden&lt;br /&gt;
* ww (&amp;quot;WordWrap&amp;quot;) - Wenn Y, werden zu lange Zeilen automatisch umgebrochen; default Y, Funktionen werden ersetzt&lt;br /&gt;
* z - Text des Memo-Segments; Wird von den Daten in q gegebenenfalls überschrieben&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
Zusätzlich gibt es die Parameter aller Segmente.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #memo_seg   q=link   i=vl   f=code   c=&amp;quot;Code&amp;quot;   b=H&lt;br /&gt;
 #memo_seg   q=file   fn=i:\temp\test.txt   c=$T(Notes)&lt;br /&gt;
 #memo_seg   q=data   i=memo_reise   k=$PVAL(vl,reise_id)   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
&lt;br /&gt;
==#btns_seg==&lt;br /&gt;
&lt;br /&gt;
Legt ein Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Button-Segmente haben nur die gemeinsamen Parameter aller Segmente. Meist werden überhaupt keine Parameter benötigt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg&lt;br /&gt;
&lt;br /&gt;
==#btns_btn==&lt;br /&gt;
&lt;br /&gt;
Legt einen Button in einem Button-Segment an.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Beschriftung des Buttons; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) -Kommando, das ausgeführt wird, wenn auf den Button geklickt wird (und ggf. die Bestätigungsabfrage mit Ja beantwortet wurde); Funktionen werden ersetzt (zum Zeitpunkt des Buttons-klicks)&lt;br /&gt;
* cnf (&amp;quot;confirmation&amp;quot;) - Beim Mausklick auf den Button wird zunächst ein Bestätigungs-Dialog mit dem im Parameter cnf angegebenen Text angezeigt. Nur wenn dieser Bestätigungs-Dialog mit Ja geschlossen wird, wird cmd ausgeführt. Funktionen werden bei Anzeige des Bestätigungs-Dialogs ersetzt. Ist cnf leer, unterbleibt die Anzeige.&lt;br /&gt;
* h (&amp;quot;hint&amp;quot;) - Hinweistext&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechte-Definition des Buttons; zum Ausführen des Buttons werden Schreibrechte benötigt; default sind die Rechte des Formulars&lt;br /&gt;
* se (&amp;quot;status enabled&amp;quot;) - Je nach Status des Formulars ist der Button enabled oder nicht (es können mehrere Status-Buchstaben in beliebiger Reihenfolge kombiniert werden); Funktionen werden ersetzt&lt;br /&gt;
** b (&amp;quot;browse&amp;quot;) - Normalzustand des Formulars&lt;br /&gt;
** c (&amp;quot;changed&amp;quot;) - Nachdem Daten geändert wurden&lt;br /&gt;
** e (&amp;quot;editing&amp;quot;) - Während einer Editierung&lt;br /&gt;
** f (&amp;quot;failed&amp;quot;) - Die Plausibilitätsprüfung wurde nicht bestanden&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Mit Y wird die Ausführung des Buttons gesperrt; Funktionen werden ersetzt&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite des Buttons&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=$T(Test_special)  w=150   cmd=&amp;quot;#pagefill  d=xspecial_page_list(test)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=VL-Segmente=&lt;br /&gt;
&lt;br /&gt;
VL-Segmente (&amp;quot;Value List&amp;quot;) sind Gitter-Segmente zur Anzeige eines einzelnen Datensatzes.&lt;br /&gt;
&lt;br /&gt;
Im Standard-Fall sind VL-Segmente zweispaltig: Auf der linken Seite wird die Beschriftung angezeigt, auf der rechten Seite der jeweilige Wert des Datensatzes. &lt;br /&gt;
&lt;br /&gt;
VL-Segmente können aber auch mehr als zwei Spalten haben. Das können unsichtbare Spalten sein, um Daten für z.B. ein Memo-Segment zu beinhalten, das können aber auch sichtbare Spalten sein, um den Platz auf dem Bildschirm besser auszunutzen.&lt;br /&gt;
&lt;br /&gt;
==#vl_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #vl_seg wird ein VL-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100   w2=200   wst2=200   w3=200   n=vl   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
&lt;br /&gt;
==#vl_line==&lt;br /&gt;
&lt;br /&gt;
Legt eine Zeile in einem VL-Segment an&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Die Parameter in #vl_line haben als Postfix die Nummer die Spalte, auf die sie sich beziehen.&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* arp1, arp2... (additional right pixels) - Anzahl der Pixel, um welche der Text bei Rechtsausrichtung nac links gerückt wird; default 0, Funktionen werden ersetzt.&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Spalte; Wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc1, ccc2 (&amp;quot;cell color command&amp;quot;) - Kommando, das die Zellenfarbe ermittelt&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cs1, cs2... (&amp;quot;col span&amp;quot;) - Werte größer 1 fügen Zellen zusammen; default 1&lt;br /&gt;
* cy1, cy2... (&amp;quot;char type&amp;quot;)&lt;br /&gt;
** l - LowerCase&lt;br /&gt;
** n - Normal&lt;br /&gt;
** u - UpperCase&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenbank&lt;br /&gt;
* h1, h2... (&amp;quot;hint&amp;quot;) - Feldname in der Datenbank für den Hinweistext, ersatzweise der Hinweistext selbst&lt;br /&gt;
* ld1, ld2... (&amp;quot;lookup data&amp;quot;) - Name der Lookup-Liste, wenn der Datentyp lookup; Alternativ sql1, sql2..., um die Daten aus einem SQL-Statement zu ziehen&lt;br /&gt;
* ls1, ls2... (&amp;quot;lookup special&amp;quot;) - Alternativ zu ld: Name des Specials, wenn die Daten aus einem Special gezogen werden sollen&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* nv1, nv2... (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc1, nvc2... (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi1, nvi2... (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic1, nvic2... (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line   c1=&amp;quot;Name&amp;quot;   f2=name&lt;br /&gt;
 #vl_line   c1=&amp;quot;Type&amp;quot;   f2=type   ro=Y   y2=lookup   ld2=user_group_type   nv2=$FND(s,type)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Data Special Id&amp;quot;   f2=data_special_id   ro2=Y   nvic2=$GUID()   f3=code&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für chg'''&lt;br /&gt;
&lt;br /&gt;
 #cmdclear&lt;br /&gt;
 #cmd #page_val   i=vl   col=1   row=4   z=$HASH($PVAL(vl,1,2),SHA512)&lt;br /&gt;
 ...&lt;br /&gt;
 vl_line   c1=$T(new_password)    nd2=Y     chg2=1   pw2=Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiel für Datenquelle'''&lt;br /&gt;
&lt;br /&gt;
Im Normalfall ist mit einem VL-Segment immer nur eine Tabelle verbunden. Mit Hilfe eines Joins können zwar Daten aus mehreren Tabellen angezeigt werden, aber üblicherweisen werden die Daten nur in eine Tabelle zurück geschrieben, die anderen Zellen sind mit nd=Y gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Sollen Daten jedoch in mehrere Tabellen zurückgeschrieben werden, dann ist das Vorgehen das Folgende:&lt;br /&gt;
&lt;br /&gt;
* Die weiteren Tabellen benötigen eine Schlüsselspalte, welche denselben Inhalt wie die primäre Tabelle hat. Gegebenenfalls muss diese Spalte ergänzt werden. Bei der Benennung dieser Spalte gibt es zwei Möglichkeiten:&lt;br /&gt;
** Die Spalte heißt genau so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_test2 die ID test_test2_id, und die angehängte Tabelle test_test2_add hat auch die ID test_test2_id - und nicht test_test2_add_id).&lt;br /&gt;
** Die Spalte heißt nicht so wie die Schlüsselspalte in der primären Tabelle (hier im Beispiel hat die Tabelle test_add3 die Schlüsselspalte test_add3_id); die bei BAF &amp;quot;übliche&amp;quot; Benennung mit einem angehängten _id wie hier bei test_add3 ist zu bevorzugen.&lt;br /&gt;
* Es wird ein SQL-Statement erstellt, um diese Tabellen zusammenzufügen. Die angehängten Tabellen werden mit einem left outer join verbunden. Dort, wo die ID-Spalten der angehängten Tabellen gleich wie in der primären Tabelle heißen (im Beispiel test_test2_id), werden sie umbenannt (im Beispiel yid).&lt;br /&gt;
* In #vl_data werden die weiteren Tabellen als t2, t3... aufgezählt; hier im Beispiel t2=test_tes2_add und  t3=test_add3. Wo sich der Name der Schlüsselspalte nicht auf dem Tabellennamen ableiten lässt, sind auch die Schlüsselspalten entsprechend anzugeben als k2, k3...; hier im Beispiel k2=yid&lt;br /&gt;
* Die Schlüsselspalten der ergänzten Tabellen sind im VL-Segment zu speichern. Üblicherweise wird dafür eine ausgeblendete Spalte verwendet. &lt;br /&gt;
* Bei jeder Zelle, die in einer der angehängten Tabellen gespeichert werden soll, ist mit dem Parameter q anzugeben, welches die angehängte Tabelle ist. y2 ist t2, y3 ist t3... (hier im Beispiel q2, weil die Daten in der zweiten Spalte der VL-Segments stehen).&lt;br /&gt;
* Dort, wo Schlüsselspalten gleich heißen wie in der primären Tabelle und deswegen im SQL-Statement umbenannt werden müssen (hier im Beispiel yid statt test_test2_id), muss der Spaltenname in der Tabelle mit yf angegeben werden, damit die Daten korrekt zurück geschrieben werden (hier im Beispiel yf3=test_test2_id - die Ziffer 3 bei yf3 bezieht sich auf die (unsichtbare) Spalte im VL-Segment, nicht auf die Nummer der Tabelle)&lt;br /&gt;
* Es ist sicherzustellen, dass alle beteiligten Tabellen dieselben Schlüsselwerte bekommen. Zu diesem Zweck wird im Beispiel die ID der primären Tabelle in den Value 1 geschrieben, ersatzweise wird eine neue GUID verwendet. Dieser Value wird dann mittels nvi in alle Schlüsselfelder geschrieben.&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$FND(s,test_test2_id)   ie=$GUID()&lt;br /&gt;
 &lt;br /&gt;
 #vl_seg  cc=3  clt=ss   w1=100  w2=200   wst2=200  w3=0   n=vl   c=&amp;quot; &amp;quot;  b=H&lt;br /&gt;
 #vl_line   c1=&amp;quot;ID&amp;quot;   f2=test_test2_id   ro2=Y   nvic2=$VAL(1)     f3=yid   yf3=test_test2_id    q3=y2   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Zahl&amp;quot;   f2=zahl   f3=test_add3_id   q3=y3   nvi3=$VAL(1)&lt;br /&gt;
 #vl_line   c1=&amp;quot;Text&amp;quot;   f2=text&lt;br /&gt;
 #vl_line   c1=&amp;quot;Todo&amp;quot;   f2=boolsch   y2=todo&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 1&amp;quot;   f2=add_1     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 2&amp;quot;   f2=add_2     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 3&amp;quot;   f2=add_3     q2=y2&lt;br /&gt;
 #vl_line   c1=&amp;quot;Add 31&amp;quot;   f2=add31     q2=y3&lt;br /&gt;
 #sql select t.test_test2_id, t.zahl, t.text, t.boolsch, a.test_test2_id as yid, a.add_1, a.add_2, a.add_3, b.test_add3_id, b.add31&lt;br /&gt;
 #sql   from test_test2 t&lt;br /&gt;
 #sql     left outer  join test_test2_add a on a.test_test2_id = t.test_test2_id &lt;br /&gt;
 #sql     left outer join test_add3 b on b.test_add3_id = t.test_test2_id &lt;br /&gt;
 #sql   where t.test_test2_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=test_test2      t2=test_test2_add   k2=yid   t3=test_add3   kid=$FND(s,test_test2_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_data==&lt;br /&gt;
&lt;br /&gt;
Füllt ein VL-Segment mit Daten&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Als Prefix für alle SQL-Parameter; siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* kid (&amp;quot;key id&amp;quot;) - bei q=t der Wert der Schlüsselspalte, damit der Datensatz lokalisiert werden kann&lt;br /&gt;
* q (&amp;quot;Quelle&amp;quot;) - Datenherkunft&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** t - Table&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) - Name der Tabelle; obligatorisch bei q=t und wenn bei q=sql die Daten zurückgeschrieben werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... (&amp;quot;table&amp;quot;) weitere Tabellen, in die Daten gespeichert werden sollen; siehe ''Beispiel für Datenquelle'' in #vl_line&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #vl_data   q=t   t=data_list   kid=$FND(s,data_list_id)  &lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :k_menu_category_id&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   k_menu_category_id=$FND(s,menu_category_id)&lt;br /&gt;
 &lt;br /&gt;
 #sql select * from menu_category where menu_category_id = :kid&lt;br /&gt;
 #vl_data   q=sql   t=menu_category   kid=$FND(s,menu_category_id)&lt;br /&gt;
&lt;br /&gt;
==#vl_hist==&lt;br /&gt;
&lt;br /&gt;
Definiert die Rechte für ein Feld in der History-Ansicht. Funktioniert auch mit #grd_seg, #xgrs_seg und #xxgrd_seg&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;field&amp;quot;) - Name der Spalte in der Tabelle&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Name der Rechtedefinition für diese Spalte&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #vl_line  c1=$T(Description)   f2=description   l2=80   r=admin&lt;br /&gt;
 #vl_hist   f=description   r=admin&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel wird durch r=admin in #vl_line dafür gesorgt, dass nur Administratoren die Beschreibung im VL-Segment sehen. Mit der Anweisung #vl_hist wird sichergestellt, dass andere als Administratoren den Spalteninhalt auch nicht über die Historie einsehen können.&lt;br /&gt;
&lt;br /&gt;
==#vl_thread==&lt;br /&gt;
&lt;br /&gt;
Ergänzt Daten mittels eines Thread. Wird üblicherweise dazu verwendet, Daten aus anderen Datenbanken zu ergänzen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden Zellen, die durch den Thread gefüllt werden, als geändert gekennzeichnet; default N, Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des VL-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im VL-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select bezeichnung from rsd where aktion = $PVAL(vl,aktion)&lt;br /&gt;
 #vl_thread   db=ora_prod   i=vl&lt;br /&gt;
&lt;br /&gt;
=Grid-Segmente=&lt;br /&gt;
&lt;br /&gt;
Grid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer Datenbanktabelle oder einer SQL-Abfrage angezeigt werden. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#grd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_seg wird ein Grid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* acmd (add command) - Kommando, das ausgeführt wird, wenn auf den Button + geklickt wird.&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
** A (&amp;quot;active&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf Y; ist das Grid gefiltert, werden nur die gefilterten Zellen gesetzt.&lt;br /&gt;
** F (&amp;quot;filter&amp;quot;) öffnet den Filter-Dialog&lt;br /&gt;
** H (&amp;quot;history&amp;quot;) öffnet den History-Dialog&lt;br /&gt;
** I (&amp;quot;inactive&amp;quot;) setzt in der mit sc spezifizierten Spalten alle Zellen auf N; es werden immer alle Zellen auf N gesetzt, auch wenn sie ausgefiltert sind&lt;br /&gt;
** X (&amp;quot;xlsx&amp;quot;) exportiert das Grid im xlsx-Format&lt;br /&gt;
** Y exportiert das Grid im pdf-Format&lt;br /&gt;
** + führt acmd aus (nur #grd_seg); wird üblicherweise dazu verwendet, einen Datensatz hinzuzufügen&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   mhc=300   n=item&lt;br /&gt;
&lt;br /&gt;
==#grd_col==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #grd_col wird eine Spalte in einem Grid-Segment definiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* a (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* a1, a2... (align) - [Header] Ausrichtung des Textes des Headers der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* arp (additopnal right pixels) - Anzahl der Pixel, welcher der Text bei Rechtsausrichtung weiter nach links gerückt wird; Default 0, Funktionen werden ersetzt&lt;br /&gt;
* c (caption) - Spalten-Titel im Filter-Formular; Funktionen werden ersetzt. Bleibt dieser Parameter leer, so wird ersatzweise c1 verwendet.&lt;br /&gt;
* c1, c2... (caption) - [Header] Spalten-Titel der ersten, zweiten... Zeile; Funktionen werden ersetzt.&lt;br /&gt;
* ccc (CellColorCommand) - Kommando, das die Farbe der Zelle setzt.&lt;br /&gt;
* ci (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* chg (change) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird.&lt;br /&gt;
* cmd (command) - Kommando, zum Beispiel für Verlinkung oder die Formatierung; Funktionen werden sofort ersetzt.&lt;br /&gt;
** no_crlf - Zeilenumbüche werden durch Leerzeichen ersetzt&lt;br /&gt;
** conv_yyyy - Datum im Format yyyymmddhhmmss wird nach dd.mm.yyyy hh:mm:ss und yyyymmdd nach dd.mm.yyyy konvertiert &lt;br /&gt;
* cmdn (command no) - Kommando, zum Beispiel für Verlinkung; Funkionen werden erst bei Ausführung des Kommandos ersetzt; wird nur berücksichtigt, wenn cmd leer ist.&lt;br /&gt;
* cs1, cs2... (ColSpan) - [Header] Die Zelle des Spaltentitels der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* cy (character type) - Groß- und Kleinschreibung; default ist n&lt;br /&gt;
** l (lower case) - Spalte wird in Kleinbuchstaben dargestellt&lt;br /&gt;
** n (normal) - Groß- und Kleinschreibung wie eingegeben&lt;br /&gt;
** u (upper case) - Spalte wird in Großbuchstaben dargestellt&lt;br /&gt;
* f (fieldname) - Feldname der Spalte in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* f1, f2... (fieldname) - [Header] Feldname des Spaltentitels der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter c1, c2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus c1, c2... vorangestellt wird.&lt;br /&gt;
* fa1, fa2... (footer align) - [Footer] Ausrichtung des Textes der Fußzeile der Spalte der ersten, zweiten... Zeile. Zulässige Werte siehe Parameter a.&lt;br /&gt;
* fc1, fc2... (footer caption) - [Footer] Spalten-Fußzeile der ersten, zweiten... Zeile. Ist im Text ein $-Zeichen enthalten, dann wird der Text als Zellen-Kommando interpretiert.&lt;br /&gt;
* fcs1, fcs2... (footer ColSpan) - [Footer] Die Zelle der Fußzeile der ersten, zweiten... Zeile überspannt die angegebene Anzahl an Spalten. Default ist 1; Funktionen werden ersetzt.&lt;br /&gt;
* ff1, ff2... (footer fieldname) - [Footer] Feldname des Fußzeile der ersten, zweiten... Zeile; Funktionen werden ersetzt. Sind auch die Parameter fc1, fc2... gesetzt, dann werden die Texte zusammengefügt, wobei der Text aus fc1, fc2... vorangestellt wird.&lt;br /&gt;
* fh1, fh2... (footer hint) - [Footer] Feldname des Hint-Textes der Spalte der ersten, zweiten... Fußeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* fy1, fy2... (footer Typ) - [Footer] Datentyp des Datentyps der ersten, zweiten... Fußzeile; default ist text. Zulässige Werte siehe y.&lt;br /&gt;
* h (hint) -  Feldname des Hint-Textes in der Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
* h1, h2... (hint) - [Header] Feldname des Hint-Textes der Spalte der ersten, zweiten... Zeile; Funktionen werden ersetzt. Gibt es in der Datenmenge keine Spalte dieses Namens, dann wird der Wert als Konstante ausgegeben.&lt;br /&gt;
* jy (join type) - Im Standardfall werden bei Join-Gruppierung die Daten durch Kommata getrennt dargestellt. Sie können jedoch auch summiert werden, dafür ist jy=sum  zu setzen. &lt;br /&gt;
* l (length) - Maximale Länge in Zeichen bei der Eingabe&lt;br /&gt;
* ld (LookupData) - Name der Nachschlageliste beim Spaltentyp y=lookup&lt;br /&gt;
* llc (LookupLiveCommand) - Name oder Nummer des Kommandos, das beim Spaltentyp y=lookuplive verwendet wird; ls und ls dürfen nicht gesetzt werden&lt;br /&gt;
* ls (LookupSpecial) - Name des Specials (hinterlegte SQL-Anweisung in xspecial), wird nur berücksichtigt, wenn ld nicht gesetzt ist&lt;br /&gt;
* nd (no data) - Spalte wird beim Speichern nicht berücksichtigt; Änderungen versetzen das Grid auch nicht in den Zustand changed.&lt;br /&gt;
* nv (&amp;quot;no value&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist&lt;br /&gt;
* nvc (&amp;quot;no value change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Changed-Modus gesetzt&lt;br /&gt;
* nvi (&amp;quot;no value insert&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment auch in den Insert-Modus gesetzt&lt;br /&gt;
* nvic (&amp;quot;no value insert change&amp;quot;) - Wert, der eingefügt wird, wenn das Feld in der Datenmenge leer ist; dann wird das Segment in den Insert- und Changed-Modus gesetzt&lt;br /&gt;
* q (quelle) - Datenquelle für das Grid.&lt;br /&gt;
** j, join - Daten aus einem Datenbank-Join werden gruppiert dargestellt &lt;br /&gt;
** s, sql - SQL-Statement&lt;br /&gt;
** t, tbl, tab, table - Datenbanktabelle&lt;br /&gt;
* r (right) - Rechtedefinition der Spalte. Sofern nur ein Leserecht vorliegt, wird die Spalte ReadOnly. Sofern kein Recht vorliegt, wird die Spalte ausgeblendet und auch nicht in der Historie angezeigt.&lt;br /&gt;
* ro (ReadOnly) - Wenn Y, dann kann die Spalte nicht beschrieben werden.&lt;br /&gt;
* rof (ReadOnlyField) - Wenn der Inhalte der angegebenen Datenbankspalte Y ist, dann kann die betreffende Zelle nicht beschrieben werden.&lt;br /&gt;
* ss1, ss2... (SortSymbols) - [Header] Mit Mausklick auf den Spaltentitel kann nach dieser Spalte sortiert werden, mit einem weiteren Mausklick die Sortierrichtung umgekehrt werden. Es werden dabei entsprechend Symbole rechts im Spaltentitel angezeigt. Um eine Sortierung zu verhinden, kann ss1, ss2... auf N gesetzt werden. Funktionen werden ersetzt.&lt;br /&gt;
* w (width) - Breite der Spalte in Pixel; Funktionen werden ersetzt.&lt;br /&gt;
* wst (width stretch) - Anzahl von Pixel, welche die Spalte maximal verbreitert wird, wenn Platz dafür da ist. Voraussetzung dafür ist, dass der Parameter clt von #grd_seg den Wert ss oder ms hat. Funktionen werden ersetzt.&lt;br /&gt;
* y (typ) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* xop (xlsx options) - unsortierte Reihenfolge von Optionen für den Excel-Export&lt;br /&gt;
** n  (null) - Ist der Inhalt eines Zahlenfeldes leer, dann wird nicht 0 bzw. 0,00 exportiert, sondern das Feld bleibt auch im xlsx-Export leer&lt;br /&gt;
* xw (xlsx width) - Spaltenbreite, wenn das Segment im Excel-Format exportiert wird; wenn leer, wird statt dessen w verwendet; Funktionen werden ersetzt&lt;br /&gt;
* yf (Y fieldname) - Feldname der Spalte in einer zusätzlichen Datenmenge; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=translate_list_item_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=user_group_id   c1=$T(group)   y=lookup   ls=system_groups_all   w=200   wst=200&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
==#grd_data==&lt;br /&gt;
&lt;br /&gt;
Füllt das Grid mit Daten aus der Dankenbank.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Beschriftung des Segments, wenn der Thread ausgeführt wurde; nur für thread und xmlthread; Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* gc (grid cache) - Erhält dieser Paremeter einen Wert, dann wird das SQL-Statement nur beim erstmaligen Aufruf von #grd_data ausgeführt. Die Daten werden dann in einem Cache gespeichert, so dass erneute Aufrufe weniger lange dauern. Der Inhalt das Parameters wird als Name für die Seite im Cache verwendet und muss eindeutig sein - im Zweifelsfall verwendet man eine GUID. Hinweise: Wenn weitere Spalten der Abfrage und dem Grid hinzugefügt werden, bleiben diese erste mal leer. Auch Veränderungen der Daten durch andere User bleiben erst mal unsichtbar. Ein erneuter Start der BAF-Clients führt zu einem leeren Cache und somit zur erneuten Ausführung des SQL-Statements.&lt;br /&gt;
* ior (insert one row) - Wenn Y, wird eine (leere) Zeile eingefügt, wenn die Datenmenge leer ist; default N; Funktionen werden ersetzt&lt;br /&gt;
* jk (join key) - Feldname der Spalte, nach der bei q=j gruppiert wird&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* mk (&amp;quot;merge key&amp;quot;) - Die Spalte, die das Entscheidungskriterium bei q=merge beinhaltet.&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* q (quelle) - Herkunft der Daten&lt;br /&gt;
** j - Join&lt;br /&gt;
** json - Das Grid wird mit einem geparsten JSON gefüllt&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
** sqladd / add - SQL-Statement, fügt Daten zu einem Grid hinzu; somit können die Daten aus zwei unterschiedlichen SQL-Statements kommen, die ggf. auch auf unterschiedlichen Datenbanken ausgeführt werden können&lt;br /&gt;
** sqlmerge / merge - SQL-Statement, fügt wie ''sqladd'' Daten zu einem Grid hinzu, hier aber unter Berücksichtigung der im Parameter mk spezifizierten Spalte: Ein Datensatz wird nur dann hinzugefügt, wenn es noch keine Zeile mit dem entsprechenden Wert gibt.&lt;br /&gt;
** t - Table&lt;br /&gt;
** thread - ein SQL-Statement wird in einem Hintergrund-Thread ausgeführt&lt;br /&gt;
** xml - Das Grid wird mit einem geparsten XML gefüllt&lt;br /&gt;
** xmlthread - In einem Hintergrundthread wird mit http(s) ein XML geholt, dieses geparst und damit das Grid gefüllt.&lt;br /&gt;
* sc (SaveCommand) - Kommando das ausgeführt wird, wenn das Grid gespeichert werden soll; nur für xml und xmlthread&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grddata   q=sql   t=translate_list_item   kid=$FND(s,data_list_item_id)&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #http_request   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml     $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap&lt;br /&gt;
&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text &amp;lt;soapenv:Envelope xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:web=&amp;quot;http://webservice.xxxxxxxxxxxxxxxxxx.de/&amp;quot;&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Header/&amp;gt;&lt;br /&gt;
 #text    &amp;lt;soapenv:Body&amp;gt;&lt;br /&gt;
 #text       &amp;lt;web:searchCustomer&amp;gt;&lt;br /&gt;
 #text           &amp;lt;searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text          &amp;lt;postalCode&amp;gt;31582&amp;lt;/postalCode&amp;gt;&lt;br /&gt;
 #text          &amp;lt;/searchCustomerRequest&amp;gt;&lt;br /&gt;
 #text       &amp;lt;/web:searchCustomer&amp;gt;&lt;br /&gt;
 #text    &amp;lt;/soapenv:Body&amp;gt;&lt;br /&gt;
 #text &amp;lt;/soapenv:Envelope&amp;gt;&lt;br /&gt;
 #code   url=https://xxxxxxxxxxxxxxxxxx.de/ITAPIWebservice/xxxxxxxxxxInterface?doAgencyLogin&lt;br /&gt;
 #code   e_res=ansi&lt;br /&gt;
 #code   y=post    cy=&amp;quot;application/xml&amp;quot;   request=$TEXT(1)   response=resp   se=Y   acc=application/xml   &lt;br /&gt;
 #grd_data   q=xmlthread    pfx=customer   path=soap:Envelope.soap:Body.ns2:searchCustomerResponse.searchCustomerResponse   sc=xbaftest_save_soap     $CODE$&lt;br /&gt;
&lt;br /&gt;
'''Beispiel Daten aus XML-Array'''&lt;br /&gt;
&lt;br /&gt;
Die Abfrage im folgenden Beispiel gibt ein XML nach dem folgenden Muster zurück:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;contacts&amp;gt;&lt;br /&gt;
   &amp;lt;contact&amp;gt;&lt;br /&gt;
     &amp;lt;email&amp;gt;michael.mustermann@gmail.com&amp;lt;/email&amp;gt;&lt;br /&gt;
     &amp;lt;created&amp;gt;2024-06-14 14:02:48.0&amp;lt;/created&amp;gt;&lt;br /&gt;
     &amp;lt;updated&amp;gt;2024-06-22 14:05:00.0&amp;lt;/updated&amp;gt;&lt;br /&gt;
     &amp;lt;id&amp;gt;123456&amp;lt;/id&amp;gt;&lt;br /&gt;
     &amp;lt;external_id&amp;gt;990000018&amp;lt;/external_id&amp;gt;&lt;br /&gt;
     &amp;lt;permission&amp;gt;5&amp;lt;/permission&amp;gt;&lt;br /&gt;
     &amp;lt;standard_fields&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;FIRSTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Michael&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;LASTNAME&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Mustermann&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
       &amp;lt;field&amp;gt;&lt;br /&gt;
         &amp;lt;name&amp;gt;SALUTATION&amp;lt;/name&amp;gt;&lt;br /&gt;
         &amp;lt;value&amp;gt;Herr&amp;lt;/value&amp;gt;&lt;br /&gt;
       &amp;lt;/field&amp;gt;&lt;br /&gt;
     &amp;lt;/standard_fields&amp;gt;&lt;br /&gt;
     &amp;lt;custom_fields/&amp;gt;&lt;br /&gt;
   &amp;lt;/contact&amp;gt;&lt;br /&gt;
 &amp;lt;/contacts&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anrede sowie Vor- und Nachname sind hier in den Standard-Feldern und können nicht direkt adressiert werden. Hier lautet dann die Syntax für den Spaltenbezeichner wie folgt:&lt;br /&gt;
&lt;br /&gt;
 f=standard_fields.field[name=SALUTATION].value&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=&amp;quot;Alle Maileon-Einträge der Kundennummer $FND(s,customernumber)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #btns_seg&lt;br /&gt;
 #btns_btn  c=&amp;quot;Gewählte Maileon-Einträge unsubscriben&amp;quot;   w=350   cmd=xkudat_act(adrnr)&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   clt=ss   hrc=1   n=adrnr   sc=0&lt;br /&gt;
 #grd_col   c1=Sel   w=30   y=bool   nd=Y&lt;br /&gt;
 #grd_col   c1=ID   f=id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;E-Mail&amp;quot;   f=email   w=200  wst=200   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Adrnr&amp;quot;   f=external_id   w=80   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Anrede&amp;quot;   f=standard_fields.field[name=SALUTATION].value   w=100    ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Vorname&amp;quot;   f=standard_fields.field[name=FIRSTNAME].value   w=150  wst=100   ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=&amp;quot;Nachname&amp;quot;   f=standard_fields.field[name=LASTNAME].value   w=150   wst=100  ro=Y   q=xml&lt;br /&gt;
 #grd_col   c1=E   h1=&amp;quot;Zusendung von E-Mails erlaubt&amp;quot;   f=&amp;lt;permission&amp;gt;   w=30   y=bool   ro=Y  &lt;br /&gt;
 &lt;br /&gt;
 #code   url=https://api.maileon.com/1.0/contacts/externalid/$FND(s,customernumber)?standard_field=FIRSTNAME&amp;amp;standard_field=LASTNAME&amp;amp;standard_field=SALUTATION&lt;br /&gt;
 #code   f_Authorization=&amp;quot;Basic (je nach dem...)&amp;quot;&lt;br /&gt;
 #code   e_res=utf8&lt;br /&gt;
 #http_request   y=get    cy=&amp;quot;application/vnd.maileon.api+xml; charset=utf-8&amp;quot;   response=resp   se=N   $CODE$&lt;br /&gt;
 #xml_parse   xml=$VAR(resp)&lt;br /&gt;
 #grd_data   q=xml    pfx=contact   path=contacts&lt;br /&gt;
&lt;br /&gt;
==#grd_add==&lt;br /&gt;
&lt;br /&gt;
Fügt einem Grid-Segment eine weitere Reihe hinzu.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Primärschlüsselspalte wird üblicherweise nicht in der Prozedur #grd_add gesetzt, sondern mit dem Parameter nvi in der Prozedur #grd_col.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, wird die neue Reihe gleich in den Changed-Modus gesetzt; default N; Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* sc (&amp;quot;selected column&amp;quot;) - Index oder Feldname der Spalte, deren Zelle im Anschluss an die Einfügeoperation selektiert werden soll. Wenn leer, wird die Selektierung nicht verändern. Funktionen werden ersetzt, default leer.&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_add   i=todo_add   f_ref=$VAR(todo_id)   f_ref_text=$VAR(todo_text)   f_ref_hint=$VAR(todo_hint)   f_status=1&lt;br /&gt;
&lt;br /&gt;
==#grd_loop==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_loop führt eine Schleife über alle oder alle selektierten Reihen eines Grid-Segments durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (each row) - Kommando, das für jede oder jede selektierte Zeile des Grids ausgeführt wird; Funktionen werden ersetzt.&lt;br /&gt;
* ert (each row transaction) - Wenn Y, dann wird jeder Aufruf des mit er festgelegten Kommandos in einer Transaktion gekapselt&lt;br /&gt;
* i (item) - Name des Grid-Segments&lt;br /&gt;
* nkomma - In eine Variable dieses Namens wird bei jedem Schleifendurchlauf mit Ausnahme des letzten Schleifendurchlaufs ein Komma geschrieben; default leer, Funktionen werden ersetzt. Wird üblicherweise dazu verwendet, um aus einem Grid eine Liste zu machen, bei der die einzelnen Elemente durch ein Komma getrennt sind, aber kein Komma hinter dem letzten Element stehen soll. Werden andere Trennzeichen benötigt, lässt sich diese mit $VT() bewerkstelligen.&lt;br /&gt;
* sc (selection column) - Index der Selection-Column; Wenn damit eine Spalte angegeben wird, dann wird das mit er festgelegte Kommando nur ausgeführt, wenn der Werte dieser Spalte in der betreffenden Reihe Y ist; default ist -1; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_loop   i=grid   er=1   sc=0&lt;br /&gt;
&lt;br /&gt;
==#grd_calc==&lt;br /&gt;
&lt;br /&gt;
Zählt die Zeilen in einem Grid oder berechnet eine Funktion. Es kann dabei eine Bedingung formuliert werden, welche Datensätze gezählt werden sollen. &lt;br /&gt;
&lt;br /&gt;
Diese Prozedur kann auch dazu verwendet werden, um zu ermitteln, ob eine bestimmte Zeile schon im Grid vorhanden ist oder nicht. Davon lässt sich dann zum Beispiel abhängig machen, ob Daten in das Grid eingefügt werden sollen oder nicht.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CalcCondition&amp;quot;) - Wenn Y, dann wird die Zeile berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* col - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet. Wird beim Typ cnt nicht benötigt.&lt;br /&gt;
* f (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. Wird beim Typ cnt nicht benötigt. &lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid- oder XGrid-Segments&lt;br /&gt;
* n (name / number) - Name der Variable oder Nummer des Values, in die/den das Ergebnis geschrieben wird.&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. Wird gerne in Kombination mit page_check verwendet, um zu prüfen, ob alle geänderten Zeilen den formulierten Anforderungen genügen. Siehe Beispiel.&lt;br /&gt;
* ry (&amp;quot;result type&amp;quot;) - Ergebnistyp; default ist int, Funktionen werden ersetzt.&lt;br /&gt;
** curr - zwei Nachkommastellen&lt;br /&gt;
** curr4 - vier Nachkommastellen&lt;br /&gt;
** int - keine Nachkommastelle&lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur gezählt, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet.&lt;br /&gt;
* y - Typ der Operation. Funktionen werden ersetzt, default ist cnt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** cnt - Anzahl&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_calc   i=item   n=1   ccnd=&amp;quot;$BOOL($PVAL(item,key,cntrow) &amp;gt; 5)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In Kombination mit #page_check&lt;br /&gt;
&lt;br /&gt;
 #page_check   y=e   chk=&amp;quot;$EXEC(xm_konfiguration_check(partner_g))&amp;quot;         c=&amp;quot;Codes, die mit G beginnen, müssen der Channel Group 'Partner' zugeordnet werden.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- in xm_konfiguration_check&lt;br /&gt;
 ~ $ICP(0,partner_g)&lt;br /&gt;
 #grd_calc   n=1   i=grid   ocr=Y   ccnd=&amp;quot;$BOOL($COPY($PVAL(grid,code,calcrow),1,1) = G   and   $PVAL(grid,channel_group,calcrow) &amp;lt;&amp;gt; P)&amp;quot;&lt;br /&gt;
 #var_set   n=result   z=&amp;quot;$BOOL($VAL(1) = 0)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
&lt;br /&gt;
==#grd_lookuplivefill==&lt;br /&gt;
&lt;br /&gt;
Füllt aus einem SQL-Statement eine LookupLive-Nachschlageliste&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear&lt;br /&gt;
 #cmd #sql select ckey, cvalue from data_list_item &lt;br /&gt;
 #cmd #sql    where data_list_id = '21DE9AF0-0C30-4222-A131-B855FAA85DEB'   &lt;br /&gt;
 #cmd #sql       and (ckey = 1 or ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0))     order by csort&lt;br /&gt;
 #cmd #grd_lookuplivefill &lt;br /&gt;
 &lt;br /&gt;
 #grd_col   f=lookup   c1=&amp;quot;Lookup&amp;quot;   y=lookuplive   llc=1&lt;br /&gt;
&lt;br /&gt;
==#grd_paste==&lt;br /&gt;
&lt;br /&gt;
Fügt Daten aus der Zwischenablage in ein Grid-Segment ein.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* add - Wenn Y, werden die über die Zwischenablage zugewiesenen Zeilen hinzugefügt, andernfalls ersetzt; Funktionen werden ersetzt, default N; &lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field&amp;quot;) - Prefix für Spalten, denen im Anschluss ein Wert zugewiesen wird; beginnt der Wert mit ''row'' (zum Beispiel f_cvalue=row1), dann wird die folgende Zahl als 0-relativer Spaltenindex in den eingefügten Daten interpretiert, andernfalls wird der zugewiesene Wert direkt eingefügt, wobei Funktionen ersetzt werden.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Als erste Zeile muss der angegebene String gepastet werden, sonst wird die Verarbeitung abgebrochen; wenn fr nicht gesetzt ist, wird die erste Zeile nicht geprüft und statt dessen wir eine normale Datenzeile behandelt;Funktionen werden ersetzt, default leer. &lt;br /&gt;
* frow - Index der Spalte in den eingefügten Daten, der in der Grid-Spalte fxrow gesucht wird. Wird nur bei y=r verwendet.&lt;br /&gt;
* frowpre, frowpost - Prefix und Postfix für frow, nur bei y=r. Wenn der mittels frow ermittelte Indexwert mit dem durch fxrow spezifizierten Wert im Grid verglichen wird, dann wird vor diesen Wert frowpre und nach diesem Wert frowpost eingefügt. &lt;br /&gt;
* fxrow - Feldname (f) der Spalte, mit deren Hilfe jeweilige Reihe identifiziert werden soll. Bei y=r muss dieser Parameter gesetzt werden. &lt;br /&gt;
* ige (&amp;quot;ignore empty&amp;quot;) - Wenn Y, werden leere Zeilen ignoriert; default N, Funktionen werden ersetzt.&lt;br /&gt;
* lat (&amp;quot;lookup as text&amp;quot;) - Wenn Y, dann werden für Lookup-Spalten nicht die Schlüssel, sondern die Werte gepastet, der Import ermittelt daraus dann die Schlüssel; default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen, mit denen innerhalb einer Zeile die Spalten getrennt werden; Funktionen werden ersetzt, default ist ein Tab-Zeichen&lt;br /&gt;
* trim - Wenn Y, werden vor dem Einfügen alle Werte getrimmt, es werden also insbesondere führende oder anhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ&lt;br /&gt;
** c (&amp;quot;column&amp;quot;) - Die Spalten werden entsprechend der Definition zugeordnet&lt;br /&gt;
** d (&amp;quot;direct&amp;quot;) - Spalten und Reihen werden so eingefügt, wie sie in der Zwischenablage sind; Link- und Button-Spalten werden ignoriert. Mit f_fieldname=wert definierte Werte werden anschließend den entsprechenden Spalten zugewiesen.&lt;br /&gt;
** r (&amp;quot;row&amp;quot;) - Mittels fxrom und frow wird die Reihe im Grid-Segment ermittelt, welcher die Werte aus der aktuellen Zeile zugewiesen werden sollen. Sofern eine solche Reihe nicht gefunden wird und(!) add=Y ist, wird die Reihe neu angelegt und dann mit Werten befüllt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #grd_paste   y=c    i=item   ige=Y   add=Y   f_ckey=row0   f_cvalue=row1   f_csort=row2   f_status=1&lt;br /&gt;
 #grd_paste   y=r    i=grid   fxrow=datum    frow=0   f_ft_sperren=row1  fr=$FND(aktion)&lt;br /&gt;
 #grd_paste   y=r    ige=Y   add=Y   lat=Y   i=grid   frow=0   fxrow=code   f_code=row0   f_target=row1   f_channel_type=row2   f_channel_group=row3   f_channel=row4&lt;br /&gt;
&lt;br /&gt;
==#grd_ac==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #grd_ac fügt einem Grid eine Zeile hinzu und setzt dort die Werte (&amp;quot;add&amp;quot;) oder ändert nur die Werte ab (&amp;quot;change&amp;quot;), abhängig davon, ob der mit fnd_1 bis fnd_9 definierte Datensatz bereits vorhanden ist oder nicht. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* chg (&amp;quot;change&amp;quot;) - Wenn Y, werden die Zellen in den Changed-Modus gesetzt, auch wenn sich ihr Wert nicht ändert; default N; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f_ (&amp;quot;field) - Prefix für die Feldnamen der Spalten, deren Werte gesetzt werden sollen; Funktionen werden ersetzt&lt;br /&gt;
* fnd_1 bis fnd_9 - Namen der Spalten, anhand die Zeile identifiziert wird; es wird die erste Zeile verwendet, auf die diese Bedingung zutrifft; Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments&lt;br /&gt;
* ic (&amp;quot;IgnoreCase&amp;quot;) - bei der Prüfung mit fnd_1 bis fnd_9 bleiben Groß- und Kleinschreibung unberücksichtigt&lt;br /&gt;
* y - Typ der Einfügeoperation; Funktionen werden ersetzt; default bottom&lt;br /&gt;
** asel (&amp;quot;after selected&amp;quot;) - die neue Zeile wird nach der selektierten Zeile eingefügt&lt;br /&gt;
** bottom - die neue Zeile wird unten angehängt&lt;br /&gt;
** bsel (&amp;quot;before selected&amp;quot;) - die neue Zeile wird vor der selektierten Zeile eingefügt&lt;br /&gt;
** top - die neue Zeile wird als erste Zeile eingefügt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear2 #grd_ac   i=grid   fnd_1=adrnr   fnd_2=aktion   f_adrnr=$SEPLINE(0)   f_aktion=$SEPLINE(1)   f_add_1=$SEPLINE(2)   f_add_2=$SEPLINE(3)  &lt;br /&gt;
 #btns_btn  c=&amp;quot;Kunden aus Zwischenablage&amp;quot;   w=200   cmd=&amp;quot;#csv_paste   er=2&amp;quot;   se=bcp&lt;br /&gt;
&lt;br /&gt;
==#grd_sort==&lt;br /&gt;
&lt;br /&gt;
Sortiert das Grid nach der angegebenen Spalte. Das kann beispielsweise erforderlich sein, wenn ein Grid mit zwei #grd_data-Prozeduren gefüllt wird, so dass nicht mit einer ORDER BY-Klausel sortiert werden kann.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f (field) - Feldname der Spalte, nach der sortiert werden soll&lt;br /&gt;
* i (item) - Name des Grids, das sortiert werden soll&lt;br /&gt;
* y - Sortierreihenfolge (u oder d, entsprechend der Symbole an der Spalte, wenn manuell sortiert wird)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_sort   i=grid   f=aktion   y=d &lt;br /&gt;
 #grd_sort   i=grid   f=adrnr   y=d&lt;br /&gt;
&lt;br /&gt;
Diese beiden Zeilen entsprechen einem ORDER BY adrnr, aktion&lt;br /&gt;
&lt;br /&gt;
==#grd_pos==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Zeilennummer der ersten Zeile, auf welche die Such-Kriterien zutreffen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* f_ (field) - Prefix der Spaltenbezeichner, die das Suchkriterium bilden. Als Wert des Parameters wird dann der Wert übergeben, nach dem in dieser Spalte gesucht werden soll.&lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* res (result) - Name der Variable oder Nummer des Values, in die das Suchergebnis (Y oder N) geschrieben wird&lt;br /&gt;
* row - Name der Variable oder Nummer des Values, in welche die Reihennummer geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_pos   i=grid   f_adrnr=$SEPLINE(0)   f_isocode=$SEPLINE(1)   f_status=1   res=1   row=2&lt;br /&gt;
&lt;br /&gt;
==#grd_dub==&lt;br /&gt;
&lt;br /&gt;
Ermittelt, ob in einer Spalte oder einer Spaltenkombination Duletten auftreten.&lt;br /&gt;
&lt;br /&gt;
Mit ccnd, ocr und sc kann die Menge der Zeilen eingeschränkt werden, die geprüft wird. Dubletten werden nur innerhalb der Reihen gefunden, die geprüft werden. Üblicherweise werden die ocr und sc nicht verwendet. &lt;br /&gt;
&lt;br /&gt;
Wenn auf mehrere Spalten geprüft wird, dann wird dieselbe Kombination alles Spalten als Dublette erkannt. (Die Zellenwerte werden zu einem langen String zusammengefügt und dabei mit ~@~ getrennt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* ccnd (&amp;quot;CheckCondition&amp;quot;) - Wenn Y, dann wird die Zeile bei der Prüfung berücksichtigt. Default Y, Funktionen werden ersetzt. Auf die aktuelle Zeile kann mit der Sonderzeile ''calcrow'' zugegriffen werden. Üblicherweise muss die Funktion $BOOL() verwendet werden, um eine Bedingung auszuwerten, siehe Beispiel.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - wenn Y, dann wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Spalten oder Feldnamen, die verwendet werden&lt;br /&gt;
* col1, col2... - Index der Spalte. Wenn nicht gesetzt, wird der Feldname verwendet; Funktionen werden ersetzt&lt;br /&gt;
* d1, d2... (&amp;quot;dublette&amp;quot;) -  Name der Variable oder Nummer des Values, in welche(n) die erste gefundene Dublette geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;fieldname&amp;quot;) - Feldname der Spalte. Wird nur verwendet, wenn col nicht gesetzt ist. &lt;br /&gt;
* i (item) - Name des Grids, in dem gesucht wird&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in welche(n) das Prüfungsergebnis geschrieben wird (Y - mindestens eine Dublette, N - keine Dublette); Funktionen werden ersetzt&lt;br /&gt;
* ocr (OnlyChangedRows) - Wenn Y, werden nur Zeilen bei der Berechnung berücksichtigt, die geändert wurden; default N. &lt;br /&gt;
* sc (&amp;quot;SelectionColumn&amp;quot;) - Index der Spalte, die als Selection-Column verwendet wird. Eine Zeile wird dann nur geprüft, wenn sie auch selektiert ist. Default ist -1, dann wird keine SelectionColumn verwendet; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code  ccnd=&amp;quot;$BOOL($PVAL(reisen,status,calcrow) = 1   and $IN($PVAL(reisen,reise_jahr_id,calcrow),30211BFC-A87D-4C07-9D7E-A92B07C52377) = N)&amp;quot;&lt;br /&gt;
 #grd_dub   i=reisen   n=result   cnt=2   f1=reise_jahr_id   f2=kgr  $CODE$&lt;br /&gt;
&lt;br /&gt;
==#grd_thread==&lt;br /&gt;
&lt;br /&gt;
Lädt Daten aus einem Hintergrund-Thread in ein Grid-Segment. Wird dazu verwendet, Daten aus unterschiedlichen Datenbank zusammen zu führen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter für alle Typen'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* i (&amp;quot;item&amp;quot;) - Name des Grid-Segments; Funktionen werden ersetzt, default ist das zuletzt eingefügte Segment &lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Parameter im SQL-Statement; im Grid-Segment muss es eine Spalte mit diesem Feldnamen geben.&lt;br /&gt;
* ready - Kommando, das ausgeführt wird, wenn der Thread fertig ist; lokale Kommandos können nicht verwendet werden; Funktionen werden ersetzt (zum Zeitpunkt des Kommandos #grd_thread)&lt;br /&gt;
* rni (&amp;quot;row no insert&amp;quot;) - Wenn Y, dann wird bei Zellen, für die Daten ergänzt wurden, das Insert-Flag entfernt; default N, Funktionen werden ersetzt. Dieser Parameter wird in folgender Konstellation benötigt: Über einen Thread werden Daten aus einer Ergänzungstabelle ergänzt. Bei grd_data sind die Daten noch nicht vorhanden, für alle Zeilen wird dort mit nvi=$GUID() eine Guidergänzt und dabei das Insert-Flag gesetzt. Der Thread ergänzt nun bereits vorliegende Daten und überschreibt dabei die Guid mit dem Wert aus der SQL-Abfrage, so dass bei Änderungen diese in den korrekten Datensatz zurückgeschrieben werden. Allerdings würde dabei das noch gesetzte Insert-Flag dazu führen, dass ein INSERT-Statement versucht würde, was zu einer Primärschlüsselverletzung führt. Wird nun rni=Y gesetzt, dann wird bei diesen Zellen das Insert-Flag entfernt, so dass statt dessen ein UPDATE durchgeführt wird.&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in Sekunden, bis ein Request abgebrochen wird; Funktionen werden ersetzt, default 15&lt;br /&gt;
* y - Typ des Threads; Funktionen werden ersetzt, default grid&lt;br /&gt;
** grid - Grid wird mittels SQL-Statement gefüllt, das mit #sql definiert werden muss&lt;br /&gt;
** gridbulk - Die Daten werden mit nur einer Abfrage ermittelt; geht bisweilen deutlich schneller&lt;br /&gt;
** gridlist - im Gegensatz zu den anderen Typen wird nicht ein einzelner Wert abgefragt, sondern alle Zeilen, welche die SQL-Abfrage liefert; die einzelnen Zeilen werden mit dem Inhalt des Parameters sep getrennt.&lt;br /&gt;
** gridxml - Grid wird mittels xml gefüllt, das mittels http(s)-Abfrage beschafft wird&lt;br /&gt;
&lt;br /&gt;
'''Parameter für SQL-Statements'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Datenbank, in der das Statement ausgeführt wird.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, mit der bei y=gridlist die einzelnen Zeilen getrennt werden; Funktionen werden ersetzt; um Zeilenumbrüche zu setzen, verwendet man sep=$CHR(crlf)&lt;br /&gt;
&lt;br /&gt;
'''Parameter für XML'''&lt;br /&gt;
* acc - Akzeptierte Response-Formate&lt;br /&gt;
* cu8 (&amp;quot;convert UTF8&amp;quot;) - wenn Y, werden die Zeichen von UTF8 nach ANSI konvertiert; default N, Funktionen werden ersetzt&lt;br /&gt;
* cy - Content-Typ der Anfrage&lt;br /&gt;
* e_req - Encoding des Requests, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* e_res - Encoding des Response, zulässig sind ansi, ascii, utf7, utf8, unicode und bigendianunicode. Funktionen werden ersetzt, default utf8.&lt;br /&gt;
* f_ - Prefix für Header-Einträge, zum Beispiel für die Authorisierung; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, werden bei den SSL-Options die Werte IgnoreServerCertificateConstraints, IgnoreServerCertificateInsecurity und IgnoreServerCertificateValidity gesetzt. Das ist zum Beispiel erforderlich, um auf REST-Server zuzugreifen, deren Zertifikat abgelaufen ist. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* method - Methode des http(s)-Aufrufs (nicht y, da bereits belegt); Funktionen werden ersetzt&lt;br /&gt;
** delete&lt;br /&gt;
** get&lt;br /&gt;
** post&lt;br /&gt;
** put&lt;br /&gt;
* request - Text der Anfrage bei post und put; Funktionen werden ersetzt&lt;br /&gt;
* response - Nummer des Values oder Name der Variable, in die bzw. den das Ergebnis geschrieben wird&lt;br /&gt;
* url - Webadresse des aufgerufenen Services; Funktionen werden ersetzt&lt;br /&gt;
* wait - Zeit in Millisekunden, die auf die Antwort gewartet wird; Funktionen werden ersetzt; default 1000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel werden drei Spalten als q=thread definiert. Die Daten für diese Spalten werden mittels #grd_thread ermittelt, der das vorangehende SQL-Statement ausführt. Schlüssel ist dwversionid.&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dwversionid   c1=&amp;quot;Dwversionid&amp;quot;&lt;br /&gt;
 #grd_col   f=szlongname    h=szlongname   c1=&amp;quot;Dateiname&amp;quot;   w=100    q=thread &lt;br /&gt;
 #grdcol c1=Tournr   f=tournr   w=50   st=gsj   f=szlongname   q=thread   ss1=Y&lt;br /&gt;
 #grdcol c1=&amp;quot;Dok Time&amp;quot;   h1=&amp;quot;Dokumentendatum Uhrzeit&amp;quot;   f=doctime   q=thread  w=80   ro=Y   nd=Y   ss1=Y  st=gsj&lt;br /&gt;
 ...&lt;br /&gt;
 #grd_data   q=sql  &lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
 #sql SELECT substring(xyz, 1, 2) + ':' + substring(xyz, 3, 2) AS doctime, dwinteger09 as tournr , szlongname FROM&lt;br /&gt;
 #sql   (SELECT format(b.dwCreation_time, '000000') AS xyz, dwinteger09, szlongname&lt;br /&gt;
 #sql     FROM dbo.baseattributes b     WHERE b.dwVersionId = :dwversionid) q&lt;br /&gt;
 #grd_thread   k=dwversionid   db=wd&lt;br /&gt;
&lt;br /&gt;
==$GRD_CHECK==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $GRD_CHECK prüft ein Grid-Segment auf bestimmte Bedingungen und ist damit eine Alternative zu #grd_calc in bestimmten Konstellationen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name des Grid-Segments&lt;br /&gt;
# Spaltenindex oder Feldname der Spalte, die untersucht wird&lt;br /&gt;
# Reihentyp&lt;br /&gt;
## all - es werden alle Reihen geprüft&lt;br /&gt;
## cellchanged - es werden nur die Reihen geprüft, wenn sie in der angegebenen Spalte geändert wurden&lt;br /&gt;
## rowchanged - es werden nur die Reihen geprüft, die (in einer beliebigen Spalte) geändert wurden&lt;br /&gt;
## rowselected - es wird nur die Reihe der selektierten Zelle geprüft&lt;br /&gt;
# Prüf-Statement, der Inhalt der jeweiligen Zelle wird durch $CELL$ eingefügt, siehe Beispiel. Bitte beachten, dass Funktionen in diesem Parameter nicht verwendbar sind.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;MWSt muss 7, 19 oder leer sein&amp;quot;    chk=&amp;quot;$GRD_CHECK(codes,kosten_mwst,all,$CELL$ = 7 or $CELL$ = 19 or $CELL$ =)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CCI==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CCI ermittelt aus einem Integer-Wert die zu setzenden Zellen-Farbe&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der Wert, der die Zellen-Farbe bestimmt. Sofern der Wert der Zelle verwendet werden soll, deren Farbe gesetzt wird, reicht ein Ausrufezeichen.&lt;br /&gt;
# Wenn L, dann muss der Wert in Parameter 1 den Schwellwert erreichen oder unterschreiten, andernfalls muss er ihn erreichen oder überschreiten&lt;br /&gt;
# Schwellwert rot. &lt;br /&gt;
# optional: Schwellwert gelb; wird nur geprüft, wenn der Schwellwert rot nicht erreicht ist&lt;br /&gt;
# optional: Schwellwert grün; wird nur geprüft, wenn die Schwellwerte rot und gelb nicht erreicht sind&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grd_col   f=dubletten   y=int   w=30   a=r   c1=&amp;quot;D&amp;quot;   h1=&amp;quot;Dubletten&amp;quot;   ccc=$CCI(!,,1)&lt;br /&gt;
&lt;br /&gt;
=XGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XGrid-Segmente sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch eine andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_seg wird ein XGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrid_col definiert die fixen Spalten des Grid, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_xcol definiert die X-Spalten, also die Spalten, die für jeden Datensatz der #xgrd_xdata eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_xdata==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_xdata werden die variablen Spalten des Grids angelegt. Für jede Zeile der mit #xgrd_xdata geöffneten SQL-Abfrage wird ein Satz von den mit #xgrd_xcol angelegten Spalten angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_data==&lt;br /&gt;
&lt;br /&gt;
Mit #xgrd_data werden Zeilen des Grids angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* k (key) - Name der Schlüsselspalte; per default der Tabellennamen plus ein angehängtes _id; Funktionen werden ersetzt&lt;br /&gt;
* k2, k3... - Name der Schlüsselspalten weiterer Tabellen; per default der Tabellennamen plus ein angehängtes _id&lt;br /&gt;
* Prefix k - Prefix für SQL-Parameter&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Nach dieser Anzahl von Zeilen wird abgebrochen; default MaxInt (2 147 483 647), Funktionen werden ersetzt&lt;br /&gt;
* ocd (open cat on data) - Wenn Y, wird die übergeordnete Kategorie geöffnet, wenn das Grid Daten enthält; default N; Funktionen werden ersetzt&lt;br /&gt;
* t (table) - Name der Datenbanktabelle, in welche die Daten beim Speichern zurückgeschrieben werden; Funktionen werden ersetzt&lt;br /&gt;
* t2, t3... - Tabellennamen weiterer Tabellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xgrd_calc==&lt;br /&gt;
&lt;br /&gt;
Mit #grd_calc funktioniert grundsätzlich auf bei X-Grids. Allerdings gibt es Aufgabenstellungen, die mit #grd_calc nicht durchführbar sind. &lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xgrd_calc bildet erst eine Aggregatfunktion in der einen Richtung, und dann aus den Ergebnissen eine zweite Aggregatfunktion in der anderen. Nähre Erläuterungen siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* f - (&amp;quot;FieldName&amp;quot;) Feldname der Zelle im Grid, für welche die fnc1 ausgeführt wird; Funktionen werden ersetzt&lt;br /&gt;
* fnc1, fnc2 - (&amp;quot;Function&amp;quot;) die erste und zweite Funktion, die ausgeführt wird; default sum, Funktionen werden ersetzt&lt;br /&gt;
** avg - Durchschnitt&lt;br /&gt;
** count - Anzahl&lt;br /&gt;
** max - Maximum&lt;br /&gt;
** min - Minimum&lt;br /&gt;
** sum - Summe&lt;br /&gt;
* nv0 - (&amp;quot;NullValue = 0&amp;quot;) Wenn Y, werden leere Zellen sowie Spalten- beziehungsweise Reihen-Ergebnisse wie 0 behandelt; default N, Funktionen werden ersetzt&lt;br /&gt;
* ry - (&amp;quot;result type&amp;quot;) Type des Ergebnisses; default curr&lt;br /&gt;
** curr - Festkommewert mit zwei Nachkommastellen&lt;br /&gt;
** curr 4 - Festkommawert mit vier Nachkommastellen&lt;br /&gt;
** date - Datum&lt;br /&gt;
** datemin - Datum mit Stunden und Minuten&lt;br /&gt;
** datesec / datesek - Datum mit Stunden, Minuten und Sekunden&lt;br /&gt;
** int - Ganzzahlen&lt;br /&gt;
* y - Typ; default xy, Funktionen werden ersetzt&lt;br /&gt;
** xy - Erst wird in X-Richtung (durch alle Spalten) die fnc1 ermittelt; jede Zeile hat dann ein Ergebnis. Danach wird über alle Zeilenergebnisse fnc2 ermittelt.&lt;br /&gt;
** yx - Erst wird in Y-Richtung (durch alle Zeilen) die fnc1 ermittelt. Jede Spalte hat dann ein Ergebnis. Danach wird über alle Spaltenergebnisse fnc2 ermittelt.&lt;br /&gt;
* z - Name der Variable oder Nummer des Values, in die das/den das Ergebnis geschrieben wird.&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll geprüft werden, wie viele Reisen einem Code maximal zugewiesen sind. Dazu wird in X-Richtung die Summe der aktivierten Zellen in der Spalte aktiv gezählt, so dass für jede Zeile (hier jedem Werbecode) ein Anzahl ermittelt wird. fnc1 ist somit sum. Dann geht die Prozedur durch alle Zeilen und ermittelt das Maximum, fnc2 ist daher max.&lt;br /&gt;
&lt;br /&gt;
 #xgrd_calc   i=jahr2code   y=xy   f=aktiv   fnc1=sum   fnc2=max   nv0=Y   ry=int   n=result&lt;br /&gt;
&lt;br /&gt;
==$XGRD_CALC==&lt;br /&gt;
&lt;br /&gt;
Wie die Prozedur #xgrd_calc, kann aber direkter in #page_check verwendet werden, siehe Beispiel&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Segment&lt;br /&gt;
# Typ; xy oder yx&lt;br /&gt;
# FieldName&lt;br /&gt;
# Func 1 (avg, count, max, min oder sum)&lt;br /&gt;
# Func 2 (avg, count, max, min oder sum)&lt;br /&gt;
# NV0 - wenn Y, werden leere Feldwerte oder Spalten- oder Zeilenergebnisse wie 0 gezählt&lt;br /&gt;
# Ergebnistyp (curr, curr4, date, datemin, datesek / datesec, int)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
Im X-grid jahr2code werden Reisejahre Werbecodes zugeordnet. Es soll mittels #page_check sichergestellt werden, dass bei fertig angelegten und nicht stornierten Werbeaktionen (status zwischen 2 und 8, wird über cnd realisiert) jedem Code mindestens eine Reise und jeder Reise mindestens ein Code zugeordnet ist. &lt;br /&gt;
&lt;br /&gt;
Zunächst wird für jede Spalte und jede Zeile die Anzahl der Zuordnungen (aktiv = Y) ermittelt (erste Funktion sum), von den Ergebnissen wird dann das Minimum gebildet; das Ergebnis wird dann darauf geprüft, ob es &amp;gt; 0 ist.&lt;br /&gt;
&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,xy,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jeder aktive Code muss mindestens einer Reise zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)   $CODE$&lt;br /&gt;
 #code   chk=&amp;quot;$BOOL($XGRD_CALC(jahr2code,yx,aktiv,sum,min,Y,int) &amp;gt; 0)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Jede aktive Reise muss mindestens einem Code zugeordnet sein&amp;quot;    cnd=$NUMBETWEEN($PVAL(vl,status),2,8)     $CODE$&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Für das Beispiel werden die folgenden drei Tabellen verwendet, zwei Detail-Tabellen und eine Verknüpfungstabelle:&lt;br /&gt;
&lt;br /&gt;
 create table sd_cross_x (&lt;br /&gt;
   sd_cross_x_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_y (&lt;br /&gt;
   sd_cross_y_id varchar(40) not null primary key,&lt;br /&gt;
   name varchar(40) not null,&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
 &lt;br /&gt;
 create table sd_cross_xy (&lt;br /&gt;
   sd_cross_xy_id varchar(40) not null primary key,&lt;br /&gt;
   sd_cross_x_id varchar(40) not null,&lt;br /&gt;
   sd_cross_y_id varchar(40) not null,&lt;br /&gt;
   active char(1),&lt;br /&gt;
   remarks varchar(40),&lt;br /&gt;
   datechg date,&lt;br /&gt;
   usrchg varchar(40),&lt;br /&gt;
   progchg varchar(40)      &lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Damit wollen wir das folgende Formular erstellen:&lt;br /&gt;
&lt;br /&gt;
[[file:demo xgrid.png|1000px|Demo XGrid]]&lt;br /&gt;
&lt;br /&gt;
Damit die Änderungen in den Detail-Tabellen gleich nach dem Speichern im XGrid sichtbar werden, wird bei der Page der Parameter ras (&amp;quot;RefreshAfterSave&amp;quot;) gesetzt.&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
&lt;br /&gt;
Wir verwenden hier in einer Primär-Region zwei Kategorien, links für die Spalten (X), rechts für die Reihen (Y). Die beiden Kategorien werden also nebeneinander angezeigt.&lt;br /&gt;
&lt;br /&gt;
Jede Kategorie hat ein Button-Segment mit einem Button, mit dem jeweils ein neuer Datensatz angelegt werden kann. Dazu muss lediglich die Prozedur #grd_add aufgerufen werden.&lt;br /&gt;
&lt;br /&gt;
Die Tabellen hier im Beispiel haben (neben den Standard-Spalten _id, datechg, usrchg und progchg) lediglich einen Namen. Damit die ID-Spalte mit einer GUID versorgt wird, wird diese für den Parameter nvi (&amp;quot;NullValue Insert&amp;quot;) erzeugt; bei der Gelegenheit wird die Zeile dann gleich als neu eingefügt gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=X&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridx&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridx   c=&amp;quot; &amp;quot;   b=XYH  &lt;br /&gt;
 #grd_col   f=sd_cross_x_id   c1=ID   w=30   y=guid   ro=Y     nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_x   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_x &lt;br /&gt;
 &lt;br /&gt;
 #cat  as=Y     c=Y&lt;br /&gt;
 #btns_seg  &lt;br /&gt;
 #btns_btn  c=&amp;quot;$T(Add item)&amp;quot;  w=150   cmd=&amp;quot;#grd_add   i=gridy&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #grd_seg   frc=0   fcc=1   clt=ss   n=gridy   c=&amp;quot; &amp;quot;   b=xYH&lt;br /&gt;
 #grd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y   nvi=$GUID()&lt;br /&gt;
 #grd_col   f=name   c1=&amp;quot;Name&amp;quot;   l=40   w=100   wst=500   xw=400&lt;br /&gt;
 #sql select * from sd_cross_y   order by name&lt;br /&gt;
 #grd_data   q=sql   t=sd_cross_y   &lt;br /&gt;
&lt;br /&gt;
Die zweite Primärregion beinhaltet das XGrid, mit dem die Verknüpfung angezeigt wird. Nach der Prozedur #xgrd_seg werden mit #xgrd_col erst mal die beiden fixen Spalten definiert, die ID und der Name (der Reihe).&lt;br /&gt;
&lt;br /&gt;
Danach werden die variablen Spalten mit #xgrd_xcol definiert und mit #xgrd_xdata angelegt. Als erste Spalte in einem solchen Spaltensatz wird eine Spalte für die IDs eingefügt. Diese hat üblicherweise die Breite w=0, da die IDs nicht interessieren. Zum Debuggen kann diese Spalte jedoch breiter gemacht werden. Diese &amp;quot;unsichtbare&amp;quot; Spalte hat als Feld f die ID der Verknüpfungstabelle, hier also f=sd_cross_xy_id. Als Feld für die erste Headerzeile f1 muss die ID der X-Datenmenge, hier also f1=sd_cross_x_id.&lt;br /&gt;
&lt;br /&gt;
Bei den weiteren Spalten besteht die Freiheit des Programmierers. Hier im Beispiel wird eine bool'sche Spalte für die Verknüpfung sowie eine Anmerkungsspalte eingefügt. Mit cs1=2 bei der bool'schen Spalte wird die Überschrift über beide Spalten gezogen.&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y  &lt;br /&gt;
 #cat  as=Y     c=XY&lt;br /&gt;
 &lt;br /&gt;
 #xgrd_seg   frc=0   fcc=1   clt=ss   n=gridxy   c=&amp;quot; &amp;quot;  b=XYH&lt;br /&gt;
 #xgrd_col   f=sd_cross_y_id   c1=ID   w=30   y=guid   ro=Y&lt;br /&gt;
 #xgrd_col   f=yname   c1=&amp;quot;name&amp;quot;   w=80   nd=Y   ro=Y &lt;br /&gt;
 &lt;br /&gt;
 #xgrd_xcol   f1=sd_cross_x_id   f=sd_cross_xy_id   w=0   y=guid   ro=Y  &lt;br /&gt;
 #xgrd_xcol   f1=name   cs1=2   f=active   y=bool   w=30   xcs1=2&lt;br /&gt;
 #xgrd_xcol   f=remarks   l=40   &lt;br /&gt;
 #sql select * from sd_cross_x order by name&lt;br /&gt;
 #xgrd_xdata  &lt;br /&gt;
&lt;br /&gt;
Für die Daten im XGrid brauchen wir zunächst ein SQL-Statement, das aus den beiden Detail-Datenmengen ein kartesisches Produkt (Mengenprodukt) erstellt; dafür sehen wir im Statement die Verknüpfungsbedingung 1=1 (die nur deswegen eingefügt ist, damit formal eine Verknüpfungsbedingung vorhanden und das SQL-Statement syntaktisch korrekt ist). Mit einem left outer join wird die Verknüpfungstabelle hinzugefügt (kein inner join, da anfangs ja die Datensätze noch nicht vorhanden sind).&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xgrd_data werden die Daten dann aus der Ergebnismenge geladen. Wir müssen hier die Tabellen t angeben, in welche die Daten zurückgeschrieben werden (also in die Verknüpfungstabelle, hier t=sd_cross_xy), welches die ID für die Spalten ist (hier fcol=sd_cross_x_id, das muss übereinstimmen mit f1=sd_cross_x_id in der 0-breiten ersten Spalte des Spalten-Sets), und wann eine neue Zeile begonnen wird (frow=sd_cross_y_id). Damit Letzteres korrekt funktioniert, muss die erste Sortierung im Statement nach den Reihen sein (hier order by y.name)&lt;br /&gt;
&lt;br /&gt;
 #sql select y.sd_cross_y_id, y.name as yname, x.sd_cross_x_id, x.name as xname, c.sd_cross_xy_id, c.active, c.remarks&lt;br /&gt;
 #sql   from sd_cross_y y&lt;br /&gt;
 #sql     inner join sd_cross_x x on 1=1&lt;br /&gt;
 #sql     left outer join sd_cross_xy c on c.sd_cross_y_id = y.sd_cross_y_id and c.sd_cross_x_id = x.sd_cross_x_id&lt;br /&gt;
 #sql   order by y.name, x.name&lt;br /&gt;
 #xgrd_data   q=sql   t=sd_cross_xy   fcol=sd_cross_x_id   frow=sd_cross_y_id&lt;br /&gt;
&lt;br /&gt;
==Tipps==&lt;br /&gt;
&lt;br /&gt;
Das Erstellen des Codes für ein XGrid ist am Anfang ein wenig komplex und fehleranfällig. Von daher sollen hier noch die folgenden Tipps gegeben werden:&lt;br /&gt;
&lt;br /&gt;
'''Vorlage kopieren''' &lt;br /&gt;
&lt;br /&gt;
Nehmen Sie sich ein bestehendes XGrid-Segment, kopieren es und ändern es entsprechend ab.&lt;br /&gt;
&lt;br /&gt;
'''Schrittweise vorgehen'''&lt;br /&gt;
&lt;br /&gt;
Legen Sie erst die Spalten an, dann den Code für die Daten. Wenn Sie eine Vorlage kopiert haben, dann setzen Sie nach #xgrd_xdata erst mal vier Minuszeichen (der Rest das Codes ist dann Kommentar) und schauen erst mal, dass die Spalten korrekt angezeigt werden.&lt;br /&gt;
&lt;br /&gt;
'''Gern gemachte Fehler'''&lt;br /&gt;
&lt;br /&gt;
* In der ersten Spalte das variablen Spaltensatzes ist f oder f1 nicht oder nicht korrekt gesetzt. Oder f1 stimmt nicht mit fcol aus #xgrd_data überein.&lt;br /&gt;
* Das Statement für die Daten ist kein kartesisches Produkt als Spalten und Reihen&lt;br /&gt;
* Die Verknüpfungtabelle ist nicht mit einem left outer join hinzugefügt.&lt;br /&gt;
* Das Statement für die Daten ist nicht nach den Reihen sortiert.&lt;br /&gt;
&lt;br /&gt;
'''In mehrere Tabellen schreiben'''&lt;br /&gt;
&lt;br /&gt;
Müssen die Daten in mehrere Tabellen geschrieben werden, so ist die Verknüpfungstabelle immer die Tabelle t, alle anderen Tabellen werden mit t2, t3... hinzugefügt.&lt;br /&gt;
&lt;br /&gt;
Schauen Sie sich als Beispiel xtodo_page_add an.&lt;br /&gt;
&lt;br /&gt;
=XXGrid-Segmente=&lt;br /&gt;
&lt;br /&gt;
XXGrid-Segmente (&amp;quot;Double-X-Grid-Segmente&amp;quot;) sind Segmente, in denen in Tabellenform mehrere Datensätze einer SQL-Abfrage angezeigt werden. Dabei werden die Spalten durch zwei andere SQL-Abfrage gebildet. Grid-Segmente können Kopf- und Fußzeilen haben (default 1 Kopfzeile, 0 Fußzeilen)&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #xxgrd_seg wird ein XXGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; default 0; Funktionen werden ersetzt&lt;br /&gt;
* frc (footer row count) - Anzahl der Fußzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* hrc (header row count) - Anzahl der Kopfzeilen; default 0; Funktionen werden ersetzt&lt;br /&gt;
* sc (selection column) - Spaltenindex der Selection-Zeile. Ein Grid-Segment kann eine Selection-Spalte haben, also eine Spalte vom Typ bool, mit deren Hilfe einzelne Zeilen ausgewählt werden können. Default ist -1, Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_col==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_col definiert die fixen Spalten des Grids, die an der linken Seite stehen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xcol definiert die vorderen variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==#xxgrd_xxcol==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #xxgrid_xxcol definiert die hinteren variablen Spalten des Grids.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
Diese Prozedur gleich #grid_col, die Parameter sind dort beschrieben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
siehe unten&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel ist aus der Reklamationsbearbeitung eines Reiseveranstalters. Die einzelnen Stichworte (hier nur ausschnittsweise) sind in Kategorien zusammengefasst. Diese Kategorien bilden die vorderen Spaltenüberschriften, die Reisenummern die hinteren (in einer Reklamation können mehrere Reisen bemängelt werden, die Stichworte müssen von daher den Reisen zugeordnet werden).&lt;br /&gt;
&lt;br /&gt;
[[file:Xxgrid 2.png|XXGrid-Segment]]&lt;br /&gt;
&lt;br /&gt;
Um die Stichworte positionieren zu können, wird mit Zeilennummern gearbeitet, diese werden in der ersten Spalte angezeigt. Da die gesetzten Stichworte dem Vorgang zugeordnet werden müssen, muss die Vorgangs-ID gespeichert werden, dies passiert in einer Spalte mit der Breit 0.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_seg   n=cross   fcc=1   c=&amp;quot; &amp;quot;   b=H&lt;br /&gt;
 #xxgrd_col  c1=Nr   w=30  ro=Y  f=zahl  st=gsj  nd=Y&lt;br /&gt;
 #xxgrd_col  w=0  ro=Y  f=ks_vorgang_id  &lt;br /&gt;
&lt;br /&gt;
Hier werden nun die variablen Spalten definiert. Vorne (xxgrid_xcol) haben wir das Stichwort, für die IDs, auch der Kategorie, haben wir davor eine Spalte mit der Breite 0. Hinten (xxgrid_xxcol) haben wir dann die Möglichkeit, einen Haken zu setzen (y=bool2), darüber muss die Reisenummer (f1=aktion), davor gibt es wieder eine Spalte mit der Breite 0 mit der ID des Stichworts. Da der Platz begrenzt ist, wird die Bezeichnung der Reise nur als Hint-Text der Reisenummer angezeigt.&lt;br /&gt;
&lt;br /&gt;
 #xxgrd_xcol   w=0   f1=rekla_tbs_kat_id   f=rekla_tbs_id&lt;br /&gt;
 #xxgrd_xcol   w=170   f1=name   f=stiwo   ro=Y   st=gsf   nd=Y&lt;br /&gt;
 #xxgrd_xxcol   w=0   f=rekla_stiwo_id&lt;br /&gt;
 #xxgrd_xxcol   w=36   f1=aktion   f=aktiv   h1=bezeichnung   y=bool2&lt;br /&gt;
&lt;br /&gt;
Mit #xxgrd_xdata werden die Spalten ermittelt. Das SQL-Statement muss ein kartesisches Produkt aus den Kategorien und denjenigen Reisenummern bilden, die beim Vorgang beteiligt sind (Tabelle neuland.ks_vorgang_reise). (Am Rande: Es handelt sich hier um einen Test auf einem System, das auf einer Postgres-Datenbank läuft, die Datenbank aber aus einem Oracle-System holt. Entsprechend ist db=ora_prod gesetzt und die GUID des Vorgangs hart codiert.)&lt;br /&gt;
&lt;br /&gt;
 #sql select k.rekla_tbs_kat_id, k.name, r.aktion, d.bezeichnung&lt;br /&gt;
 #sql   from neuland.rekla_tbs_kat k&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join rsd d on d.aktion = r.aktion&lt;br /&gt;
 #sql   where k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql   order by k.sort, r.aktion;&lt;br /&gt;
 #xxgrd_xdata   k=rekla_tbs_kat_id   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB    kaz=R   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
Die Tabelle, in welche die gesetzten Stichworte geschrieben werden, ist neuland.rekla_stiwo. Eine solche Tabelle muss stets mit einem left outer join der restlichen Abfrage hinzugefügt werden. Das restliche Statement liefert die Stichworte, Kategorien und Reisenummern. Der Parameter kaz ist ein Parameter aus dem SQL-Statement, in den die Abteilungszugehörigkeit (hier R für Reklamationsabteilung) geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
Wenn das Statement korrekt ist, müssen dann nur noch die Spaltenbezeichner für die Überschrift der vordere Variable Spalte (Kategorie, also fcol=rekla_tbs_kat_id), die vordere variable Spalte (Stichwort, also fxcol=rekla_tbs_id) und die hintere variable Spalte (Reisenummer, also fxxcol=aktion) sowie der Reihen (frow=zahl) gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
 #sql select r.ks_vorgang_id, t.zahl, k.rekla_tbs_kat_id, k.name as kat, r.aktion, b.rekla_tbs_id, b.name as stiwo, s.rekla_stiwo_id, s.aktiv&lt;br /&gt;
 #sql   from neuland.stamm_tage t&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs_kat k on  k.status = 1   and k.az = :kaz&lt;br /&gt;
 #sql     inner join neuland.ks_vorgang_reise r on r.ks_vorgang_id = :kid   and r.status &amp;lt; 7&lt;br /&gt;
 #sql     inner join neuland.rekla_tbs b on b.rekla_tbs_kat_id = k.rekla_tbs_kat_id and b.sort = t.zahl&lt;br /&gt;
 #sql     left outer join neuland.rekla_stiwo s     on s.ks_vorgang_id = r.ks_vorgang_id      and s.rekla_tbs_id = b.rekla_tbs_id     and s.aktion = r.aktion&lt;br /&gt;
 #sql   where t.zahl between 1 and 20&lt;br /&gt;
 #sql   order by t.zahl, k.sort, r.aktion;&lt;br /&gt;
 #code   fcol=rekla_tbs_kat_id   fxcol=rekla_tbs_id   fxxcol=aktion   &lt;br /&gt;
 #xxgrd_data  t=neuland.rekla_stiwo   kid=FFACF140-151F-412C-8EE7-A872B1DCA7EB   kaz=R   $CODE$   frow=zahl   db=ora_prod&lt;br /&gt;
&lt;br /&gt;
=SGrid-Segmente=&lt;br /&gt;
Bei einem SGrid sind die Zeilen durch so genannte Segmente gruppiert.&lt;br /&gt;
&lt;br /&gt;
[[file:sgrid.png|788px|SGrid]]&lt;br /&gt;
&lt;br /&gt;
==#sgrd_seg==&lt;br /&gt;
&lt;br /&gt;
Mit der Prozedur #sgrd_seg wird ein SGrid-Segment angelegt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cc (&amp;quot;ColumnCount&amp;quot;) - Anzahl der Spalten; default 2; Funktionen werden ersetzt&lt;br /&gt;
* clt (column line type) - Spezifiziert, ob Spalten verbreitert oder umgebrochen werden; default sf; Funktionen werden ersetzt&lt;br /&gt;
** mf - multi line fixed&lt;br /&gt;
** ms - multi line stretch&lt;br /&gt;
** sf - single line fixed&lt;br /&gt;
** ss - single line stretch&lt;br /&gt;
* fcc (fixed columns count) - Spalten, die auch beim Scrollen links angezeigt werden; Wird bei #vl_seg sehr selten verwendet; default 0&lt;br /&gt;
* w (&amp;quot;width&amp;quot;) - Breite der Spalte (w1, w2, w3...); Funktionen werden ersetzt&lt;br /&gt;
* wst (&amp;quot;width stretch&amp;quot;) - Anzahl der Pixel, um welche die Spalte maximale verbreitert wird (wst1, wst2, wst3...); Funktionen werden ersetzt; findet nur bei clt=ss und clt=ms Verwendung&lt;br /&gt;
* whs (without horizontal scrollbar) - Blendet einen horizontalen Scrollbalken komplett aus, das Grid wird dadurch 20 Pixel weniger hoch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''gemeinsame Parameter aller Segmenttypen'''&lt;br /&gt;
&lt;br /&gt;
* b (&amp;quot;Buttons&amp;quot;) - Buttons für das Segment; benötigt eine Überschrift (zur Not ein Leerzeichen), weil die Buttons rechts oben in der Überschriftszeile untergebracht werden; Funktionen werden ersetzt&lt;br /&gt;
* c (&amp;quot;Caption&amp;quot;) - Überschrift für das Segment; Funktionen werden ersetzt&lt;br /&gt;
* hp (&amp;quot;help path&amp;quot;) - noch ohne Funtion&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name des Segments, wird benötigt, wenn auf das Segment zugegriffen werden soll&lt;br /&gt;
* mhc (&amp;quot;max height closed&amp;quot;) - maximale Höhe im geschlossenen Zustand&lt;br /&gt;
* mho (&amp;quot;max height opened&amp;quot;) - maximale Höhe im geöffneten Zustand&lt;br /&gt;
* oc (&amp;quot;open close&amp;quot;) - Spezifiziert, ob das Segment im geöffneten und/oder geschlossenen Zustand der Kategorie angezeigt wird; Funktionen werden ersetzt; default o&lt;br /&gt;
** c - Segment wird nur in geschlossenem Zustand angezeigt&lt;br /&gt;
** o - Segment wird nur in geöffnetem Zustand angezeigt&lt;br /&gt;
** oc - Segment wird in geöffnetem und geschlossenen Zustand angezeigt&lt;br /&gt;
* r (&amp;quot;rights&amp;quot;) - Rechtedefinition&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Der Anwender kann die Daten im Segment nicht ändern&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80&lt;br /&gt;
&lt;br /&gt;
==#sgrd_node==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_node legt eine Ebene des SGrids an und definiert dort die Spalten. Im einfachsten Fall hat ein SGrid eine Zeile für eine übergeordnete und eine Zeile für die untergeordnete Ebene. Es können jedoch mehr als zwei Ebenen angelegt werden. Es ist auch möglich, dass eine Ebene mehrere Zeilen hat - das ist besonders dann hilfreich, wenn viele Spalten untergebracht werden müssen. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a1, a2... (align) - Ausrichtung des Textes in der Spalte; default ist l.&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c1, c2... (&amp;quot;caption&amp;quot;) - Beschriftung der Zelle; wird die Beschriftung ersetzt, wird die Zelle auf ReadOnly gesetzt; Funktionen werden ersetzt&lt;br /&gt;
* ccc (&amp;quot;cell color command&amp;quot;) - Kommando für die Zellenfarbe der Zeile, default leer, Funktionen werden ersetzt. Wird primär für ccc=header verwendet.&lt;br /&gt;
* chg1, chg2... (&amp;quot;change&amp;quot;) - Kommando, das ausgeführt wird, wenn der Inhalt der Zelle geändert wird; siehe auch ''Beispiel für chg''&lt;br /&gt;
* ci1, ci2... (characters ignore) - Zeichen, die bei der Eingabe über die Tastatur ignoriert werden; default leer; Funktionen werden ersetzt&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* f1, f2... (&amp;quot;field&amp;quot;) - Feldname in der Datenmenge, aus der die Zelle ihre Daten bezieht; Funktionen werden ersetzt&lt;br /&gt;
* k (&amp;quot;key&amp;quot;) - Name der Schlüsselspalte; default ist der Tabellenname mit einem angehängten _id&lt;br /&gt;
* l1, l2... (&amp;quot;length&amp;quot;) - Zeichenlänge der Zelle&lt;br /&gt;
* nd1, nd2... (&amp;quot;no data&amp;quot;) - Daten werden beim Speichern nicht zurück in die Datenbank geschrieben; Änderungen an den Daten versetzen das VL-Segment und somit die Page nicht in den Changed-Status&lt;br /&gt;
* pw1, pw2... (&amp;quot;password&amp;quot;) - Wenn Y, dann werden statt des Inhalts Punkte angezeigt; Funktionen werden ersetzt&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* q1, q2... (&amp;quot;Quelle&amp;quot;) - Datenquelle für die Zelle; siehe auch ''Beispiel für Datenquelle''&lt;br /&gt;
* r1, r2... (&amp;quot;rights&amp;quot;) - Rechtedefinition der Zelle&lt;br /&gt;
* ro (&amp;quot;read only&amp;quot;) - Wenn Y, kann die Zeile nicht bearbeitet werden; default N, Funktionen werden ersetzt&lt;br /&gt;
* ro1, ro2... (&amp;quot;read only&amp;quot;) - Zelle kann nicht bearbeitet werden&lt;br /&gt;
* t (&amp;quot;table&amp;quot;) -Name der Tabelle, in der die Daten zurück geschrieben werden.&lt;br /&gt;
* u - Typ der Ebene. Der Typ hat eher deklaratorischen Charakter, lediglich a und w haben eine Funktion. Ansonsten müssen die Ebenen in der Reihenfolge angelegt werden, wie sie kommen, also zuerst die oberste Ebene.&lt;br /&gt;
** a / w (&amp;quot;additional&amp;quot;, &amp;quot;weitere&amp;quot;) - deklariert eine weitere Zeile auf derselben Ebene.&lt;br /&gt;
** l (&amp;quot;last&amp;quot;) - untergeordnet unter der zuletzt deklarierten Ebene&lt;br /&gt;
** r (&amp;quot;root&amp;quot;) - oberste Ebene&lt;br /&gt;
* y1, y2... (&amp;quot;type&amp;quot;) - Datentyp der Spalte; default ist text&lt;br /&gt;
** bool - bool'sche Felder mit Y und N; wird als Checkbox dargestellt&lt;br /&gt;
** bool2 - bool'sche Felder, Y wird als angehakte Checkbox dargestellt, N als leeres Feld&lt;br /&gt;
** curr - Currency, also Zahlen mit zwei Nachkommastellen&lt;br /&gt;
** curr4 - Zahlen mit vier Nachkommastellen&lt;br /&gt;
** date - Datum im Format dd.mm.yyyy&lt;br /&gt;
** datemin - Datum im Format dd.mm.yyyy hh:mm&lt;br /&gt;
** datesec / datesek - Datum im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
** guid - Inhalt wird als drei Punkte dargestellt; wird für GUIDs verwendet, die sich dann aber kopieren lassen&lt;br /&gt;
** iban - noch nicht implementiert&lt;br /&gt;
** int - Integer, also ganze Zahlen&lt;br /&gt;
** link - Link-Symbol&lt;br /&gt;
** lookup - Nachschlageliste&lt;br /&gt;
** lookuplive - Nachschlageliste, die beim Öffnen neu und auch für jede Zelle individuell geladen wird&lt;br /&gt;
** text - normaler Text&lt;br /&gt;
** todo - Symbole für ToDo-Listen&lt;br /&gt;
** triex - drei Symbole: 0, ? und !&lt;br /&gt;
** triplus - drei Symbole: 0, - und +&lt;br /&gt;
* z1, z2... - Wert der Zelle; im Unterschied zur Caption wird der Wert von #vl_data überschrieben, die Zelle wird auch nicht auf ReadOnly gesetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
&lt;br /&gt;
==#sgrd_hf==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_hf legt Kopf- und Fußzeilen an.&lt;br /&gt;
&lt;br /&gt;
Die Zahl zur Benennung ist die Kombination aus der Header/Footer-Zeile und der Spaltennummer. Da es quasi nie mehr als 9 Header- oder Footer-Zeilen gibt, funktioniert das in der Praxis.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* a11, a12, a21... (&amp;quot;hint&amp;quot;) - Alignment des Headers&lt;br /&gt;
** c (center) - Text wird zentriert ausgerichetet&lt;br /&gt;
** d2 (decimal 2) - Text wird rechtsbündig für zwei Nachkommastellen ausgerichtet&lt;br /&gt;
** d4 (decimal 4) - Text wird rechtsbündig für vier Nachkommastellen ausgerichtet&lt;br /&gt;
** l (left) - Text wird linksbündig ausgerichtet&lt;br /&gt;
** r (right) - Text wird rechtsbündig ausgerichtet&lt;br /&gt;
* c11, c12, c21... (&amp;quot;caption&amp;quot;) - Header Spalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* cs11, cs12, cs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Header, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* fa11, fa12, fa21... (&amp;quot;hint&amp;quot;) - Alignment des Footers; fültige Werte siehe a11...&lt;br /&gt;
* fc11, fc12, fc21... (&amp;quot;caption&amp;quot;) - FooterSpalten-Titel; Funktionen werden ersetzt.&lt;br /&gt;
* fcs11, fcs12, fcs21... (&amp;quot;column span&amp;quot;) - Spalten-Zusammenfassung im Footer, default 1; Funktionen werden ersetzt.&lt;br /&gt;
* fy11, fy12, fy21... - Type der Footer-Zelle&lt;br /&gt;
* h11, h12, h21... (&amp;quot;hint&amp;quot;) - Hint-Text des Headers; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_hf   c11=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
&lt;br /&gt;
==#sgrd_data==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #sgrd_data lädt die Werte für das SGrid aus der Datenbank&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* db (&amp;quot;DataBase&amp;quot;) - Name der Datenbankverbindung, aus der die Daten bezogen werden; Funktionen werden ersetzt, default ist die Standard-Datenbankverbindung&lt;br /&gt;
* q (quelle) - Herkunft der Daten; default sql&lt;br /&gt;
** sql - SQL-Statement&lt;br /&gt;
&lt;br /&gt;
'''Beispiel''' &lt;br /&gt;
&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 #prim  as=Y &lt;br /&gt;
 #cat  as=Y     c=$T(Items_of_the_category)&lt;br /&gt;
 &lt;br /&gt;
 #sgrd_seg   hrc=1   cc=5   w1=30   w2=40   w3=80   w4=200   wst4=200   w5=80  &lt;br /&gt;
 #sgrd_hf   c1=ID   c12=Sort   c13=Schlüssel   c14=Wert   c15=Status&lt;br /&gt;
 #sgrd_node   u=r   ro=Y   ccc=header   t=data_list   f1=data_list_id   y1=guid   f2=name   cs2=2   f4=description  cs4=2   nc=Y&lt;br /&gt;
 #sgrd_node   u=l   t=data_list_item   f1=data_list_item_id   y1=guid   f2=csort   f3=ckey   f4=cvalue   f5=status   y5=lookup   ld5=general_status&lt;br /&gt;
 &lt;br /&gt;
 #sql select l.data_list_id, l.name, l.description , i.data_list_item_id, i.csort, i.ckey, i.cvalue, i.status&lt;br /&gt;
 #sql   from data_list l&lt;br /&gt;
 #sql     inner join data_list_item i   on i.data_list_id = l.data_list_id&lt;br /&gt;
 #sql   where l.category = 'General'&lt;br /&gt;
 #sql   order by l.name, i.csort, i.ckey&lt;br /&gt;
 #sgrd_data   q=sql&lt;br /&gt;
&lt;br /&gt;
=Picture-Segmente=&lt;br /&gt;
&lt;br /&gt;
Picture-Segmente dienen dazu, Bilder anzuzeigen.&lt;br /&gt;
&lt;br /&gt;
==#pic_seg==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #pic_seg fügt ein Bild ein. Mit dem Parameter y wird spezifiziert, wo das Bild her kommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* f (&amp;quot;Field&amp;quot;) - Feldname, in dem der Dateiname des Bildes steht, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname des Bildes, wenn Parameter q=file; Funktionen werden ersetzt&lt;br /&gt;
* ho (&amp;quot;height closed&amp;quot;) - Die Höhe des Segments bei geschlossener Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* ho (&amp;quot;height open&amp;quot;) - Die Höhe des Segments bei geöffneter Kategorie, wenn nicht AutoSize verwendet wird.&lt;br /&gt;
* i (&amp;quot;Item&amp;quot;) - Name des Grid-Segmentes, wenn Parameter q=link; Funktionen werden ersetzt&lt;br /&gt;
* isc (&amp;quot;ignore server certificate&amp;quot;) - Wenn Y, wird das Zertifikat des Servers bei q=http ignoriert; Funktionen werden ersetzt, default N&lt;br /&gt;
* q - Datenquelle des Bildes&lt;br /&gt;
** file - Der Dateiname des Bildes wird mit dem Parameter fn angegeben.&lt;br /&gt;
** link - Der Dateiname des Bildes steht in einem verbundenen Grid-Segment, dessen Namen mit dem Parameter i und dessen Feldname mit dem Parameter f angegeben wird.&lt;br /&gt;
** http - Das Bild wird aus dem Netz geladen, siehe Parameter url und isc&lt;br /&gt;
* sh (&amp;quot;scroll horizontal&amp;quot;) - Wenn Y, wird ein waagerechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
* sv (&amp;quot;scroll vertical&amp;quot;) - Wenn Y, wird ein senkrechter Scrollbalken eingefügt;  Funktionen werden ersetzt, default Y&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #pic_seg   aso=Y   q=file   fn=&amp;quot;T:\Tools Gruppenrechte\BafClient2\pics\gutschein_a4.png&amp;quot;   c=Gutschein   sv=N   sh=N&lt;br /&gt;
 #pic_seg   aso=Y   q=link   i=grid   f=filename   c=Gutschein     sv=N   sh=N&lt;br /&gt;
 #pic_seg   ho=300   q=http   url=&amp;quot;https://api.predic8.de/shop/products/$FND(s,id)/photo&amp;quot;   isc=Y     sv=N   sh=N&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22516</id>
		<title>Modul VAR neu</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22516"/>
		<updated>2025-03-26T14:24:25Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* $CONVERT() */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das Modul Var sammelt neben den Variablen auch die grundlegenden Prozeduren und Funktionen.&lt;br /&gt;
&lt;br /&gt;
=Variable=&lt;br /&gt;
&lt;br /&gt;
==#var_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#setvar setzt den Wert einer Variablen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis: Variable sind global, auf sie kann auch in Sub-Kommandos zugegriffen werden. Values sind dagegen lokal.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*rf (replace functions) - Wenn Y, dann werden nach der Zuweisung auf die Variable nochmals die Funktionen ersetzt. Wird zum Beispiel benötigt, wenn Code mit Funktionen mittels $DATA() aus der Datenbank geladen wird; Funktionen werden ersetzt, default N; siehe Beispiel&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_set   n=test2  z=$GUID()&lt;br /&gt;
 #var_set   n=edt    z=$EDT(edt1)   ie=42&lt;br /&gt;
 #var_set   n=_page_kunde_adressänderung_ro   z=N   zn=Y   zr=Y   r=kundenservice&lt;br /&gt;
&lt;br /&gt;
Zum Parameter rf: $NOW() in die Zwischenablage kopieren und dann ausführen:&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=N&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=Y&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_setempty==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_setempty setzt den Wert einer Variablen, sofern sie (noch) leer ist.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Besteht der Variableninhalt aus Leerzeichen, gilt die Variable auch als leer.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_setempty   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_setempty   n=test2  z=$GUID()&lt;br /&gt;
 #var_setempty   n=edt    z=$EDT(edt1)    ie=42&lt;br /&gt;
&lt;br /&gt;
==#var_add==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_add fügt einer Variablen einen Wert hinzu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. &lt;br /&gt;
* y -Typ der Operation; default ''text''&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** month - Es wird dem Datum eine Anzahl von Monaten hinzugefügt&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
*z - Wert, welcher der Variablen hinzugefügt wird, Funktionen werden ersetzt, default ist ein leerer String oder eine 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$NOW()&lt;br /&gt;
 #var_add   n=test   z=1   y=datetime&lt;br /&gt;
 #cout   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_log==&lt;br /&gt;
&lt;br /&gt;
Schreibt den Inhalt aller Variablen in das Debug-Log.&lt;br /&gt;
&lt;br /&gt;
Wird nur zur Fehlersuche verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_log&lt;br /&gt;
&lt;br /&gt;
==$VAR()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $VAR() wird auf den Inhalt der Variable zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
# optional: Der Wert wird vor oder nach der Rückgabe als Funktionsergebnis verändert; nur für ganzzahlige Werte&lt;br /&gt;
## ib (&amp;quot;increment before&amp;quot;) - Der Wert wird vor der Rückgabe um eins erhöht&lt;br /&gt;
## db (&amp;quot;decrement before&amp;quot;) - Der Wert wird vor der Rückgabe um eins verringert&lt;br /&gt;
## ia (&amp;quot;increment after&amp;quot;) - Der Wert wird nach der Rückgabe um eins erhöht&lt;br /&gt;
## da (&amp;quot;decrement after&amp;quot;) - Der Wert wird nach der Rückgabe um eins verringert&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #message  c=$VAR(test)&lt;br /&gt;
 #var_set  n=neuer_wert   z=$VAR(wert)   ie=$VAR(alternativwert)&lt;br /&gt;
 #execsql   k_lfdnr=$VAR(lfdnr,ib)&lt;br /&gt;
&lt;br /&gt;
=Kommandos=&lt;br /&gt;
&lt;br /&gt;
(Primär- und Sub) Kommandos sind üblicherweise benannt und werden im Code-Dialog eingegeben.&lt;br /&gt;
&lt;br /&gt;
Es besteht jedoch auch die Möglichkeit, lokale Kommandos innerhalb eines anderen Kommandos zu definieren. Diese Kommandos haben statt eines Kommando-Namens dann dann eine Kommando-Nummer.&lt;br /&gt;
&lt;br /&gt;
Lokale Kommandos werden üblicherweise für folgende Zwecke verwendet:&lt;br /&gt;
&lt;br /&gt;
* Bei der Verwendung von xlive werden bisweilen Prozeduren eingesetzt, die ihrerseits ein Kommando aufrufen (z.B. #sql_open). Wenn dieses Kommando nichts bereits existiert, kann es nur als lokales Kommando erstellt werden.&lt;br /&gt;
&lt;br /&gt;
* Wenn das auszuführende Kommando auf derselben Seite stehen soll wie die aufrufende Prozedur.&lt;br /&gt;
&lt;br /&gt;
Siehe als Beispiel: [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd fügt dem Kommando eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd fügt dem ersten Kommando eine Zeile hinzu, #cmd2 fügt dem zweiten Kommando eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd hat keine benannten Parameter. Die ganze Zeile nach dem #cmd und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd3 #text $DATA(n,login);$DATA(n,shortname);$DATA(n,firstname);$DATA(n,lastname);$DATA(n,userid);&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clear löscht ein Kommando&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd_clear löscht das erste Kommando, #cmd_clear2 löscht das zweite Kommando, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #cmd_clear Zeichen, so werden die dem gerade gelöschten Kommando hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear3&lt;br /&gt;
 #cmd_clear #grd_add   i=grid   f_logtext=&amp;quot;Kunde angerufen und nicht erreicht.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#cmd_clearall==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clearall löscht alle Kommandos&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clearall&lt;br /&gt;
&lt;br /&gt;
=CSV=&lt;br /&gt;
&lt;br /&gt;
Die CSV-Routinen werden verwendet, um CSV-Dateien einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==#csv_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_open öffnet eine CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_open öffnet die erste CSV-Datei, #csv_open2 öffnet die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*ber - wenn Y, werden die Zeilenumbrüche innerhalb von Feldern durch Leerzeichen ersetzt. Die Felder müssen dabei in doppelten Anführungszeichen eingeschlossen sein.&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - (&amp;quot;Filename&amp;quot;) Dateiname der CSV-Datei&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich. Muss bereits hier gesetzt werden, wenn mit $CSV_LINE auf den Header zugegriffen werden soll, bevor #csv_line ausgeführt wird.&lt;br /&gt;
*txt (&amp;quot;Text&amp;quot;) - alternativ zum Dateinamen fn die Nummer eines Textes, der als CSV-Datei verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open  fn=c:\temp\text.csv&lt;br /&gt;
&lt;br /&gt;
==#csv_line==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_line geht zeilenweise durch die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_line geht durch die erste CSV-Datei, #csv_line2 geht durch die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;database&amp;quot;) - Die Datenbank, für welche die Transaktion ausgeführt wird, wenn ert=Y gesetzt ist. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
*er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
*ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt, Funktionen werden ersetzt&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich.&lt;br /&gt;
*m (&amp;quot;maximum&amp;quot;) - Maximale Anzahl der Zeilen, die verarbeitet wird. Wird gerne bei der Entwicklung verwendet, um die Bearbeitungsgeschwindigkeit zu erhöhen. Funktionen werden ersetzt&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird im Falle einer Exception die Bearbeitung nicht abgebrochen, sondern lediglich Warnungen geloggt; Default N, Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Semikolon, Funktionen werden ersetzt&lt;br /&gt;
*trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_line  er=test_csv_line   hhr=Y   m=3&lt;br /&gt;
&lt;br /&gt;
==#csv_check==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_check prüft die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnt (&amp;quot;count&amp;quot;) - Anzahl der Header-Einträge, die geprüft wird; Funktionen werden ersetzt&lt;br /&gt;
*h1, h2... (&amp;quot;header&amp;quot;) - Eintrag im Header, der auf existenz geprüft wird; Groß und Kleinschreibung ist unerheblich, Funktionen werden ersetzt.&lt;br /&gt;
*n (&amp;quot;name&amp;quot; / &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in die/den das Ergebnis (Y oder N) geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*res (&amp;quot;result&amp;quot;) - Name der Variable oder Nummer des Values, in die/den der Ergebnistext geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwischen den einzelnen Spalten; Funktionen werden ersetzt&lt;br /&gt;
*y - Typ der Prüfung; Funktionen werden ersetzt, default header&lt;br /&gt;
** header - Prüft die Existenz von Spaltennamen im Header. Die zu prüfenden Spaltennamen werden als h1, h2... übergeben, cnt ist entsprechend zu setzen. Wenn alle geprüften Spaltennamen vorhanden sind, wird Y zurück gegeben, ansonsten N. Die fehlenden Spaltennamen werden als Ergebnistext zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open   fn=C:\temp\mad\done\MTF3108_ET2607_selektion.CSV&lt;br /&gt;
 #csv_check   n=1   res=2   cnt=3   h1=eins   h2=zwei   h3=drei&lt;br /&gt;
 #coutl $VAL(1) - $VAL(2)&lt;br /&gt;
&lt;br /&gt;
==#csv_paste==&lt;br /&gt;
&lt;br /&gt;
Übernimmt eine CSV-Datei aus der Zwischenablage. Auf die Werte kann mit $SEPLINE() zugegriffen werden, siehe [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
'''Multi-Row'''&lt;br /&gt;
&lt;br /&gt;
Mit dem Multi-Row-Modus können Daten eingelesen werden, die in einer Zeile mehrere gleichartige Werte haben.&lt;br /&gt;
&lt;br /&gt;
Daten, die im Single-Row-Modus wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465&lt;br /&gt;
 01.01.2020     8574&lt;br /&gt;
 01.01.2020     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     3456&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     4457&lt;br /&gt;
 03.01.2020     7658&lt;br /&gt;
&lt;br /&gt;
Würden im Multi-Row-Modus wie folgt aussehen (und könnten auch so eingelesen werden):&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465     8574     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436     6578     3456     6578     4457     7658&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Wenn dieser Parameter einen Wert hat, dann muss die kopierte CSV-Datei in der ersten Zeile auch diesen Wert haben, oder die Aktion wird abgebrochen; Funktionen werden ersetzt&lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden.&lt;br /&gt;
* mrs (&amp;quot;multi row start&amp;quot;) - Erste Spalte für den Multi-Row-Bereich&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Tabulatorzeichen&lt;br /&gt;
* trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ; default s&lt;br /&gt;
** m - multi; siehe Abschnitt Multi-Row&lt;br /&gt;
** s - single; die CSV-Datei wird Zeile für Zeile eingelesen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
* [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
 #csv_paste   er=imp_line   hhr=Y&lt;br /&gt;
 #csv_paste   er=imp_line   y=m   mrs=1&lt;br /&gt;
&lt;br /&gt;
==$CSV()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV() greift auf einen Feldinhalt der aktuellen CSV-Zeile zu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Spalte oder 0-relative Spaltennummer. Name der Spalte setzt voraus, dass bei #csv_line der Parameter hhr gleich Y ist.&lt;br /&gt;
# optional: Stelle der Zeichens, ab dem der Inhalt des CSV-Feldes zurück gegeben wird&lt;br /&gt;
# optional: Anzahl der Zeichen, die maximal zurück gegeben werden; wird meist dafür verwendet, damit die maximale Länge von Datenbankfeldern nicht überschritten wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0)&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird in der ersten CSV-Datei (#csv_open) auf die erste Spalte (0, da 0-relativ) zugegriffen.&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0,1,30)&lt;br /&gt;
&lt;br /&gt;
Wie oben, nur werden nur die ersten 30 Zeichen zurück gegeben&lt;br /&gt;
&lt;br /&gt;
==$CSV_LINE()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV_LINE() Gibt eine ganze Zeile einer CSV-Datei zurück&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Zeile: header gibt die Header-Zeile zurück, current die aktuelle Zeile in #csv_line&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CSV_LINE wird insbesondere dafür verwendet, um CSV-Dateien mit Daten zu ergänzen. Hier im Beispiel wird jede Zeile mit einer GUID ergänzt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #text $CSV_LINE(1,current)$GUID();&lt;br /&gt;
 &lt;br /&gt;
 #csv_open   fn=c:\temp\ex.csv   hhr=Y&lt;br /&gt;
 #text_clear $CSV_LINE(1,header)guid;&lt;br /&gt;
 #csv_line   er=1   hhr=Y&lt;br /&gt;
 &lt;br /&gt;
 #text_save   fn=c:\temp\ex2.csv&lt;br /&gt;
&lt;br /&gt;
Nach dem Öffnen der bestehenden CSV-Datei (es muss hier bereits hhr gesetzt werden) wird zunächst der Header in Text 1 eingefügt, ergänzt um die Spalte ''guid'' und das abschließende Semikolon. Danach gehen wir mit #csv_line durch alle Zeile, fügen diese komplett in Text 1 ein und hängen eine GUID hinten dran. Danach wird die Datei gespeichert.&lt;br /&gt;
&lt;br /&gt;
=Text=&lt;br /&gt;
&lt;br /&gt;
==#text==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text fügt dem Text eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text fügt dem ersten Text eine Zeile hinzu, #text2 fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Und jetzt noch eine GUID: $GUID()&lt;br /&gt;
 #text Der folgende Text kommt in Großbuchstaben: $UPP(hello world)&lt;br /&gt;
&lt;br /&gt;
==#textn==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#textn fügt dem Text eine Zeile hinzu. Im Unterschied zu #text werden dabei keine Funktionen ersetzt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #textn fügt dem ersten Text eine Zeile hinzu, #text2n fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #textn und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden dabei '''nicht''' ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #textn Zeile 1&lt;br /&gt;
 #textn Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_clear löscht einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_clear löscht den ersten Text, #text_clear2 löscht den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #text_clear Zeichen, so werden die dem gerade gelöschten Text hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear7&lt;br /&gt;
 #text7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
Das vorangestellt #text_clear stellt sicher, dass Text7 leer ist. Alternativ könnte man formulieren:&lt;br /&gt;
&lt;br /&gt;
 #text_clear7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_save==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_save speichert einen Text in einer Datei.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_save speichert den ersten Text, #text_save2 speichert den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* bom (&amp;quot;Byte order mark&amp;quot;) - Wenn Y, dann wird die Datei mit BOM geschrieben; default Y&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu speichernden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname, unter dem die Datei gespeichert wird. Bestehende Dateien werden überschrieben, sofern das Betriebssystem das nicht verhindert (z.B, weil die Datei gerade geöffnet ist)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Öffnet die gespeicherte Datei gleich anschließend.&lt;br /&gt;
*sort - Wenn Y, dann wird die Datei vor dem Speichern sortiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Hello world&lt;br /&gt;
 #text_save  fn=$DIR(userroot)hello_world.txt&lt;br /&gt;
 #text_save  fn=c:\temp\export_vert_export.prepared_.csv   e=utf8   bom=N&lt;br /&gt;
&lt;br /&gt;
==#text_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_open öffnet einen Text aus einer Datei, der bisherige Inhalt der Datei wird überschrieben.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_open öffnet den ersten Text, #text_open2 öffnet den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname der Datei, die geöffnet wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_open  fn=$DIR(userroot)test.txt&lt;br /&gt;
 #text Eine weitere Zeile, $GUID()&lt;br /&gt;
 #text_save  fn=$DIR(userroot)test.txt&lt;br /&gt;
&lt;br /&gt;
==#text_props==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_props stellt Eigenschaften des Textes ein.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_props bezieht sich auf den ersten Text, #text_props2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* dub (&amp;quot;duplicates&amp;quot;) - Verhalten einer sortierten Liste bezüglich Dubletten&lt;br /&gt;
** acc (&amp;quot;accept&amp;quot;) - Dubletten werden akzeptiert&lt;br /&gt;
** err (&amp;quot;error&amp;quot;) - Dubletten führen zu Fehlern&lt;br /&gt;
** ign (&amp;quot;ignore) - Dubletten werden ignoriert&lt;br /&gt;
* srt (&amp;quot;sorted&amp;quot;) - Wenn ja, dann ist die Liste sortiert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_props   srt=Y   dup=ign&lt;br /&gt;
&lt;br /&gt;
==#text_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_set setzt eine bestimmte Zeile eines Textes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_set bezieht sich auf den ersten Text, #text_set2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;index&amp;quot;) - 0-relativer Index der Zeile, die geschrieben werden soll. Mit ''last'' kann die letzte Zeile geschrieben werden, mit ''all'' werden alle Zeilen ersetzt, das wird dann gebraucht, wenn mehrzeiliger Text zugewiesen werden soll; Funktionen werden ersetzt&lt;br /&gt;
* z - Text, der geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text_set   i=2   z=&amp;quot;dritte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=last   z=&amp;quot;letzte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=all   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
==#text_sort==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_sort sortiert einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_sort bezieht sich auf den ersten Text, #text_sort2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* y - Typ, default alpha, Funktionen werden ersetzt&lt;br /&gt;
** alpha - sortiert alphanumerisch&lt;br /&gt;
** inv - invertiert die gegebene Reihenfolge&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=&amp;quot;,OU=2nd_Level_T1,OU=Kundenservice,OU=Benutzer,OU=Testtours,OU=Travel&amp;quot;&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text_dissect   z=$VAL(1)   sep=&amp;quot;,OU=&amp;quot;&lt;br /&gt;
 #coutl  $TEXT(1)&lt;br /&gt;
 #text_sort   y=inv&lt;br /&gt;
 #text_compose   n=1   sep=.&lt;br /&gt;
 #val_set   n=1   z=tt.$VAL(1)&lt;br /&gt;
 #coutl $VAL(1)&lt;br /&gt;
&lt;br /&gt;
 Ergebnis ist:&lt;br /&gt;
 2nd_Level_T1&lt;br /&gt;
 Kundenservice&lt;br /&gt;
 Benutzer&lt;br /&gt;
 Testtours&lt;br /&gt;
 tt.Testtours.Benutzer.Kundenservice.2nd_Level_T1.&lt;br /&gt;
&lt;br /&gt;
==#text_dissect==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_dissect zerteilt einen String anhand einer vorgegebenen Trennzeichenfolge und fügt das Ergebnis dem betreffenden Text hinzu. Gegebenenfalls muss der Text vorher mit #text_clear geleert werden.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_dissect bezieht sich auf den ersten Text, #text_dissect bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - wenn Y, wird die sep-Zeichenfolge noch mal dem String angehängt; default N, Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, anhand der String zerteilt wird; Funktionen werden ersetzt&lt;br /&gt;
* z - String, der zerlegt wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_compose==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_compose setzt einen Text mithilfe eines Trennzeichens zu einem String zusammen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_compose bezieht sich auf den ersten Text, #text_compose bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - Wenn Y, wird die Trennzeichenfolge auch noch mal am Ende des Strings eingefügt; default N, Funktionen werden ersetzt&lt;br /&gt;
* n - Nummer des Values oder Name der Variable, in welche der String geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichenfolge, die beim Zusammenfügen des Textes verwendet wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_act==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_act bearbeitet einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_act bezieht sich auf den ersten Text, #text_act bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text der Zeile, die bei insert eingefügt werden soll; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* cu (&amp;quot;current&amp;quot;) - 0-relative Zeilennummer der Operation; default 0, Funktionen werden ersetzt&lt;br /&gt;
* ne (&amp;quot;new&amp;quot;) - 0-relative Zeilennummer als Ziel bei move; default 0, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt&lt;br /&gt;
** delete - Löscht die Zeile an Position cu (&amp;quot;current&amp;quot;)&lt;br /&gt;
** insert - Fügt den Text c an der Position cu (&amp;quot;current&amp;quot;) ein&lt;br /&gt;
** move - verschiebt die Zeile cu (&amp;quot;current&amp;quot;) nach Zeile ne (&amp;quot;new&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #text_act   y=move   cu=0&lt;br /&gt;
&lt;br /&gt;
==#text_loop==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_loop geht durch die Zeilen eines Textes und ruft für jede Zeile ''er'' auf&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_loop  bezieht sich auf den ersten Text, #text_loop2  bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich ert bezieht&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m - (&amp;quot;maximum&amp;quot;) Es wird maximal für die Anzahl der angegebenen Zeilen das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* n - Name der Variable, in welche die 0-relative Schleifenvariable geschrieben wird. (Es würde auch in einen Value geschrieben, wenn es sich um eine Nummer handelt, das ergibt in der Praxis aber meist nicht viel Sinn) Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear eins&lt;br /&gt;
 #text zwei&lt;br /&gt;
 #text drei&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear #coutl - $TEXT(1,$VAR(eins))&lt;br /&gt;
 #text_loop   er=1   n=eins&lt;br /&gt;
&lt;br /&gt;
==#tvl_add==&lt;br /&gt;
&lt;br /&gt;
Addiert dem Wert in einer Text-Valueliste einen Wert hinzu. Es handelt sich dabei um eine nummerierte Prozedur: #tvl_add arbeitet mit Text 1, #tvl_add2 mit Text 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Zeile, der ein Wert hinzugefügt wird; Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Operation, Funktionen werden ersetzt, default text&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
* z - Der Wert, der hinzugefügt wird&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text eins=1&lt;br /&gt;
 #text zwei=2&lt;br /&gt;
 #text drei=3&lt;br /&gt;
 #tvl_add   y=int   n=zwei   z=1&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==$TEXT()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $TEXT() wird auf den Inhalt des Textes zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# optional Zeile des Textes (0-relativ). Wenn es keinen zweiten Parameter gibt, wird der komplette Text zurück gegeben. Alternativ als zweiter Parameter eine Sonderfunktion:&lt;br /&gt;
## cnt / count - Gibt die Anzahl der Zeilen zurück&lt;br /&gt;
## last - Gibt die letzte Zeile zurück&lt;br /&gt;
## ix - Gibt die Position des Textes im dritten Parameter zurück&lt;br /&gt;
## as_line - Gibt den Text als eine Zeile zurück, Zeilenumbrüche werden durch den dritten Parameter ersetzt&lt;br /&gt;
# optional in abhängigkeit vom zweiten Paremeter&lt;br /&gt;
## wenn zweiter Parameter ix: Textzeile, nach der mit ix gesucht wird&lt;br /&gt;
## wenn zweiter Parameter as_line: Zeichenfolge, mit der die Zeilenumbrüche ersetzt werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Zeile 3&lt;br /&gt;
 #message  c=$TEXT(1)&lt;br /&gt;
&lt;br /&gt;
 #code url=$TEXT(1,as_line,&amp;amp;)&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich gilt in BAL: Eine Prozedur - eine Zeile.&lt;br /&gt;
&lt;br /&gt;
Bei vielen und/oder langen Parametern führt das zu recht langen Code-Zeilen und zu Unübersichtlichkeit. Hier können nun Teile der Parameter mit #code in weitere Zeile ausgelagert werden, deren Inhalt dann mit $CODE$ oder $CODE$ der eigentlichen Code-Zeile hinzugefügt wird.&lt;br /&gt;
&lt;br /&gt;
==#code==&lt;br /&gt;
&lt;br /&gt;
Fügt Text dem Code-Speicher hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#code hat keine benannten Parameter. Die ganze Zeile nach dem #code und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=G:\pics\pic5d68865cdaba62_62767562.jpg&lt;br /&gt;
 #code fn2=G:\pics\pic5d913c48682128_67979256.jpg&lt;br /&gt;
 #email_send   from=test@****.de   to=info@*****************.de   bcc=info@*****.de   subject=Testmail   text=$TEXT(1)   $CODE$&lt;br /&gt;
&lt;br /&gt;
==$CODE$ / $CODEN$==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CODE$ und $CODEN$ sind keine Funktionen, auch wenn sie auf den ersten Blick ähnlich aussehen. Sie haben keine Parameter und auch keine Klammern, dafür ein abschließendes $.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen fügen den Code-Speicher der jeweiligen Zeile hinzu. $CODE$ löscht danach den Code-Speicher, $CODEN$ tut das nicht, so dass dieselben Parameter wiederholt eingefügt werden können (beim letzten Einfügen sollte dann $CODE$ verwendet werden).&lt;br /&gt;
&lt;br /&gt;
=Separierte Zeile=&lt;br /&gt;
&lt;br /&gt;
Eine separierte Zeile ist eine Textzeile, die mehrere gleichartige Werte enthält, die durch Trennzeichen getrennt sind.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 3244,4465,7763,4536,4356,7777&lt;br /&gt;
&lt;br /&gt;
Solche Zeilen können mit #sepline aufgetrennt werden.&lt;br /&gt;
&lt;br /&gt;
==#sepline==&lt;br /&gt;
&lt;br /&gt;
Trennt eine separierte Zeile auf und führt für jeden Wert das mit er angegebene Kommando aus.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur (#sepline, #sepline2...)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y; Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, für welche die Transaktion gestartet wird, wenn ert=Y. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern (&amp;quot;each row no&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Wenn Y, wird für jeden Wert der separierten Zeile eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Es wird maximal für die Anzahl der angegebenen Werte das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten; Funktionen werden ersetzt.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N; Funktionen werden ersetzt.&lt;br /&gt;
* nn (&amp;quot;not null&amp;quot;) - Wenn Y, dann wird er nur für Werte der separierten Zeile aufgerufen, die nicht leer sind. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Das oder die Trennzeichen; default ist das Semikolon, Funktionen werden ersetzt.&lt;br /&gt;
* z - Der Inhalt der separierten Zeile; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(1)&lt;br /&gt;
 #sepline z=3244,4465,7763,4536,4356,7777   sep=,   er=1&lt;br /&gt;
&lt;br /&gt;
==$SEPLINE()==&lt;br /&gt;
&lt;br /&gt;
Greift auf den einzelnen Wert einer mit #sepline getrennten Zeile zu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der separierten Zeile&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(3)&lt;br /&gt;
 #sepline3 z=3244;4465;7763;4536;4356;7777     er=1&lt;br /&gt;
&lt;br /&gt;
=User und Rechte=&lt;br /&gt;
&lt;br /&gt;
Aus Gründen der Übersichtlichkeit ist die Rechtevergabe zweistufig:&lt;br /&gt;
&lt;br /&gt;
# Es werden (meist am Anfang eines Primär-Kommandos) Rechte-Definitionen erstellt, die einer oder mehreren Benutzergruppen Rechte (lesen oder lesen und schreiben) zuweisen. Die Rechte werden dabei implizit auch allen Untergruppen der angegebenen Benutzergruppe erteilt (Zum Beispiel: Rechte der Gruppe ''user'' hat auch implizit die Gruppe ''user.admin'').&lt;br /&gt;
# Dem Parameter r verschiedener Prozeduren kann dann eine Rechte-Definition zugewiesen werden.&lt;br /&gt;
&lt;br /&gt;
Den Parameter r als Rechte-Definition berücksichtigen die folgenden Prozeduren:&lt;br /&gt;
&lt;br /&gt;
* #frm&lt;br /&gt;
* Buttons (#btn, #btns_btn)&lt;br /&gt;
* Alle Segmente (#text_seg, #memo_seg, #btns_seg, vl_seg, #grd_seg, #xgrd_seg)&lt;br /&gt;
* Tree (#tree_add, #tree_fill, #tree_fillsql, Lese-Recht reicht)&lt;br /&gt;
* Grid-Spalten (#grd_col, #xgrd_col)&lt;br /&gt;
* #vl_line (für die komplette Zeile (r) und die einzelne Zelle (r1, r2, r3...))&lt;br /&gt;
&lt;br /&gt;
Wo der Parameter r nicht gesetzt ist, wird die Rechte-Definition der Formulars verwendet.&lt;br /&gt;
&lt;br /&gt;
==#rights==&lt;br /&gt;
&lt;br /&gt;
Setzt eine Rechte-Definition im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Rechte-Definition; default ist ''frm'', also dsa Default-Recht für das Formular.&lt;br /&gt;
* r_ (&amp;quot;right&amp;quot;) - Prefix für die Benutzergruppe. Für die Rechte-Definition sind die folgenden Werte zulässig&lt;br /&gt;
** n (&amp;quot;no&amp;quot;) - kein Recht&lt;br /&gt;
** r (&amp;quot;read&amp;quot;) - nur lesen&lt;br /&gt;
** w (&amp;quot;write&amp;quot;) - lesen und schreiben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights  n=frm   r_user=r   r_user.admin=w&lt;br /&gt;
&lt;br /&gt;
Setzt für alle User das Lese-Recht und für Administratoren das Lese- und Schreibrecht.&lt;br /&gt;
&lt;br /&gt;
==#rights_clear==&lt;br /&gt;
&lt;br /&gt;
Löscht alle Rechte-Definitionen im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
(Wird in der Praxis selten benötigt, weil Kommandos mit leerer Rechte-Definition starten.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights_clear&lt;br /&gt;
&lt;br /&gt;
==$USERID()==&lt;br /&gt;
&lt;br /&gt;
Die ID des angemeldeten Users&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kusr=$USERID()&lt;br /&gt;
&lt;br /&gt;
==$RIGHTUSERID()==&lt;br /&gt;
&lt;br /&gt;
Administratoren können andere User einstellen (Userliste links unten im BAF-Client), vor allem um deren Rechte zu prüfen. Die UserID dieses ausgewählten Users kann mit der Funktion $RIGHTUSERID() ermittelt werden.&lt;br /&gt;
&lt;br /&gt;
In fast allen Fällen gilt der folgende Grundsatz: Lesende Operationen mit $RIGHTUSERID(), schreibende Operationen mit $USERID().&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_open   kusr=$RIGHTUSERID()&lt;br /&gt;
&lt;br /&gt;
==$ADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der angemeldete User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $ADM()&lt;br /&gt;
&lt;br /&gt;
==$RADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der ausgewählte User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $RADM()&lt;br /&gt;
&lt;br /&gt;
=Ausführen=&lt;br /&gt;
&lt;br /&gt;
==#exec==&lt;br /&gt;
&lt;br /&gt;
Führt ein anderes Kommando aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Names des (Primär- oder Sub-) Kommandos, das ausgeführt werden soll.&lt;br /&gt;
* ex (&amp;quot;exception&amp;quot;) - Name oder Nummer des Kommandos, das ausgeführt wird, wenn bei der Ausführung von cmd eine Exception auftritt; siehe Beispiele&lt;br /&gt;
* fin (&amp;quot;finally&amp;quot;) - Name oder Nummer des Kommandos, das nach der Ausführung von cmd ausgeführt wird - egal ob eine Exception aufgetreten ist oder nicht. Wird nur berücksichtigt, wenn der Parameter ex nicht gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel löst das Problem, dass ein neues PDF unter demselben Dateinamen nicht erstellt werden kann, wenn beim vorherigen Versuche der Erstellung eine Exception aufgetreten ist. In einem solchen Fall wurde ein #pdf_start, aber kein #pdf_stop ausgeführt, und die geöffnete Datei sperrt diesen Dateiname, bis der BAF-Client geschlossen wird. Lösung dieses Problems ist es, im Parameter ex ein #pdf stop auszuführen; auf das Öffnen der Datei kann in einem solchen Fall verzichtet werden. Mit der Funktion $DATA() wird hier im Beispiel gezielt eine Exception ausgelöst.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test_pdf&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #pdf_text  c=&amp;quot;Hello World&amp;quot;&lt;br /&gt;
 -- #cmd #pdf_text  c=&amp;quot;Hello World $DATA(dat,test)&amp;quot;&lt;br /&gt;
 #cmd #pdf_stop   o=Y&lt;br /&gt;
 &lt;br /&gt;
 #pdf_start  fn=$DIR(doc)\test.pdf&lt;br /&gt;
 #exec   cmd=1   ex=&amp;quot;#pdf_stop   o=N&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test_pdf executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#batchexec==&lt;br /&gt;
&lt;br /&gt;
Speichert den Text n in der Datei batch.bat und führt diese aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clr (&amp;quot;clear&amp;quot;) - Wenn Y, wird der Text nach Ausführung des Batch-Datei gelöscht; Default Y; Funktionen werden ersetzt;&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes; der mit #text gespeicherte Text hat die Nummer 1 &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #batchexec   n=1&lt;br /&gt;
&lt;br /&gt;
==#file_open==&lt;br /&gt;
&lt;br /&gt;
Öffnet eine Datei (oder auch eine Webseite)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder die URL der Webseite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_open  fn=c:\temp\test.csv&lt;br /&gt;
 #file_open  fn=https://www.google.de&lt;br /&gt;
&lt;br /&gt;
==#loop==&lt;br /&gt;
&lt;br /&gt;
BAL kennt keine Schleifen als Sprachelement. Um Schleifen mit einer fest Schleifenzahl auszuführen, wird die Prozedur #loop verwendet. lf muss nicht kleiner als lt sein, #loop kann auch von oben nach unten zählen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* lf (&amp;quot;loop from&amp;quot;) - Anfangswert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* lt (&amp;quot;loop to&amp;quot;) - Endwert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in der die Schleifenvariable gespeichert wird (damit sie an anderer Stelle gelesen werden kann); Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #loop   lf=42   lt=1337   er=test_line&lt;br /&gt;
&lt;br /&gt;
==#exit==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #exit bricht die Ausführung auf der jeweiligen Code-Ebene (Kommando bzw. Sub-Kommando) ab&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 ~ $EMPTY($PVAL(vl,id))   and   $PVAL(vl,status) &amp;gt; 20&lt;br /&gt;
 #sql select nextval('ausza_id') as id&lt;br /&gt;
 #sql_openval   f_id=1&lt;br /&gt;
 #page_val   i=vl   f=id   z=$VAL(1)&lt;br /&gt;
 #save&lt;br /&gt;
 #exit&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Der Beispiel-Code befindet sich auf der Seite xausza_page_ausza und baut die entsprechende Seite auf. Er prüft, ob bereits eine ID-Gesetzt ist - wenn nicht, wird über eine Datenbank-Sequenz die nächste ID abgefragt, in das VL-Segment geschrieben und die Seite gespeichert. Beim Speichern der Seite wird sie jedoch neu aufgerufen, also komplett neu aufgebaut, was erst einmal kein Problem ist. Danach würde aber die Ausführung auf der Code-Ebene, auf der sich #save befindet, fortgeführt, was zur Folge hat, dass die dann folgenden Segmente doppelt erscheinen (zunächst die aus dem Neu-Aufbau der Seite, dann die, die von der Fortsetzung des Codes her stammen).&lt;br /&gt;
&lt;br /&gt;
Um dies zu vermeiden muss die Ausführung des Codes nach #save abgebrochen werden.&lt;br /&gt;
&lt;br /&gt;
==$EXEC==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando. Im ausgeführten Kommando kann eine Variable gesetzt werden, die dann als Funktionsergebnis von $EXEC zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll&lt;br /&gt;
# optional: Der Name der Variablen, in der das Ergebnis steht; default ist ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;test_funkexec&amp;quot;   y=console&lt;br /&gt;
 #cout   c=$EXEC(test_funkexec_line)&lt;br /&gt;
&lt;br /&gt;
 -- test_funkexec_line&lt;br /&gt;
 #var_set   n=result   z=42&lt;br /&gt;
&lt;br /&gt;
=Dateien und Verzeichnisse=&lt;br /&gt;
&lt;br /&gt;
==#file_op==&lt;br /&gt;
&lt;br /&gt;
Führt eine Operation mit einer Datei oder einem Verzeichnis aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder des Verzeichnisses&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in die/den das Ergebnis der Operation (Y oder N) geschrieben wird.&lt;br /&gt;
* on (&amp;quot;old name) - der bisherige Dateiname bei RenameFile&lt;br /&gt;
* y - Typ der Operation&lt;br /&gt;
** cd / createdir - Erzeugt ein Verzeichnis&lt;br /&gt;
** cf / copyfile - Kopiert eine Datei (von on zu fn)&lt;br /&gt;
** df / deletefile - Löscht eine Datei&lt;br /&gt;
** fd / forcedirectories - Stellt sicher, dass ein Pfad vorhanden ist&lt;br /&gt;
** rd / removedir - Entfernt ein Verzeichnis&lt;br /&gt;
** rf / renamefile - Benennt eine Datei um, kann auch dazu verwendet werden, eine Datei zu verschieben&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #file_op   y=renamefile   on=c:\temp\debug.txt   fn=c:\temp\test\debug.txt   n=1&lt;br /&gt;
 #cout   c=$VAL(1)&lt;br /&gt;
 &lt;br /&gt;
 #file_op   y=fd   fn=c:\eins\zwei\drei\vier&lt;br /&gt;
&lt;br /&gt;
==#file_search==&lt;br /&gt;
&lt;br /&gt;
Sucht Dateien und schreibt die Ergebnisliste in einen Text.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* clr - (&amp;quot;clear&amp;quot;) wenn Y, wird der Text vor der Suche geleert. Default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, in den die Ergebnisliste geschrieben wird; default 1, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_search   fn=c:\*.ini   n=1   y=0   all_=Y&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==#file_wait==&lt;br /&gt;
&lt;br /&gt;
Wartet, bis zumindest eine Datei vorhanden ist, die den Kriterien entspricht, und führt dann cmd aus. Wird nach der in to eingestellten Zeit keine Datei gefunden, dann wird mit dem in cmdto eingestellten Kommando abgebrochen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* cmd - Kommando, das ausgeführt wird, sobald eine Datei gefunden wird; Funktionen werden ersetzt&lt;br /&gt;
* cmdto - Kommando, das ausgeführt wird, sobald die Prozedur wegen eines TimeOuts abgebrochen wird; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* sleep - Zeit in ms zwischen den einzelnen Suchen nach einer Datei, die den Kriterien entspricht; Default 1000, Funktionen werden ersetzt&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in ms, nach der die Ausführung abgebrochen wird; Default 15000, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #cout c=&amp;quot;Gefunden&amp;quot;&lt;br /&gt;
 #cmd_clear2 #cout c=&amp;quot;TimeOut&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #file_wait   fn=C:\temp\test\*.txt   cmd=1   cmdto=2&lt;br /&gt;
&lt;br /&gt;
==#dir_force==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass es den spezifizierten Verzeichnispfad gibt, indem erforderlichenfalls Verzeichnisse angelegt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Names des Pfads&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_force   n=c:\temp\pdf&lt;br /&gt;
&lt;br /&gt;
==#dir_proc==&lt;br /&gt;
&lt;br /&gt;
Durchsucht ein Verzeichnis nach Dateien, die den angegebenen Kriterien entsprechen, und führt für jede gefundene Datei ''cmd'' aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das für jede gefundene Datei ausgeführt wird&lt;br /&gt;
* dn (&amp;quot;DirectoryName&amp;quot;) - Pfad des Verzeichnisses, in dem die Dateien gesucht werden; Funktionen werden ersetzt.&lt;br /&gt;
* done - Verzeichnis, in das die Dateien nach Abarbeitung verschoben werden (sofern der Parameter nicht leer ist). Funktionen werden ersetzt.&lt;br /&gt;
* fn (&amp;quot;filename&amp;quot;) - Suchkriterium für den Dateinamen; Funktionen werden ersetzt; Default *&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in welcher der Dateiname der aktuell zu bearbeitenden Datei inklusive Pfad gespeichert wird; Funktionen werden ersetzt; Default dir_proc&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_proc   dn=c:\temp\in   done=c:\temp\done   fn=*.csv   cmd=importcsv_line&lt;br /&gt;
&lt;br /&gt;
==$FILEINFO()==&lt;br /&gt;
&lt;br /&gt;
Liefert Infos über eine Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Dateiname&lt;br /&gt;
# Typ der Information, es stehen dabei folgende Optionen zur Verfügung&lt;br /&gt;
#* size - Dateigröße in Byte&lt;br /&gt;
#* size_point - Dateigröße in Byte, Punkte alle drei Zeichen von rechts&lt;br /&gt;
#* size_auto - Dateigröße in Byte, kB, MB oder GB, je nach Größe; mit Einheit&lt;br /&gt;
#* size_kb - Dateigröße in kB (analog Windows-Explorer)&lt;br /&gt;
#* date - Datum im Format dd.mm.yyyy&lt;br /&gt;
#* date_yyyy - Datum im Format yyyymmdd&lt;br /&gt;
#* datetime - Datum und Uhrzeit im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
#* datetime_yyyy - Datum im Format yyyymmddhhmmss&lt;br /&gt;
#* exists - Y, wenn die Datei existiert, sonst N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=fn   z=&amp;quot;T:\Tools Gruppenrechte\BC3 light\BafClientFM.exe&amp;quot;&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_point)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_auto)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_kb)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),exists)&lt;br /&gt;
&lt;br /&gt;
Ergebnis&lt;br /&gt;
&lt;br /&gt;
 27668480&lt;br /&gt;
 27.668.480&lt;br /&gt;
 26,39 MB&lt;br /&gt;
 27.020 kB&lt;br /&gt;
 02.05.2023&lt;br /&gt;
 20230502&lt;br /&gt;
 02.05.2023 12:20:09&lt;br /&gt;
 20230502122009&lt;br /&gt;
 Y&lt;br /&gt;
&lt;br /&gt;
==$DIR()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Verzeichnisnamen. Trailing Path Delimiter (\ bei Windows) wird immer angehängt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bezeichnung des Verzeichnisses&lt;br /&gt;
## appdata - Verzeichnis für Anwendungsdaten des Users&lt;br /&gt;
## cappdata - gemeinsames Verzeichnis für Anwendungsdaten aller User&lt;br /&gt;
## cdoc - gemeinsames Dokumentenverzeichnis  aller User&lt;br /&gt;
## cfav / cfavorites - gemeinsames Favoritenverzeichnis aller User&lt;br /&gt;
## cmusic - gemeinsames Musikverzeichnis aller User&lt;br /&gt;
## cpic / cpictures - gemeinsames Bilderverzeichnis aller User&lt;br /&gt;
## cvideo - gemeinsames Videoverzeichnis aller User&lt;br /&gt;
## desktop - Desktopverzeichnis des Rechners&lt;br /&gt;
## '''doc''' / docdir - Dokumentenverzeichnis des Users&lt;br /&gt;
## downloads - Downloadsverzeichnis des Users&lt;br /&gt;
## fav / favorites - Favoritenverzeichnis des Users&lt;br /&gt;
## fonts - Fontsverzeichnis des Rechners&lt;br /&gt;
## music - Musikverzeichnis des Users&lt;br /&gt;
## pic / pictures - Bilderverzeichnis des Users&lt;br /&gt;
## prog / program - Programmverzeichnis des Rechners&lt;br /&gt;
## prog86 / program86 - Programm86-Verzeichnis des Rechners&lt;br /&gt;
## '''root''' - Root-Verzeichnis des BAF-Clients bzw. des BAF-Servers&lt;br /&gt;
## '''userroot''' / usrroot - User-Verzeichnis des BAF-Clients&lt;br /&gt;
## video - Videoverzeichnis des Users&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=$DIR(doc)test.txt&lt;br /&gt;
&lt;br /&gt;
==$FILEDIALOG()==&lt;br /&gt;
&lt;br /&gt;
Führt einen Dateiauswahl-Dialog aus und gibt den gewählten Dateinamen zurück. Im Falle des Abbruchs wird ''abort'' zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wenn der erste Parameter ''save'' lautet, wird ein Speichern-Dialog, sonst ein Öffnen-Dialog aufgerufen.&lt;br /&gt;
# Filter-Statement, immer Kombinationen aus Text (Text-Dateien *.txt) und Filter-Statement(*.txt), getrennt durch Pipes.&lt;br /&gt;
# Standard-Dateierweiterung&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=&amp;quot;$FILEDIALOG(save,Text-Dateien *.txt|*.txt|Alle Dateien *.*|*.*,txt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Bitte beachten: Wegen der Leerzeichen im Filter-Statement muss der ganze Parameter in doppelte Anführungszeichen gesetzt werden.)&lt;br /&gt;
&lt;br /&gt;
=ZIP=&lt;br /&gt;
&lt;br /&gt;
==#zip_create==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine ZIP-Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Dateien, die der ZIP-Datei hinzugefügt werden; Funktionen werden ersetzt&lt;br /&gt;
* dir (&amp;quot;directory&amp;quot;) - Verzeichnis, wenn das nicht bei allen fn1, fn2... angegeben werden soll&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Der Dateiname, unter dem die ZIP-Datei gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* fn1, fn2,... (&amp;quot;FileName&amp;quot;) - Die Dateien, die in der ZIP-Datei gespeichert werden; die Anzahl wird mit dem Parameter cnt bestimmt; Funktionen werden ersetzt&lt;br /&gt;
* list - Nummer eines Textes (#text, #text2...), in dem die Dateien gelistet sind, die der ZIP-Datei hinzugefügt werden sollen. Wenn list ein Wert größer 0 hat, werden cnt und fn1, fn2... ignoriert. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* pw (&amp;quot;PassWord&amp;quot;) - Password der erzeugten ZIP-Datei; Funktionen werden ersetzt.&lt;br /&gt;
* pwc (&amp;quot;PassWordCrypted&amp;quot;) - Wenn Y, dann ist das Passwort mit der Verschlüsselungsfunktion auf der Seite Tools des Code-Dialogs verschlüsselt. Hinweis: Mit dieser Verschlüsselung verhindert man lediglich, dass das Passwort direkt aus dem Code ausgelesen werden kann. Wird der BAF-Client mit dem Delphi-Debugger ausgeführt, lässt sich leicht an die betreffende Stelle ein Breakpoint setzen und das Passwort dann im Klartext auslesen (dieselbe Unit uBafCrypt vorausgesetzt).&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #zip_create   fn=$VAR(root).zip   list=1&lt;br /&gt;
 &lt;br /&gt;
 #var_set   n=fn_zip   z=tt_mail_$VAR(reise)-$VAR(reisename)_$PAD($VAR(lfdnr),4,L,0)_$NOWFMT(yyyymmdd).zip&lt;br /&gt;
 #file_op   y=df   fn=$VAR(path)\$VAR(fn_zip)&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=$VAR(filename).txt&lt;br /&gt;
 #code fn2=$VAR(filename).sab&lt;br /&gt;
 #zip_create   dir=$VAR(path)   fn=$VAR(path)\$VAR(fn_zip)    pw=$VAR(pw)   $CODE$&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #zip_create ersetzt nicht vorherige Dateien. Von daher im Zweifelsfall wie im zweiten Beispiel vorher eine Datei dieses Namens löschen.&lt;br /&gt;
&lt;br /&gt;
=Ini-Dateien=&lt;br /&gt;
&lt;br /&gt;
Der BAF-Client verwendet eine Ini-Datei im Root-Verzeichnis (vor allem für die Datenbankverbindungen) und eine Ini-Datei ''BafClientFM.ini'' im User-Anwendungsverzeichnis (vor allem für die Formularpositionen). Es können aber auch weitere Ini-Dateien verwendet werden.&lt;br /&gt;
&lt;br /&gt;
==#ini_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Ini-Datei. #ini_val ist eine nummerierte Prozedur: #ini_val schreibt in die erste Ini-Datei, #ini_val2 in die zweite Ini-Datei und so weiter. Diese Ini-Dateien werden zunächst nur im Speicher gehalten und müssen explizit aus einer Datei geladen oder in eine Datei gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;item&amp;quot; / &amp;quot;ident&amp;quot;) - Name des Eintrags in der Ini-Datei; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Wenn der Parameter n den Wert ''usr'' oder ''user'' hat, dann bleibt die Nummer der Ini-Datei unberücksichtigt und der Wert wird in die Datei ''BafClientFM.ini'' im im User-Anwendungsverzeichnis geschrieben.&lt;br /&gt;
* sec (&amp;quot;section&amp;quot;) - Abschnitt in der Ini-Datei; Funktionen werden ersetzt; default ''values''&lt;br /&gt;
* z - Wert, der in die Ini-Datei geschrieben wird; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_val  i=date_last   z=$NOW()&lt;br /&gt;
&lt;br /&gt;
==#ini_load==&lt;br /&gt;
&lt;br /&gt;
Lädt eine Ini-Datei aus einer Datei. Es handelt sich um eine nummerierte Prozedur: #ini_load lädt die Ini-Datei 1, #ini_load2 lädt die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, die geladen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_load   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==#ini_save==&lt;br /&gt;
&lt;br /&gt;
Speichert eine Ini-Datei ineine Datei. Es handelt sich um eine nummerierte Prozedur: #ini_save speichert die Ini-Datei 1, #ini_save2 speichert die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, in die gespeichert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_save   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==$INI()==&lt;br /&gt;
&lt;br /&gt;
Liest einen Wert aus einer Ini-Datei.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
# Item (Ident)&lt;br /&gt;
# optional: Sektion; wenn nicht vorhanden, dann ''values''. Wenn ''db!'', dann wird als Sektion die aktuell gewählte Datenbankverbindung verwendet (in diesem Fall sollte als erster Parameter ''root'' verwendet werden).&lt;br /&gt;
# optional: Default-Wert; wenn nicht vorhanden, dann ein leerer String&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum)&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum,bearbeitung,$TODAY())&lt;br /&gt;
&lt;br /&gt;
==$INITEXT()==&lt;br /&gt;
&lt;br /&gt;
Gibt die komplette Ini-Datei zurück. Wird vor allem beim Debugging verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $INITEXT(usr)&lt;br /&gt;
&lt;br /&gt;
=Zwischenablage=&lt;br /&gt;
&lt;br /&gt;
Das BAF-Framework unterstützt die Zwischenablage nur für Text.&lt;br /&gt;
&lt;br /&gt;
==#clipboard==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Text in die Zwischenablage&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* z - Wert, der in der Zwischenablage gespeichert werden soll; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #clipboard   z=$TEXT()&lt;br /&gt;
 #clipboard   z=$CHR(dquote)$PVAL(test,zahl,allsel,$CHR(crlf))$CHR(dquote)&lt;br /&gt;
&lt;br /&gt;
==$CLIPBOARD()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Text aus der Zwischenablage zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setvar   n=clp   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
=String-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben einen String zurück.&lt;br /&gt;
&lt;br /&gt;
==$BASE64()==&lt;br /&gt;
&lt;br /&gt;
En- oder Decodiert einen Text im Base64-Code&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Encoding oder Decoding:&lt;br /&gt;
## e - Encoding&lt;br /&gt;
## d - Decoding&lt;br /&gt;
# Text, der en-oder decodet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $BASE64(e,Dies ist ein Test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$CHR()==&lt;br /&gt;
&lt;br /&gt;
Gibt ein Zeichen (ggf zwei Zeichen) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Ansi-Zeichennummer oder eine der folgenden Bezeichnungen:&lt;br /&gt;
## crlf - Zeilenumbruch #13#10&lt;br /&gt;
## cr - Zeichen #13&lt;br /&gt;
## lf - Zeichen #10&lt;br /&gt;
## tab - Tabulator&lt;br /&gt;
## quote - ' (einfache Anführungszeichen)&lt;br /&gt;
## dquote - &amp;quot; (doppelte Anführungszeichen)&lt;br /&gt;
## space / leer - Leerzeichen&lt;br /&gt;
## comma / komma - , (Komma)&lt;br /&gt;
## questionmark / qmark / frage / fragezeichen - ?&lt;br /&gt;
## bro / bracket_open - (&lt;br /&gt;
## brc / bracket_close - )&lt;br /&gt;
## dollar - $&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CONVERT()==&lt;br /&gt;
&lt;br /&gt;
Konvertiert einen String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Konvertierungsfunktion&lt;br /&gt;
## isodate&lt;br /&gt;
## isodatetime&lt;br /&gt;
## truefalse&lt;br /&gt;
## pointfloat&lt;br /&gt;
## urlcode&lt;br /&gt;
## utf8&lt;br /&gt;
# String, der konvertiert werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $CONVERT(isodate,2025-03-12)&lt;br /&gt;
 #coutl $CONVERT(isodatetime,2025-03-12 12:03:17)&lt;br /&gt;
 #coutl $CONVERT(truefalse,true)&lt;br /&gt;
 #coutl $CONVERT(pointfloat,12.3)&lt;br /&gt;
 #coutl $CONVERT(urlcode,Für schönen Ärger)&lt;br /&gt;
 #coutl $CONVERT(utf8,Für schönen Ärger)&lt;br /&gt;
&lt;br /&gt;
(Ergebnis)&lt;br /&gt;
 12.03.2025&lt;br /&gt;
 12.03.2025 12:03:17&lt;br /&gt;
 Y&lt;br /&gt;
 12,3&lt;br /&gt;
 F%C3%BCr%20sch%C3%B6nen%20%C3%84rger&lt;br /&gt;
 Für schönen Ärger&lt;br /&gt;
&lt;br /&gt;
==$COPY()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$COPY($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$EXEC()==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando aus und gibt ein Funktionsergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll.&lt;br /&gt;
# optional: Name der Variable, die als Funktionsergebnis zurück gegeben werden soll; default ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=test   z=$EXEC(testkommando)&lt;br /&gt;
&lt;br /&gt;
==$GUID()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine GUID und gibt sie zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# optional: Name einer Variablen, in welcher die GUID zusätzlich gespeichert wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kid=$GUID()&lt;br /&gt;
&lt;br /&gt;
==$HASH()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt einen Hash-Wert vom String im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, von welchem der Hash gebildet werden soll.&lt;br /&gt;
# zu verwendender Hash-Algorithmus:&lt;br /&gt;
## sha512&lt;br /&gt;
## sha512_256&lt;br /&gt;
## sha512_224&lt;br /&gt;
## sha384&lt;br /&gt;
## sha256&lt;br /&gt;
## sha224&lt;br /&gt;
## sha1&lt;br /&gt;
## md5 (Hinweis: MD5 gilt seit Längerem als nicht mehr sicher. Verwenden Sie ihn nur, wenn dies aus Gründen der Abwärts-Kompatbilität zwingend ist.)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$HASH($PVAL(vl,1,2),sha512)&lt;br /&gt;
&lt;br /&gt;
==$INCLUDE()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass der als dritter Parameter übergebene Text am Anfang oder am Ende steht, gegebenenfalls wird er dort eingefügt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## lead(oder leading) - Text muss am Anfang stehen&lt;br /&gt;
## leadci(oder leadingci oder leadingcaseinsensitive) - Text muss am Anfang stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
## trail(oder trailing) - Text muss am Ende stehen&lt;br /&gt;
## trailci(oder trailci oder trailingcaseinsensitive) - Text muss am Ende stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
# Text, in den gegebenenfalls eingefügt wird&lt;br /&gt;
# Text, der gegebenenfalls eingefügt wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCLUDE(trailci,test.PDF,.pdf)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$INVLOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Key aus einer Nachschlageliste bei Übergabe des Values.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Value des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$INVLOOKUP(general_status,aktiv,Wert nicht vorhanden)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus einer Nachschlageliste.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Key des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$LOOKUP(general_status,1,Status nicht gesetzt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOW()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Kleinbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Kleinbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LOW($EDT(edt1)) = bus&lt;br /&gt;
&lt;br /&gt;
==$LOWNOSPACE()==&lt;br /&gt;
&lt;br /&gt;
Wandelt einen String in Kleinbuchstaben und ersetzt alle Leerzeichen durch Unterstriche.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der gewandelt werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$LOWNOSPACE($PVAL(vl,1,2))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$NOCRLF()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Zeilenumbrüche&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem die Zeilenumbrüche entfernt werden sollen&lt;br /&gt;
# optional: Zeichenfolge, die an Stelle der Zeilenumbrüche eingefügt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=2   z=$NOCRLF($VAL(1),;)&lt;br /&gt;
&lt;br /&gt;
==$NVL()==&lt;br /&gt;
&lt;br /&gt;
Liefert einen Ersatzwert, wenn der Wert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird, wenn der erste Parameter leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   where ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0)&lt;br /&gt;
&lt;br /&gt;
Liefert $PVAL einen leeren Wert zurück (z.B., weil die Gridzeile neu angelegt wurde und daher noch keine Nummer eingetragen ist), so wird statt dessen 0 verwendet, damit die WHERE-Klausel syntaktisch korrekt ist.&lt;br /&gt;
&lt;br /&gt;
==$ONLYCHAR()==&lt;br /&gt;
&lt;br /&gt;
Entfernt unerwünschte Zeichen aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# optional: Typ der Funktion&lt;br /&gt;
## (leer) - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z', 'ä', 'ö', 'ü', 'Ä','Ö', 'Ü', 'ß']) sind&lt;br /&gt;
## charnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind&lt;br /&gt;
## low - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## upp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## charnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## charnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## uml - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z') sind, Umlaute werden konvertiert (ä -&amp;gt; ae, ö -&amp;gt; oe, ü -&amp;gt; ue, Ä -&amp;gt; Ae, Ö -&amp;gt; Oe, Ü -&amp;gt; Ue, ß -&amp;gt; ss)&lt;br /&gt;
## umlcharnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Umlaute werden konvertiert&lt;br /&gt;
## umllow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## no191 / not191 - Es werden alle Zeichen mit der ANSI-Nummer 191 (¿) entfernt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg)&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg,umllow)&lt;br /&gt;
&lt;br /&gt;
==$PAD()==&lt;br /&gt;
&lt;br /&gt;
Füllt links oder rechts bis zur vorgegebenen Länge mit Zeichen auf.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# Soll-Länge. Ist der ursprüngliche String bereits länger, wird er nicht gekürzt, es werden aber auch keine weiteren Zeichen hinzugefügt&lt;br /&gt;
# Wenn L, werden die Zeichen vorne hinzugefügt, andernfalls hinten&lt;br /&gt;
# Zeichen, die soweit und so oft hinzugefügt werden, bis die Soll-Länge erreicht ist. Umfasst der Parameter mehrere Zeichen, werden diese ggf. nicht alle hinzugefügt.&lt;br /&gt;
# optional: Länge, auf die der ursprüngliche String vor der weiteren Verarbeitung gekürzt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   text1 = '$PAD($VAR(text1),70,R, )'&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ des Ergebnisses&lt;br /&gt;
## curr - Zahl mit zwei Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## curr4 - Zahl mit vier Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## date - Datum in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## int - ganze Zahl  in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## ld - Key einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ldv - Value einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ls - Key eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## lsv - Value eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## text, text2, text3... - Zeile eines Textes&lt;br /&gt;
# untere Grenze bzw. Name der Nachschlageliste oder des Specials&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $RANDOM(date,01.01.2022,31.12.2022)&lt;br /&gt;
 #coutl $RANDOM(text2)&lt;br /&gt;
&lt;br /&gt;
==$SUBSTR()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Selbe Funktionalität wie $COPY())&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$SUBSTR($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$STREP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string replace&amp;quot;) Ersetzt Zeichen im String durch andere Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, in welchen Zeichen ersetzt werden sollen.&lt;br /&gt;
# Zeichen, die ersetzt werden sollen&lt;br /&gt;
# Zeichen, die an deren Stelle treten sollen&lt;br /&gt;
# optional: Optionen (kombinierbar)&lt;br /&gt;
## i - Groß- und Kleinschreibung ignorieren &lt;br /&gt;
## a - Alle Vorkommen ersetzen (andernfalls wird nur das erste Vorkommen ersetzt)&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=&amp;quot;$STREP($PVAL(vl,1,2), ,_,a)&amp;quot;&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$STREP($PVAL(vl,1,2),$CHR(space),_,a)&lt;br /&gt;
&lt;br /&gt;
Hinweis: Beide Beispiele haben exakt dieselbe Funktion. Im oberen Beispiel steht das Leerzeichen direkt im Text, dafür muss der komplette Parameter in doppelte Anführungszeichen, im unteren Beispiel wird das Leerzeichen durch $CHR(space) eingefügt, dafür können die Leerzeichen unterbleiben.&lt;br /&gt;
&lt;br /&gt;
==$STROP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string operation&amp;quot;) Sammelsurium von String-Operationen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## trim - entfernt führende und folgende Leerzeichen&lt;br /&gt;
## trimleft - entfernt führende Leerzeichen&lt;br /&gt;
## trimright - entferne folgende Leerzeichen&lt;br /&gt;
## quote - setzt den String in einfache Anführungszeichen&lt;br /&gt;
## unquote - entfernt einschließende einfache Anführungszeichen&lt;br /&gt;
## dquote - setzt den String in doppelte Anführungszeichen&lt;br /&gt;
## unqduote - entfernt einschließende doppelte Anführungszeichen&lt;br /&gt;
## ex_filepath - entspricht der Delphi-Funktion ExtractFilePath&lt;br /&gt;
## ex_filedir - entspricht der Delphi-Funktion ExtractFileDir&lt;br /&gt;
## ex_filedrive - entspricht der Delphi-Funktion ExtractFileDrive&lt;br /&gt;
## ex_filename - entspricht der Delphi-Funktion ExtractFileName&lt;br /&gt;
## ex_fileext - entspricht der Delphi-Funktion ExtractFileExt&lt;br /&gt;
# String, der bearbeitet werden soll&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$STROP(quote,Test)&lt;br /&gt;
&lt;br /&gt;
==$STREXTR()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string extract&amp;quot;) Extrahiert einen Teil aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem extrahiert werden soll&lt;br /&gt;
# Extraktionstyp&lt;br /&gt;
## ffe (&amp;quot;from first exclude&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## ffi (&amp;quot;from first include&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tfe (&amp;quot;to first exclude&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tfi (&amp;quot;to first include&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## fle (&amp;quot;from last exclude&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## fli (&amp;quot;from last include&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tle (&amp;quot;to last  exclude&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tli (&amp;quot;to last include&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Trennzeichen&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffe,;)&amp;quot;    -- Ergebnis: test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffi,;)&amp;quot;    -- Ergebnis: ;test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfe,;)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfi,;)&amp;quot;    -- Ergebnis: test;&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;!§§test2,tfe,;!§§)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
&lt;br /&gt;
==$TRIM()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Leerzeichen und Zeilenumbrüche am Rand des Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der getrimmt werden soll&lt;br /&gt;
# optional&lt;br /&gt;
## L - trimmt nur auf der linken Seite&lt;br /&gt;
## R - trimmt nur auf der rechten Seite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$TRIM($VAL(1),R)&lt;br /&gt;
&lt;br /&gt;
==$UPP()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Großbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Großbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $UPP($EDT(edt1)) = BUS&lt;br /&gt;
&lt;br /&gt;
==$VT()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VT (&amp;quot;Value Translate&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Vergleichswert 1&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 1 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 2&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 2 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 3&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 3 dem ersten Parameter entspricht &lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VT(Frau,1,Herr,2,Frau,3)&lt;br /&gt;
 -- Frau -&amp;gt; 3&lt;br /&gt;
 -- Herr -&amp;gt; 2&lt;br /&gt;
 -- Test -&amp;gt; 1&lt;br /&gt;
 -- Firma -&amp;gt; 1&lt;br /&gt;
&lt;br /&gt;
==$VTVL()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VTVL (&amp;quot;Value Translate ValueList&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu $VT werden die zu prüfenden Werte und deren Entsprechungen nicht über Parameter übergeben, sondern aus einer Werte-Liste geholt, die in einem Text gespeichert sein muss.&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich wie folgt aufbauen&lt;br /&gt;
&lt;br /&gt;
 key1=value1&lt;br /&gt;
 key2=value2&lt;br /&gt;
 key3=value3&lt;br /&gt;
 key4=value4&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich auch mit #sql_opentvl erzeugen, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Nummer des Textes, in dem sich die Werteliste befindet.&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select userid as ckey, shortname as cvalue from user_user&lt;br /&gt;
 #sql_opentvl n=1&lt;br /&gt;
 #coutl $VTVL(591,(nicht gefunden),1)&lt;br /&gt;
&lt;br /&gt;
==$XR()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $XR (&amp;quot;XmlReplace&amp;quot;) ersetzt in XML nicht zulässige Zeichen:&lt;br /&gt;
* aus &amp;amp; wird $amp ;&lt;br /&gt;
* aus &amp;lt; wird &amp;amp;lt ;&lt;br /&gt;
* aus &amp;gt; wird &amp;amp;gt ;&lt;br /&gt;
* aus &amp;quot; wird &amp;amp;quot ;&lt;br /&gt;
* aus ' wird &amp;amp;apos ;&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Das Leerzeichen vor dem Semikolon soll verhindern, dass die Zeichen hier in der Darstellung ersetzt werden und wird nicht eingefügt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text &amp;lt;firmenname&amp;gt;$XR($DATA(dat,firmenname))&amp;lt;/firmenname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==$XRR()==&lt;br /&gt;
&lt;br /&gt;
Umkehrfunktion von $XR()&lt;br /&gt;
* aus $amp ; wird &amp;amp;&lt;br /&gt;
* aus &amp;amp;lt ; wird &amp;lt;&lt;br /&gt;
* aus &amp;amp;gt ; wird &amp;gt;&lt;br /&gt;
* aus &amp;amp;quot ; wird &amp;quot;&lt;br /&gt;
* aus &amp;amp;apos ; wird '&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
=Integer-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben eine ganze Zahl zurück&lt;br /&gt;
&lt;br /&gt;
==$DEC()==&lt;br /&gt;
&lt;br /&gt;
Verringert die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die verringert werden soll.&lt;br /&gt;
# optional: Zahl, um die verringert werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$DEC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ICALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit ganzzahligen Werten durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator, es stehen zur Verfügung&lt;br /&gt;
## +&lt;br /&gt;
## -&lt;br /&gt;
## *&lt;br /&gt;
## div&lt;br /&gt;
## mod&lt;br /&gt;
# Erste Zahl&lt;br /&gt;
# Zweite Zahl&lt;br /&gt;
# optional beim Operator +: weitere Summanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$ICALC(mod,17,5)&lt;br /&gt;
&lt;br /&gt;
==$INC()==&lt;br /&gt;
&lt;br /&gt;
Erhöht die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die erhöht werden soll.&lt;br /&gt;
# optional: Zahl, um die erhöht werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$INC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$INTLEN()==&lt;br /&gt;
&lt;br /&gt;
Ist der String im Parameter eine ganz Zahl, dann wird deren Länge in Zeichen zurückgegeben, andernfalls -1; ein leerer String im ersten Parameter ergibt 0.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, deren Länge ermittelt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTLEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Länge eines Strings in Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Länge ermittelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEVENSHTEIN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Levenshtein-Distanz (https://de.wikipedia.org/wiki/Levenshtein-Distanz) der beiden übergebenen Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# erster String&lt;br /&gt;
# zweiter String&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $LEVENSHTEIN(alpha,beta)&lt;br /&gt;
&lt;br /&gt;
==$POS()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Position des Substrings in einem String. Das Funktionsergebnis ist die Position, das erste Zeichen ist 1. 0 wird zurück gegeben, wenn der Substring im String nicht vorkommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Substring (nach dem gesucht wird)&lt;br /&gt;
# String (in dem gesucht wird)&lt;br /&gt;
# optional: Wenn ic (ignore case), dann wird bei der Suche die Groß- und Kleinschreibung nicht beachtet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $POS($EDT(edt1),$VAR(1),ic) &amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert zwischen der oberen und unteren Grenze&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ&lt;br /&gt;
## int - zufällige Ganzzahl &lt;br /&gt;
## date - zufälliges Datum &lt;br /&gt;
## curr - zufällige Zahl mit zwei Nachkommastellen&lt;br /&gt;
## curr4 - zufällige Zahl mit vier Nachkommastellen&lt;br /&gt;
## text1, text2, text3... - zufällige Zeile aus dem jeweiligen Text; text ist text1; untere und obere Grenze bleiben unberücksichtigt&lt;br /&gt;
## ld - zufälliger Schlüssel-Wert aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ldv - zufälliger Text aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ls - zufälliger Schlüssel-Wert aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## lsv - zufälliger Text aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
# untere Grenze&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $RANDOM(int,1,6)&lt;br /&gt;
&lt;br /&gt;
=Datumsfunktionen=&lt;br /&gt;
&lt;br /&gt;
==$INCDATE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktione  $INCDATE() verändert das Datum im ersten Parameter um die Anzahl Tage im zweiten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das verändert werden soll&lt;br /&gt;
# optional: Die Tage, um die verändert werden soll; wenn leer, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCDATE($NOW(),-3)   clr=Y&lt;br /&gt;
&lt;br /&gt;
==$INT2TIME()==&lt;br /&gt;
&lt;br /&gt;
Macht aus z.B. 1130 die Zeit 11:30&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zeit im Integer-Format&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_time=$INT2TIME($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$NOW()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit im Format dd.mm.yyyy hh:mm:ss zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #execsql   k_datechg=$NOW()&lt;br /&gt;
&lt;br /&gt;
==$NOWFMT()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und/oder die aktuelle Uhrzeit im angegebenen Format zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Formatierungsstring (Syntax wie FormatDateTime in Delphi)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$NOWFMT(yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$NOWMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit ohne Sekunden (also dd.mm.yyyy hh:mm) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$NOWMIN()&lt;br /&gt;
&lt;br /&gt;
==$TODAY()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum im Format dd.mm.yyyy zurück.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Wenn das Datum in einem anderen Format benötigt wird, ist $NOWFMT() das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$TODAY()&lt;br /&gt;
&lt;br /&gt;
==$DFMT()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;date formated&amp;quot;) Formatiert das übergebene Datum. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, ggf. mit Uhrzeit, das formatiert werden soll.&lt;br /&gt;
# Formatierungsstring wie in Delphi&lt;br /&gt;
# optional: Wenn hn (&amp;quot;hide null&amp;quot;), dann wird ein leerer String zurück gegeben, wenn das Datum kleiner/gleich 1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$DFMT($NOW(),yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Bool'sche Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
==$BFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert einen bool'schen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'scher Wert&lt;br /&gt;
# optional: Ergebnis, wenn Wert Y ('y', 'J', 'j', '1') ist, default Y&lt;br /&gt;
# optional: Ergebnis, wenn Wert N (also nicht 'Y', 'y', 'J', 'j', '1') ist, default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cout   c=$BFMT($VAR(test),x,)&lt;br /&gt;
&lt;br /&gt;
==$BOOL()==&lt;br /&gt;
&lt;br /&gt;
Wertet das bool'sche Statement im Parameter aus.&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
* = gleich&lt;br /&gt;
* == gleich ohne Berücksichtigung der Groß- und Kleinschreibung&lt;br /&gt;
* &amp;lt;&amp;gt; ungleich&lt;br /&gt;
* != ungleich&lt;br /&gt;
* &amp;gt; größer&lt;br /&gt;
* &amp;gt;= größer gleich&lt;br /&gt;
* &amp;lt; kleiner&lt;br /&gt;
* &amp;lt;= kleiner gleich &lt;br /&gt;
* and Und-Verknüpfung&lt;br /&gt;
* or ODER-Verknüpfung&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Statements werden von links nach rechts ausgewertet, and und or sind gleichwetig, gegebenenfalls müssen Klammern eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'sches Statement, das ausgewertet wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL((17 &amp;gt; 22) or (5 &amp;gt; 3))&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL(17 &amp;gt; 22 or 5 &amp;gt; 3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATECOMP()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn Datum 2 Operator Datum 1 zutreffend ist. Ansonsten wird N zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Wird kein Operator angegeben, dann wird die Anzahl der Tage Datum 2 - Datum 1 als Zahl zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum 1&lt;br /&gt;
# Datum 2&lt;br /&gt;
# Operator&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024,&amp;lt;)&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATEMINREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMINREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEMAXREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMAXREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in ein Datum wandeln lassen, werden zu 0 (30.12.1899) konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter diesem Datum entspricht. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;Test $DATEBETWEEN($TODAY(),1.1.2020,2.2.2022)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$EMPTY()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Parameter ein leerer String ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTY($DATE(n,grpname))&lt;br /&gt;
&lt;br /&gt;
==$EMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable ein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTYVAR(buchungsnr)&lt;br /&gt;
&lt;br /&gt;
==$IN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INIC() beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die erste Anweisung gibt Y und die zweite N zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INIC()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $IN() nicht beachtet beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen geben Y zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$ISCURR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen Currency-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISCURR($DATA(n,rechnungssumme))&lt;br /&gt;
&lt;br /&gt;
==$ISDATE()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in ein Datums- oder DatumsZeit-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Prüfoperation, default ist date&lt;br /&gt;
## date - prüft, ob in ein Datum gewandelt werden kann&lt;br /&gt;
## datetime - prüft, ob in ein Datums-Zeit-Wert gewandelt werden kann&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISDATE($DATA(n,beginn))&lt;br /&gt;
&lt;br /&gt;
==$ISINT()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen ganzzahligen Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISINT($DATA(n,tage))&lt;br /&gt;
&lt;br /&gt;
==$INTMAX()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMAX($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$INTMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMIN($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$NEMPTY()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;not empty&amp;quot;) Gibt Y zurück, wenn der Parameter nicht leer ist. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalt geprüft wird. Leerzeichen gelten als leerer String.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 &lt;br /&gt;
 ~ $NEMPTY($EDT(edt1))&lt;br /&gt;
&lt;br /&gt;
==$NEMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable kein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $NEMPTYVAR(kundennr)&lt;br /&gt;
&lt;br /&gt;
==$NOT==&lt;br /&gt;
&lt;br /&gt;
Invertiert einen bool'schen Wert. Aus Y (y, J, j, 1) wird N und aus N wird Y.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der invertiert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $NOT(2)&lt;br /&gt;
&lt;br /&gt;
==$NUMBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in eine Zahl wandeln lassen, werden zu 0 konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter dieser Zahl entspricht. Siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56,)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die beiden Beispiele unterscheiden sich auf den ersten Blick kaum. Bei der ersten Zeile muss jedoch eine Schuhgröße eingegeben werden. Bleibt das Feld im VL-Segment leer, so wird dieser fehlende Wert nach 0 konvertiert und liegt nicht zwischen 28 und 56.&lt;br /&gt;
&lt;br /&gt;
Anders bei der zweiten Zeile: Das Komma vor der schließenden Klammer sorgt für einen vierten Parameter, der ebenfalls leer ist und damit nach 0 gewandelt wird. Auf diese Weise werden die leere Eingaben (und die Eingabe von 0) gültig.&lt;br /&gt;
&lt;br /&gt;
==$REGEX()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $REGEX() (&amp;quot;regular expressions&amp;quot;) prüft, ob der String in Parameter 1 den Anforderungen von Parameter 2 entspricht (Ergebnis Y) oder nicht (Ergebnis N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft werden soll&lt;br /&gt;
# Regulärer Ausdruck, mit dem der String in Parameter 2 geprüft wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $REGEX($VAR(med),^[A-Z]{3}$)&lt;br /&gt;
&lt;br /&gt;
==$TEXT_HASLINE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $TEXT_HASLINE() prüft, ob die als Parameter 2 übergebene Textzeile in einem Text vorkommt. Es wird nur auf komplette Textzeilen geprüft. Wird zum Beispiel verwendet, um eine Liste von Kundennummern zu erstellen, und dann auf einzelne Nummern zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# Textzeile, deren Vorkommen geprüft wird&lt;br /&gt;
# Ergebnis, wenn die Textzeile vorkommt; default Y&lt;br /&gt;
# Ergebnis, wenn die Textzeile nicht vorkommt; default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $TEXT_HASLINE(1,990000018,1,0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$VIBAN()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VIBAN() (&amp;quot;validate IBAN&amp;quot;) prüft eine IBAN anhand der Prüfziffern (3. und 4. Stelle).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# IBAN, die geprüft werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VIBAN(DE12345)&lt;br /&gt;
&lt;br /&gt;
=Currency-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==$CCALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit Festkommawerten durch&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
** + - Addition&lt;br /&gt;
** - - Subtraktion&lt;br /&gt;
** * - Multiplikation&lt;br /&gt;
** / - Division&lt;br /&gt;
** % - Division und Multiplikation des Ergebnisses mit 100&lt;br /&gt;
** +4 - Addition und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** -4 - Subtraktion und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** *4 - Multiplikation und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** /4 - Division und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** %4 - Division, Multiplikation des Ergebnisses mit 100 und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
** B, b, B4, b4 - Bruttobetrag, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** E, e, E4, e4 - Enthaltene MWSt, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** M, m, M4, m4 - MWSt, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** N, n, N4, n4 - Nettobetrag, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator&lt;br /&gt;
# und weitere: Operanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 10&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(+,1,2,3,4)&amp;quot;&lt;br /&gt;
 -- Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #val_set   n=1   z=1038,87&lt;br /&gt;
 #coutl $CCALC(N,$VAL(1),19)  -  $CCALC(E,$VAL(1),19)  -&lt;br /&gt;
&lt;br /&gt;
==$CURR()==&lt;br /&gt;
&lt;br /&gt;
Currency-Werte müssen in Funktionen mit einem Punkt als Dezimaltrennzeichen eingegeben werden, da das Komma die Parameter trennt. Sofern Konstanten verwendet werden, lässt sich das einfach so eingeben, sobald aber die Werte aus anderen Funktionen kommen (zum Beispiel $DATA()), müssen sie dann mit $CURR() in dieses Format umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Vorkommastellen&lt;br /&gt;
# Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 43,48&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,$CURR(2,3))&amp;quot;&lt;br /&gt;
 -- zum Vergleich; Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert Curreny-Werte&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert&lt;br /&gt;
# optional: Formatierungsstring, default 0.00&lt;br /&gt;
# optional: wenn hn (&amp;quot;hide null&amp;quot;), dann werden leere Strings als Wert auch als leerer String ausgegeben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=###,###,###,##0.00&lt;br /&gt;
 #val_set   n=2   z=1337,42&lt;br /&gt;
 #cout   c=$CFMT($VAL(2),$VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ONLYNUM()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass in einem String nur Zahlen (ggf. auch Kommas oder Punkte) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl&lt;br /&gt;
# Art der Operation; default numkomma&lt;br /&gt;
## flnnc (&amp;quot;from last not numeric character&amp;quot;) - Ab dem letzten Zeichen, das keine Ziffer ist&lt;br /&gt;
## num - Nur Ziffern, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numkomma - Nur Ziffern und Kommata, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numpoint - Nur Ziffern und Punkte, alle anderen Zeichen werden entfernt&lt;br /&gt;
## ufnnc (&amp;quot;until first not numeric character&amp;quot;) - vom Anfang bis zum ersten Zeichen, das keine Ziffer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 -- Ergebnis 123456&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,num)&lt;br /&gt;
 -- Ergebnis 123&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,ufnnc)&lt;br /&gt;
 -- Ergebnis 456 &lt;br /&gt;
 #coutl   $ONLYNUM(123-456,flnnc)&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
	<entry>
		<id>http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22515</id>
		<title>Modul VAR neu</title>
		<link rel="alternate" type="text/html" href="http://bafbal.de/index.php?title=Modul_VAR_neu&amp;diff=22515"/>
		<updated>2025-03-26T14:15:43Z</updated>

		<summary type="html">&lt;p&gt;Michaelebner: /* $CONV() */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das Modul Var sammelt neben den Variablen auch die grundlegenden Prozeduren und Funktionen.&lt;br /&gt;
&lt;br /&gt;
=Variable=&lt;br /&gt;
&lt;br /&gt;
==#var_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#setvar setzt den Wert einer Variablen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis: Variable sind global, auf sie kann auch in Sub-Kommandos zugegriffen werden. Values sind dagegen lokal.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*rf (replace functions) - Wenn Y, dann werden nach der Zuweisung auf die Variable nochmals die Funktionen ersetzt. Wird zum Beispiel benötigt, wenn Code mit Funktionen mittels $DATA() aus der Datenbank geladen wird; Funktionen werden ersetzt, default N; siehe Beispiel&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_set   n=test2  z=$GUID()&lt;br /&gt;
 #var_set   n=edt    z=$EDT(edt1)   ie=42&lt;br /&gt;
 #var_set   n=_page_kunde_adressänderung_ro   z=N   zn=Y   zr=Y   r=kundenservice&lt;br /&gt;
&lt;br /&gt;
Zum Parameter rf: $NOW() in die Zwischenablage kopieren und dann ausführen:&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=N&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
 #var_set   n=test  z=$CLIPBOARD()   rf=Y&lt;br /&gt;
 #message   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_setempty==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_setempty setzt den Wert einer Variablen, sofern sie (noch) leer ist.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Besteht der Variableninhalt aus Leerzeichen, gilt die Variable auch als leer.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. Liegt das Recht ''read'' vor, so wird statt dem Inhalt von ''z'' der Inhalt von ''zr'' gesetzt. Liegt kein Recht vor, dann wird der Inhalt von ''zn'' gesetzt&lt;br /&gt;
*z - Wert der Variablen, Funktionen werden ersetzt, default ist ein leerer String&lt;br /&gt;
*zn - Wert der Variablen, wenn das Recht r nicht vorliegt&lt;br /&gt;
*zr - Wert der Variablen, wenn das Recht r nur ein leserecht ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_setempty   n=test   z=&amp;quot;Hello world&amp;quot;&lt;br /&gt;
 #var_setempty   n=test2  z=$GUID()&lt;br /&gt;
 #var_setempty   n=edt    z=$EDT(edt1)    ie=42&lt;br /&gt;
&lt;br /&gt;
==#var_add==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#var_add fügt einer Variablen einen Wert hinzu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
*ie - &amp;quot;if empty&amp;quot;, Wenn der Wert von z/zr/zn leer ist, dann wird ersatzweise der Wert von ie verwendet; ähnlich NVL bei SQL&lt;br /&gt;
*n - Name der Variablen, Groß- und Kleinschreibung wird nicht unterschieden, zwingend erforderlich&lt;br /&gt;
*r (rights) - Die Variable wird nur dann gesetzt, wenn das Recht ''write'' vorliegt; default ist ''frm''. &lt;br /&gt;
* y -Typ der Operation; default ''text''&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** month - Es wird dem Datum eine Anzahl von Monaten hinzugefügt&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
*z - Wert, welcher der Variablen hinzugefügt wird, Funktionen werden ersetzt, default ist ein leerer String oder eine 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$NOW()&lt;br /&gt;
 #var_add   n=test   z=1   y=datetime&lt;br /&gt;
 #cout   c=$VAR(test)&lt;br /&gt;
&lt;br /&gt;
==#var_log==&lt;br /&gt;
&lt;br /&gt;
Schreibt den Inhalt aller Variablen in das Debug-Log.&lt;br /&gt;
&lt;br /&gt;
Wird nur zur Fehlersuche verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_log&lt;br /&gt;
&lt;br /&gt;
==$VAR()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $VAR() wird auf den Inhalt der Variable zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
# optional: Der Wert wird vor oder nach der Rückgabe als Funktionsergebnis verändert; nur für ganzzahlige Werte&lt;br /&gt;
## ib (&amp;quot;increment before&amp;quot;) - Der Wert wird vor der Rückgabe um eins erhöht&lt;br /&gt;
## db (&amp;quot;decrement before&amp;quot;) - Der Wert wird vor der Rückgabe um eins verringert&lt;br /&gt;
## ia (&amp;quot;increment after&amp;quot;) - Der Wert wird nach der Rückgabe um eins erhöht&lt;br /&gt;
## da (&amp;quot;decrement after&amp;quot;) - Der Wert wird nach der Rückgabe um eins verringert&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #message  c=$VAR(test)&lt;br /&gt;
 #var_set  n=neuer_wert   z=$VAR(wert)   ie=$VAR(alternativwert)&lt;br /&gt;
 #execsql   k_lfdnr=$VAR(lfdnr,ib)&lt;br /&gt;
&lt;br /&gt;
=Kommandos=&lt;br /&gt;
&lt;br /&gt;
(Primär- und Sub) Kommandos sind üblicherweise benannt und werden im Code-Dialog eingegeben.&lt;br /&gt;
&lt;br /&gt;
Es besteht jedoch auch die Möglichkeit, lokale Kommandos innerhalb eines anderen Kommandos zu definieren. Diese Kommandos haben statt eines Kommando-Namens dann dann eine Kommando-Nummer.&lt;br /&gt;
&lt;br /&gt;
Lokale Kommandos werden üblicherweise für folgende Zwecke verwendet:&lt;br /&gt;
&lt;br /&gt;
* Bei der Verwendung von xlive werden bisweilen Prozeduren eingesetzt, die ihrerseits ein Kommando aufrufen (z.B. #sql_open). Wenn dieses Kommando nichts bereits existiert, kann es nur als lokales Kommando erstellt werden.&lt;br /&gt;
&lt;br /&gt;
* Wenn das auszuführende Kommando auf derselben Seite stehen soll wie die aufrufende Prozedur.&lt;br /&gt;
&lt;br /&gt;
Siehe als Beispiel: [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd fügt dem Kommando eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd fügt dem ersten Kommando eine Zeile hinzu, #cmd2 fügt dem zweiten Kommando eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd hat keine benannten Parameter. Die ganze Zeile nach dem #cmd und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd3 #text $DATA(n,login);$DATA(n,shortname);$DATA(n,firstname);$DATA(n,lastname);$DATA(n,userid);&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[beispiele_csv|User-Tabelle als CSV-Datei exportieren]]&lt;br /&gt;
&lt;br /&gt;
==#cmd_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clear löscht ein Kommando&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #cmd_clear löscht das erste Kommando, #cmd_clear2 löscht das zweite Kommando, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #cmd_clear Zeichen, so werden die dem gerade gelöschten Kommando hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear3&lt;br /&gt;
 #cmd_clear #grd_add   i=grid   f_logtext=&amp;quot;Kunde angerufen und nicht erreicht.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#cmd_clearall==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#cmd_clearall löscht alle Kommandos&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clearall&lt;br /&gt;
&lt;br /&gt;
=CSV=&lt;br /&gt;
&lt;br /&gt;
Die CSV-Routinen werden verwendet, um CSV-Dateien einzulesen und zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
==#csv_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_open öffnet eine CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_open öffnet die erste CSV-Datei, #csv_open2 öffnet die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*ber - wenn Y, werden die Zeilenumbrüche innerhalb von Feldern durch Leerzeichen ersetzt. Die Felder müssen dabei in doppelten Anführungszeichen eingeschlossen sein.&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - (&amp;quot;Filename&amp;quot;) Dateiname der CSV-Datei&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich. Muss bereits hier gesetzt werden, wenn mit $CSV_LINE auf den Header zugegriffen werden soll, bevor #csv_line ausgeführt wird.&lt;br /&gt;
*txt (&amp;quot;Text&amp;quot;) - alternativ zum Dateinamen fn die Nummer eines Textes, der als CSV-Datei verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open  fn=c:\temp\text.csv&lt;br /&gt;
&lt;br /&gt;
==#csv_line==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_line geht zeilenweise durch die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #csv_line geht durch die erste CSV-Datei, #csv_line2 geht durch die zweite CSV-Datei, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* db (&amp;quot;database&amp;quot;) - Die Datenbank, für welche die Transaktion ausgeführt wird, wenn ert=Y gesetzt ist. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
*er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
*ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt, Funktionen werden ersetzt&lt;br /&gt;
*hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden. Groß- und Kleinschreibung ist unerheblich.&lt;br /&gt;
*m (&amp;quot;maximum&amp;quot;) - Maximale Anzahl der Zeilen, die verarbeitet wird. Wird gerne bei der Entwicklung verwendet, um die Bearbeitungsgeschwindigkeit zu erhöhen. Funktionen werden ersetzt&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird im Falle einer Exception die Bearbeitung nicht abgebrochen, sondern lediglich Warnungen geloggt; Default N, Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Semikolon, Funktionen werden ersetzt&lt;br /&gt;
*trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_line  er=test_csv_line   hhr=Y   m=3&lt;br /&gt;
&lt;br /&gt;
==#csv_check==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#csv_check prüft die CSV-Datei&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
*cnt (&amp;quot;count&amp;quot;) - Anzahl der Header-Einträge, die geprüft wird; Funktionen werden ersetzt&lt;br /&gt;
*h1, h2... (&amp;quot;header&amp;quot;) - Eintrag im Header, der auf existenz geprüft wird; Groß und Kleinschreibung ist unerheblich, Funktionen werden ersetzt.&lt;br /&gt;
*n (&amp;quot;name&amp;quot; / &amp;quot;number&amp;quot;) - Name der Variable oder Nummer des Values, in die/den das Ergebnis (Y oder N) geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*res (&amp;quot;result&amp;quot;) - Name der Variable oder Nummer des Values, in die/den der Ergebnistext geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
*sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwischen den einzelnen Spalten; Funktionen werden ersetzt&lt;br /&gt;
*y - Typ der Prüfung; Funktionen werden ersetzt, default header&lt;br /&gt;
** header - Prüft die Existenz von Spaltennamen im Header. Die zu prüfenden Spaltennamen werden als h1, h2... übergeben, cnt ist entsprechend zu setzen. Wenn alle geprüften Spaltennamen vorhanden sind, wird Y zurück gegeben, ansonsten N. Die fehlenden Spaltennamen werden als Ergebnistext zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #csv_open   fn=C:\temp\mad\done\MTF3108_ET2607_selektion.CSV&lt;br /&gt;
 #csv_check   n=1   res=2   cnt=3   h1=eins   h2=zwei   h3=drei&lt;br /&gt;
 #coutl $VAL(1) - $VAL(2)&lt;br /&gt;
&lt;br /&gt;
==#csv_paste==&lt;br /&gt;
&lt;br /&gt;
Übernimmt eine CSV-Datei aus der Zwischenablage. Auf die Werte kann mit $SEPLINE() zugegriffen werden, siehe [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
'''Multi-Row'''&lt;br /&gt;
&lt;br /&gt;
Mit dem Multi-Row-Modus können Daten eingelesen werden, die in einer Zeile mehrere gleichartige Werte haben.&lt;br /&gt;
&lt;br /&gt;
Daten, die im Single-Row-Modus wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465&lt;br /&gt;
 01.01.2020     8574&lt;br /&gt;
 01.01.2020     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     3456&lt;br /&gt;
 03.01.2020     6578&lt;br /&gt;
 03.01.2020     4457&lt;br /&gt;
 03.01.2020     7658&lt;br /&gt;
&lt;br /&gt;
Würden im Multi-Row-Modus wie folgt aussehen (und könnten auch so eingelesen werden):&lt;br /&gt;
&lt;br /&gt;
 01.01.2020     4465     8574     3456&lt;br /&gt;
 02.01.2020     5467&lt;br /&gt;
 03.01.2020     2436     6578     3456     6578     4457     7658&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Kommando, das für jede Zeile der CSV-Datei ausgeführt wird. &lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Für jede Ausführung des in er spezifizierten Kommandos wird eine eigene Datenbank-Transaktion ausgeführt.&lt;br /&gt;
* fr (&amp;quot;first row&amp;quot;) - Wenn dieser Parameter einen Wert hat, dann muss die kopierte CSV-Datei in der ersten Zeile auch diesen Wert haben, oder die Aktion wird abgebrochen; Funktionen werden ersetzt&lt;br /&gt;
* hhr (&amp;quot;has header row&amp;quot;) - Wenn Y, ist die erste Zeile der CSV-Datei eine Überschriften-Zeile; für diese wird das in er spezifizierten Kommando nicht ausgeführt, dafür können Spaltenbezeichner für den Zugriff auf die einzelnen Spalten verwendet werden.&lt;br /&gt;
* mrs (&amp;quot;multi row start&amp;quot;) - Erste Spalte für den Multi-Row-Bereich&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichen zwichen den Spalten, default ist das Tabulatorzeichen&lt;br /&gt;
* trim - Wenn Y, dann werden in jeder Zelle führende und nachhängende Leerzeichen entfernt; default N, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ; default s&lt;br /&gt;
** m - multi; siehe Abschnitt Multi-Row&lt;br /&gt;
** s - single; die CSV-Datei wird Zeile für Zeile eingelesen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
* [[beispiele_pastecsv|Eine Tabelle in der Zwischenablage in ein PDF-Dokument wandeln]]&lt;br /&gt;
&lt;br /&gt;
 #csv_paste   er=imp_line   hhr=Y&lt;br /&gt;
 #csv_paste   er=imp_line   y=m   mrs=1&lt;br /&gt;
&lt;br /&gt;
==$CSV()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV() greift auf einen Feldinhalt der aktuellen CSV-Zeile zu.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Spalte oder 0-relative Spaltennummer. Name der Spalte setzt voraus, dass bei #csv_line der Parameter hhr gleich Y ist.&lt;br /&gt;
# optional: Stelle der Zeichens, ab dem der Inhalt des CSV-Feldes zurück gegeben wird&lt;br /&gt;
# optional: Anzahl der Zeichen, die maximal zurück gegeben werden; wird meist dafür verwendet, damit die maximale Länge von Datenbankfeldern nicht überschritten wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0)&lt;br /&gt;
&lt;br /&gt;
Hier im Beispiel wird in der ersten CSV-Datei (#csv_open) auf die erste Spalte (0, da 0-relativ) zugegriffen.&lt;br /&gt;
&lt;br /&gt;
 #setvar  n=test   z=$CSV(1,0,1,30)&lt;br /&gt;
&lt;br /&gt;
Wie oben, nur werden nur die ersten 30 Zeichen zurück gegeben&lt;br /&gt;
&lt;br /&gt;
==$CSV_LINE()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CSV_LINE() Gibt eine ganze Zeile einer CSV-Datei zurück&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der CSV-Datei&lt;br /&gt;
# Name der Zeile: header gibt die Header-Zeile zurück, current die aktuelle Zeile in #csv_line&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die Funktion $CSV_LINE wird insbesondere dafür verwendet, um CSV-Dateien mit Daten zu ergänzen. Hier im Beispiel wird jede Zeile mit einer GUID ergänzt.&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #text $CSV_LINE(1,current)$GUID();&lt;br /&gt;
 &lt;br /&gt;
 #csv_open   fn=c:\temp\ex.csv   hhr=Y&lt;br /&gt;
 #text_clear $CSV_LINE(1,header)guid;&lt;br /&gt;
 #csv_line   er=1   hhr=Y&lt;br /&gt;
 &lt;br /&gt;
 #text_save   fn=c:\temp\ex2.csv&lt;br /&gt;
&lt;br /&gt;
Nach dem Öffnen der bestehenden CSV-Datei (es muss hier bereits hhr gesetzt werden) wird zunächst der Header in Text 1 eingefügt, ergänzt um die Spalte ''guid'' und das abschließende Semikolon. Danach gehen wir mit #csv_line durch alle Zeile, fügen diese komplett in Text 1 ein und hängen eine GUID hinten dran. Danach wird die Datei gespeichert.&lt;br /&gt;
&lt;br /&gt;
=Text=&lt;br /&gt;
&lt;br /&gt;
==#text==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text fügt dem Text eine Zeile hinzu&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text fügt dem ersten Text eine Zeile hinzu, #text2 fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #text und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Und jetzt noch eine GUID: $GUID()&lt;br /&gt;
 #text Der folgende Text kommt in Großbuchstaben: $UPP(hello world)&lt;br /&gt;
&lt;br /&gt;
==#textn==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#textn fügt dem Text eine Zeile hinzu. Im Unterschied zu #text werden dabei keine Funktionen ersetzt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #textn fügt dem ersten Text eine Zeile hinzu, #text2n fügt dem zweiten Text eine Zeile hinzu, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text hat keine benannten Parameter. Die ganze Zeile nach dem #textn und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen werden dabei '''nicht''' ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #textn Zeile 1&lt;br /&gt;
 #textn Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_clear==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_clear löscht einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_clear löscht den ersten Text, #text_clear2 löscht den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
Folgen dem #text_clear Zeichen, so werden die dem gerade gelöschten Text hinzugefügt. Auf diese Weise lässt sich etwas prägnanter formulieren.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear7&lt;br /&gt;
 #text7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
Das vorangestellt #text_clear stellt sicher, dass Text7 leer ist. Alternativ könnte man formulieren:&lt;br /&gt;
&lt;br /&gt;
 #text_clear7 Zeile 1&lt;br /&gt;
 #text7 Zeile 2&lt;br /&gt;
&lt;br /&gt;
==#text_save==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_save speichert einen Text in einer Datei.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_save speichert den ersten Text, #text_save2 speichert den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* bom (&amp;quot;Byte order mark&amp;quot;) - Wenn Y, dann wird die Datei mit BOM geschrieben; default Y&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu speichernden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname, unter dem die Datei gespeichert wird. Bestehende Dateien werden überschrieben, sofern das Betriebssystem das nicht verhindert (z.B, weil die Datei gerade geöffnet ist)&lt;br /&gt;
* o (&amp;quot;open&amp;quot;) - Öffnet die gespeicherte Datei gleich anschließend.&lt;br /&gt;
*sort - Wenn Y, dann wird die Datei vor dem Speichern sortiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text Hello world&lt;br /&gt;
 #text_save  fn=$DIR(userroot)hello_world.txt&lt;br /&gt;
 #text_save  fn=c:\temp\export_vert_export.prepared_.csv   e=utf8   bom=N&lt;br /&gt;
&lt;br /&gt;
==#text_open==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_open öffnet einen Text aus einer Datei, der bisherige Inhalt der Datei wird überschrieben.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_open öffnet den ersten Text, #text_open2 öffnet den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* e (&amp;quot;encoding&amp;quot;) - Encoding der zu öffnenden Datei, zulässig sind ''ansi'', ''ascii'', ''utf7'', ''utf8'', ''unicode'' und ''bigendianunicode''. Bei leerem oder nicht gesetzten Parameter wird das Default-Encoding verwendet (Bei Windows ansi, sonst utf8).&lt;br /&gt;
*fn - Dateiname der Datei, die geöffnet wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_open  fn=$DIR(userroot)test.txt&lt;br /&gt;
 #text Eine weitere Zeile, $GUID()&lt;br /&gt;
 #text_save  fn=$DIR(userroot)test.txt&lt;br /&gt;
&lt;br /&gt;
==#text_props==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_props stellt Eigenschaften des Textes ein.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_props bezieht sich auf den ersten Text, #text_props2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* dub (&amp;quot;duplicates&amp;quot;) - Verhalten einer sortierten Liste bezüglich Dubletten&lt;br /&gt;
** acc (&amp;quot;accept&amp;quot;) - Dubletten werden akzeptiert&lt;br /&gt;
** err (&amp;quot;error&amp;quot;) - Dubletten führen zu Fehlern&lt;br /&gt;
** ign (&amp;quot;ignore) - Dubletten werden ignoriert&lt;br /&gt;
* srt (&amp;quot;sorted&amp;quot;) - Wenn ja, dann ist die Liste sortiert&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_props   srt=Y   dup=ign&lt;br /&gt;
&lt;br /&gt;
==#text_set==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_set setzt eine bestimmte Zeile eines Textes&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_set bezieht sich auf den ersten Text, #text_set2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;index&amp;quot;) - 0-relativer Index der Zeile, die geschrieben werden soll. Mit ''last'' kann die letzte Zeile geschrieben werden, mit ''all'' werden alle Zeilen ersetzt, das wird dann gebraucht, wenn mehrzeiliger Text zugewiesen werden soll; Funktionen werden ersetzt&lt;br /&gt;
* z - Text, der geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text_set   i=2   z=&amp;quot;dritte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=last   z=&amp;quot;letzte Zeile&amp;quot;&lt;br /&gt;
 #text_set   i=all   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
==#text_sort==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_sort sortiert einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_sort bezieht sich auf den ersten Text, #text_sort2 bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* y - Typ, default alpha, Funktionen werden ersetzt&lt;br /&gt;
** alpha - sortiert alphanumerisch&lt;br /&gt;
** inv - invertiert die gegebene Reihenfolge&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=&amp;quot;,OU=2nd_Level_T1,OU=Kundenservice,OU=Benutzer,OU=Testtours,OU=Travel&amp;quot;&lt;br /&gt;
 #text_clear&lt;br /&gt;
 #text_dissect   z=$VAL(1)   sep=&amp;quot;,OU=&amp;quot;&lt;br /&gt;
 #coutl  $TEXT(1)&lt;br /&gt;
 #text_sort   y=inv&lt;br /&gt;
 #text_compose   n=1   sep=.&lt;br /&gt;
 #val_set   n=1   z=tt.$VAL(1)&lt;br /&gt;
 #coutl $VAL(1)&lt;br /&gt;
&lt;br /&gt;
 Ergebnis ist:&lt;br /&gt;
 2nd_Level_T1&lt;br /&gt;
 Kundenservice&lt;br /&gt;
 Benutzer&lt;br /&gt;
 Testtours&lt;br /&gt;
 tt.Testtours.Benutzer.Kundenservice.2nd_Level_T1.&lt;br /&gt;
&lt;br /&gt;
==#text_dissect==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_dissect zerteilt einen String anhand einer vorgegebenen Trennzeichenfolge und fügt das Ergebnis dem betreffenden Text hinzu. Gegebenenfalls muss der Text vorher mit #text_clear geleert werden.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_dissect bezieht sich auf den ersten Text, #text_dissect bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - wenn Y, wird die sep-Zeichenfolge noch mal dem String angehängt; default N, Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Zeichenfolge, anhand der String zerteilt wird; Funktionen werden ersetzt&lt;br /&gt;
* z - String, der zerlegt wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_compose==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_compose setzt einen Text mithilfe eines Trennzeichens zu einem String zusammen&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_compose bezieht sich auf den ersten Text, #text_compose bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* ls (&amp;quot;last separator&amp;quot;) - Wenn Y, wird die Trennzeichenfolge auch noch mal am Ende des Strings eingefügt; default N, Funktionen werden ersetzt&lt;br /&gt;
* n - Nummer des Values oder Name der Variable, in welche der String geschrieben wird; Funktionen werden ersetzt&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Trennzeichenfolge, die beim Zusammenfügen des Textes verwendet wird; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Siehe #text_sort&lt;br /&gt;
&lt;br /&gt;
==#text_act==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_act bearbeitet einen Text&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_act bezieht sich auf den ersten Text, #text_act bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
* c (&amp;quot;caption&amp;quot;) - Text der Zeile, die bei insert eingefügt werden soll; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* cu (&amp;quot;current&amp;quot;) - 0-relative Zeilennummer der Operation; default 0, Funktionen werden ersetzt&lt;br /&gt;
* ne (&amp;quot;new&amp;quot;) - 0-relative Zeilennummer als Ziel bei move; default 0, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Operation; Funktionen werden ersetzt&lt;br /&gt;
** delete - Löscht die Zeile an Position cu (&amp;quot;current&amp;quot;)&lt;br /&gt;
** insert - Fügt den Text c an der Position cu (&amp;quot;current&amp;quot;) ein&lt;br /&gt;
** move - verschiebt die Zeile cu (&amp;quot;current&amp;quot;) nach Zeile ne (&amp;quot;new&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #text_act   y=move   cu=0&lt;br /&gt;
&lt;br /&gt;
==#text_loop==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#text_loop geht durch die Zeilen eines Textes und ruft für jede Zeile ''er'' auf&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur. #text_loop  bezieht sich auf den ersten Text, #text_loop2  bezieht sich auf den zweiten Text, und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, auf die sich ert bezieht&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m - (&amp;quot;maximum&amp;quot;) Es wird maximal für die Anzahl der angegebenen Zeilen das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* n - Name der Variable, in welche die 0-relative Schleifenvariable geschrieben wird. (Es würde auch in einen Value geschrieben, wenn es sich um eine Nummer handelt, das ergibt in der Praxis aber meist nicht viel Sinn) Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_clear eins&lt;br /&gt;
 #text zwei&lt;br /&gt;
 #text drei&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear #coutl - $TEXT(1,$VAR(eins))&lt;br /&gt;
 #text_loop   er=1   n=eins&lt;br /&gt;
&lt;br /&gt;
==#tvl_add==&lt;br /&gt;
&lt;br /&gt;
Addiert dem Wert in einer Text-Valueliste einen Wert hinzu. Es handelt sich dabei um eine nummerierte Prozedur: #tvl_add arbeitet mit Text 1, #tvl_add2 mit Text 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Zeile, der ein Wert hinzugefügt wird; Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Operation, Funktionen werden ersetzt, default text&lt;br /&gt;
** curr - Es wird eine Fixkomma-Addition vorgenommen&lt;br /&gt;
** date - Es wird dem Datum eine Anzahl von Tagen hinzugefügt&lt;br /&gt;
** datetime - Es wird dem Datum eine Anzahl von Tagen hinzugefügt, Ergebnis als datetime&lt;br /&gt;
** int - Es wird eine Ganzzahl-Addition vorgenommen&lt;br /&gt;
** text - Der Wert wird als Text hinzugefügt&lt;br /&gt;
* z - Der Wert, der hinzugefügt wird&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text eins=1&lt;br /&gt;
 #text zwei=2&lt;br /&gt;
 #text drei=3&lt;br /&gt;
 #tvl_add   y=int   n=zwei   z=1&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==$TEXT()==&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion $TEXT() wird auf den Inhalt des Textes zugegriffen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# optional Zeile des Textes (0-relativ). Wenn es keinen zweiten Parameter gibt, wird der komplette Text zurück gegeben. Alternativ als zweiter Parameter eine Sonderfunktion:&lt;br /&gt;
## cnt / count - Gibt die Anzahl der Zeilen zurück&lt;br /&gt;
## last - Gibt die letzte Zeile zurück&lt;br /&gt;
## ix - Gibt die Position des Textes im dritten Parameter zurück&lt;br /&gt;
## as_line - Gibt den Text als eine Zeile zurück, Zeilenumbrüche werden durch den dritten Parameter ersetzt&lt;br /&gt;
# optional in abhängigkeit vom zweiten Paremeter&lt;br /&gt;
## wenn zweiter Parameter ix: Textzeile, nach der mit ix gesucht wird&lt;br /&gt;
## wenn zweiter Parameter as_line: Zeichenfolge, mit der die Zeilenumbrüche ersetzt werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #text Zeile 1&lt;br /&gt;
 #text Zeile 2&lt;br /&gt;
 #text Zeile 3&lt;br /&gt;
 #message  c=$TEXT(1)&lt;br /&gt;
&lt;br /&gt;
 #code url=$TEXT(1,as_line,&amp;amp;)&lt;br /&gt;
&lt;br /&gt;
=Code=&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich gilt in BAL: Eine Prozedur - eine Zeile.&lt;br /&gt;
&lt;br /&gt;
Bei vielen und/oder langen Parametern führt das zu recht langen Code-Zeilen und zu Unübersichtlichkeit. Hier können nun Teile der Parameter mit #code in weitere Zeile ausgelagert werden, deren Inhalt dann mit $CODE$ oder $CODE$ der eigentlichen Code-Zeile hinzugefügt wird.&lt;br /&gt;
&lt;br /&gt;
==#code==&lt;br /&gt;
&lt;br /&gt;
Fügt Text dem Code-Speicher hinzu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;#code hat keine benannten Parameter. Die ganze Zeile nach dem #code und dem trennenden Leerzeichen wird hinzugefügt.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=G:\pics\pic5d68865cdaba62_62767562.jpg&lt;br /&gt;
 #code fn2=G:\pics\pic5d913c48682128_67979256.jpg&lt;br /&gt;
 #email_send   from=test@****.de   to=info@*****************.de   bcc=info@*****.de   subject=Testmail   text=$TEXT(1)   $CODE$&lt;br /&gt;
&lt;br /&gt;
==$CODE$ / $CODEN$==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;$CODE$ und $CODEN$ sind keine Funktionen, auch wenn sie auf den ersten Blick ähnlich aussehen. Sie haben keine Parameter und auch keine Klammern, dafür ein abschließendes $.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen fügen den Code-Speicher der jeweiligen Zeile hinzu. $CODE$ löscht danach den Code-Speicher, $CODEN$ tut das nicht, so dass dieselben Parameter wiederholt eingefügt werden können (beim letzten Einfügen sollte dann $CODE$ verwendet werden).&lt;br /&gt;
&lt;br /&gt;
=Separierte Zeile=&lt;br /&gt;
&lt;br /&gt;
Eine separierte Zeile ist eine Textzeile, die mehrere gleichartige Werte enthält, die durch Trennzeichen getrennt sind.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
 3244,4465,7763,4536,4356,7777&lt;br /&gt;
&lt;br /&gt;
Solche Zeilen können mit #sepline aufgetrennt werden.&lt;br /&gt;
&lt;br /&gt;
==#sepline==&lt;br /&gt;
&lt;br /&gt;
Trennt eine separierte Zeile auf und führt für jeden Wert das mit er angegebene Kommando aus.&lt;br /&gt;
&lt;br /&gt;
Es handelt sich dabei um eine nummerierte Prozedur (#sepline, #sepline2...)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y; Funktionen werden ersetzt&lt;br /&gt;
* db - (&amp;quot;database&amp;quot;) Name der Datenbank, für welche die Transaktion gestartet wird, wenn ert=Y. Default ist die Standard-Datenbank, Funktionen werden ersetzt.&lt;br /&gt;
* er (&amp;quot;each row&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern (&amp;quot;each row no&amp;quot;) - Das Kommando, das für jeden Wert der separierten Zeile aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert (&amp;quot;each row transaction&amp;quot;) - Wenn Y, wird für jeden Wert der separierten Zeile eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* m (&amp;quot;maximum&amp;quot;) - Es wird maximal für die Anzahl der angegebenen Werte das in er angegebene Kommando ausgeführt. Dieser Parameter wird häufig dazu verwendet, während der Entwicklung mit einer geringen Zahl von Datensätzen zu arbeiten; Funktionen werden ersetzt.&lt;br /&gt;
* nex (&amp;quot;no exception&amp;quot;) - Wenn Y, wird bei Exceptions in er nicht abgebrochen, sondern mit dem nächsten Datensatz fortgesetzt. Default N; Funktionen werden ersetzt.&lt;br /&gt;
* nn (&amp;quot;not null&amp;quot;) - Wenn Y, dann wird er nur für Werte der separierten Zeile aufgerufen, die nicht leer sind. Default N, Funktionen werden ersetzt.&lt;br /&gt;
* sep (&amp;quot;separator&amp;quot;) - Das oder die Trennzeichen; default ist das Semikolon, Funktionen werden ersetzt.&lt;br /&gt;
* z - Der Inhalt der separierten Zeile; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(1)&lt;br /&gt;
 #sepline z=3244,4465,7763,4536,4356,7777   sep=,   er=1&lt;br /&gt;
&lt;br /&gt;
==$SEPLINE()==&lt;br /&gt;
&lt;br /&gt;
Greift auf den einzelnen Wert einer mit #sepline getrennten Zeile zu.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der separierten Zeile&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd #cout   c=$SEPLINE(3)&lt;br /&gt;
 #sepline3 z=3244;4465;7763;4536;4356;7777     er=1&lt;br /&gt;
&lt;br /&gt;
=User und Rechte=&lt;br /&gt;
&lt;br /&gt;
Aus Gründen der Übersichtlichkeit ist die Rechtevergabe zweistufig:&lt;br /&gt;
&lt;br /&gt;
# Es werden (meist am Anfang eines Primär-Kommandos) Rechte-Definitionen erstellt, die einer oder mehreren Benutzergruppen Rechte (lesen oder lesen und schreiben) zuweisen. Die Rechte werden dabei implizit auch allen Untergruppen der angegebenen Benutzergruppe erteilt (Zum Beispiel: Rechte der Gruppe ''user'' hat auch implizit die Gruppe ''user.admin'').&lt;br /&gt;
# Dem Parameter r verschiedener Prozeduren kann dann eine Rechte-Definition zugewiesen werden.&lt;br /&gt;
&lt;br /&gt;
Den Parameter r als Rechte-Definition berücksichtigen die folgenden Prozeduren:&lt;br /&gt;
&lt;br /&gt;
* #frm&lt;br /&gt;
* Buttons (#btn, #btns_btn)&lt;br /&gt;
* Alle Segmente (#text_seg, #memo_seg, #btns_seg, vl_seg, #grd_seg, #xgrd_seg)&lt;br /&gt;
* Tree (#tree_add, #tree_fill, #tree_fillsql, Lese-Recht reicht)&lt;br /&gt;
* Grid-Spalten (#grd_col, #xgrd_col)&lt;br /&gt;
* #vl_line (für die komplette Zeile (r) und die einzelne Zelle (r1, r2, r3...))&lt;br /&gt;
&lt;br /&gt;
Wo der Parameter r nicht gesetzt ist, wird die Rechte-Definition der Formulars verwendet.&lt;br /&gt;
&lt;br /&gt;
==#rights==&lt;br /&gt;
&lt;br /&gt;
Setzt eine Rechte-Definition im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Rechte-Definition; default ist ''frm'', also dsa Default-Recht für das Formular.&lt;br /&gt;
* r_ (&amp;quot;right&amp;quot;) - Prefix für die Benutzergruppe. Für die Rechte-Definition sind die folgenden Werte zulässig&lt;br /&gt;
** n (&amp;quot;no&amp;quot;) - kein Recht&lt;br /&gt;
** r (&amp;quot;read&amp;quot;) - nur lesen&lt;br /&gt;
** w (&amp;quot;write&amp;quot;) - lesen und schreiben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights  n=frm   r_user=r   r_user.admin=w&lt;br /&gt;
&lt;br /&gt;
Setzt für alle User das Lese-Recht und für Administratoren das Lese- und Schreibrecht.&lt;br /&gt;
&lt;br /&gt;
==#rights_clear==&lt;br /&gt;
&lt;br /&gt;
Löscht alle Rechte-Definitionen im betreffenden Kommando.&lt;br /&gt;
&lt;br /&gt;
(Wird in der Praxis selten benötigt, weil Kommandos mit leerer Rechte-Definition starten.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #rights_clear&lt;br /&gt;
&lt;br /&gt;
==$USERID()==&lt;br /&gt;
&lt;br /&gt;
Die ID des angemeldeten Users&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kusr=$USERID()&lt;br /&gt;
&lt;br /&gt;
==$RIGHTUSERID()==&lt;br /&gt;
&lt;br /&gt;
Administratoren können andere User einstellen (Userliste links unten im BAF-Client), vor allem um deren Rechte zu prüfen. Die UserID dieses ausgewählten Users kann mit der Funktion $RIGHTUSERID() ermittelt werden.&lt;br /&gt;
&lt;br /&gt;
In fast allen Fällen gilt der folgende Grundsatz: Lesende Operationen mit $RIGHTUSERID(), schreibende Operationen mit $USERID().&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_open   kusr=$RIGHTUSERID()&lt;br /&gt;
&lt;br /&gt;
==$ADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der angemeldete User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der angemeldete User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $ADM()&lt;br /&gt;
&lt;br /&gt;
==$RADM()==&lt;br /&gt;
&lt;br /&gt;
Gibt den ersten Parameter (oder Y) zurück, wenn der ausgewählte User Administrator-Rechte hat, andernfalls den zweiten Parameter (oder N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User Administrator-Rechte hat; sofern kein Wert angegeben ist, Y&lt;br /&gt;
# Wert, der zurückgegeben wird, wenn der ausgewählte User keine Administrator-Rechte hat; sofern kein Wert angegeben ist, N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $RADM()&lt;br /&gt;
&lt;br /&gt;
=Ausführen=&lt;br /&gt;
&lt;br /&gt;
==#exec==&lt;br /&gt;
&lt;br /&gt;
Führt ein anderes Kommando aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (condition) - Die Variable wird nur dann gesetzt, wenn  cnd=Y ist; Funktionen werden ersetzt&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Names des (Primär- oder Sub-) Kommandos, das ausgeführt werden soll.&lt;br /&gt;
* ex (&amp;quot;exception&amp;quot;) - Name oder Nummer des Kommandos, das ausgeführt wird, wenn bei der Ausführung von cmd eine Exception auftritt; siehe Beispiele&lt;br /&gt;
* fin (&amp;quot;finally&amp;quot;) - Name oder Nummer des Kommandos, das nach der Ausführung von cmd ausgeführt wird - egal ob eine Exception aufgetreten ist oder nicht. Wird nur berücksichtigt, wenn der Parameter ex nicht gesetzt ist.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispiel löst das Problem, dass ein neues PDF unter demselben Dateinamen nicht erstellt werden kann, wenn beim vorherigen Versuche der Erstellung eine Exception aufgetreten ist. In einem solchen Fall wurde ein #pdf_start, aber kein #pdf_stop ausgeführt, und die geöffnete Datei sperrt diesen Dateiname, bis der BAF-Client geschlossen wird. Lösung dieses Problems ist es, im Parameter ex ein #pdf stop auszuführen; auf das Öffnen der Datei kann in einem solchen Fall verzichtet werden. Mit der Funktion $DATA() wird hier im Beispiel gezielt eine Exception ausgelöst.&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;c_test_pdf&amp;quot;   y=console&lt;br /&gt;
 &lt;br /&gt;
 #cmd_clear &lt;br /&gt;
 #cmd #pdf_text  c=&amp;quot;Hello World&amp;quot;&lt;br /&gt;
 -- #cmd #pdf_text  c=&amp;quot;Hello World $DATA(dat,test)&amp;quot;&lt;br /&gt;
 #cmd #pdf_stop   o=Y&lt;br /&gt;
 &lt;br /&gt;
 #pdf_start  fn=$DIR(doc)\test.pdf&lt;br /&gt;
 #exec   cmd=1   ex=&amp;quot;#pdf_stop   o=N&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #cout  c=&amp;quot;c_test_pdf executed&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==#batchexec==&lt;br /&gt;
&lt;br /&gt;
Speichert den Text n in der Datei batch.bat und führt diese aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* clr (&amp;quot;clear&amp;quot;) - Wenn Y, wird der Text nach Ausführung des Batch-Datei gelöscht; Default Y; Funktionen werden ersetzt;&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes; der mit #text gespeicherte Text hat die Nummer 1 &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #batchexec   n=1&lt;br /&gt;
&lt;br /&gt;
==#file_open==&lt;br /&gt;
&lt;br /&gt;
Öffnet eine Datei (oder auch eine Webseite)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder die URL der Webseite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_open  fn=c:\temp\test.csv&lt;br /&gt;
 #file_open  fn=https://www.google.de&lt;br /&gt;
&lt;br /&gt;
==#loop==&lt;br /&gt;
&lt;br /&gt;
BAL kennt keine Schleifen als Sprachelement. Um Schleifen mit einer fest Schleifenzahl auszuführen, wird die Prozedur #loop verwendet. lf muss nicht kleiner als lt sein, #loop kann auch von oben nach unten zählen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* er - (&amp;quot;each row&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden ersetzt.&lt;br /&gt;
* ern - (&amp;quot;each row no&amp;quot;) Das Kommando, das für jede Zeile der Datenmenge aufgerufen wird. Funktionen werden nicht ersetzt. Wenn ''ern'' einen Wert hat, bleibt ''er'' unberücksichtigt. Üblicherweise wird ''er'' verwendet.&lt;br /&gt;
* ert - (&amp;quot;each row transaction&amp;quot;) Wenn Y, wird für jede Zeile der Datenmenge eine eigene Transaktion gestartet und nach der Abarbeitung des Kommandos wieder geschlossen.&lt;br /&gt;
* lf (&amp;quot;loop from&amp;quot;) - Anfangswert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* lt (&amp;quot;loop to&amp;quot;) - Endwert der Schleifenvariable; Funktionen werden ersetzt.&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in der die Schleifenvariable gespeichert wird (damit sie an anderer Stelle gelesen werden kann); Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #loop   lf=42   lt=1337   er=test_line&lt;br /&gt;
&lt;br /&gt;
==#exit==&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #exit bricht die Ausführung auf der jeweiligen Code-Ebene (Kommando bzw. Sub-Kommando) ab&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page   ras=Y&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
 &lt;br /&gt;
 ~ $EMPTY($PVAL(vl,id))   and   $PVAL(vl,status) &amp;gt; 20&lt;br /&gt;
 #sql select nextval('ausza_id') as id&lt;br /&gt;
 #sql_openval   f_id=1&lt;br /&gt;
 #page_val   i=vl   f=id   z=$VAL(1)&lt;br /&gt;
 #save&lt;br /&gt;
 #exit&lt;br /&gt;
 &lt;br /&gt;
 ~~&lt;br /&gt;
 &lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Der Beispiel-Code befindet sich auf der Seite xausza_page_ausza und baut die entsprechende Seite auf. Er prüft, ob bereits eine ID-Gesetzt ist - wenn nicht, wird über eine Datenbank-Sequenz die nächste ID abgefragt, in das VL-Segment geschrieben und die Seite gespeichert. Beim Speichern der Seite wird sie jedoch neu aufgerufen, also komplett neu aufgebaut, was erst einmal kein Problem ist. Danach würde aber die Ausführung auf der Code-Ebene, auf der sich #save befindet, fortgeführt, was zur Folge hat, dass die dann folgenden Segmente doppelt erscheinen (zunächst die aus dem Neu-Aufbau der Seite, dann die, die von der Fortsetzung des Codes her stammen).&lt;br /&gt;
&lt;br /&gt;
Um dies zu vermeiden muss die Ausführung des Codes nach #save abgebrochen werden.&lt;br /&gt;
&lt;br /&gt;
==$EXEC==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando. Im ausgeführten Kommando kann eine Variable gesetzt werden, die dann als Funktionsergebnis von $EXEC zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll&lt;br /&gt;
# optional: Der Name der Variablen, in der das Ergebnis steht; default ist ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #frm  c=&amp;quot;test_funkexec&amp;quot;   y=console&lt;br /&gt;
 #cout   c=$EXEC(test_funkexec_line)&lt;br /&gt;
&lt;br /&gt;
 -- test_funkexec_line&lt;br /&gt;
 #var_set   n=result   z=42&lt;br /&gt;
&lt;br /&gt;
=Dateien und Verzeichnisse=&lt;br /&gt;
&lt;br /&gt;
==#file_op==&lt;br /&gt;
&lt;br /&gt;
Führt eine Operation mit einer Datei oder einem Verzeichnis aus&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Name der Datei oder des Verzeichnisses&lt;br /&gt;
* n - Name der Variable oder Nummer des Values, in die/den das Ergebnis der Operation (Y oder N) geschrieben wird.&lt;br /&gt;
* on (&amp;quot;old name) - der bisherige Dateiname bei RenameFile&lt;br /&gt;
* y - Typ der Operation&lt;br /&gt;
** cd / createdir - Erzeugt ein Verzeichnis&lt;br /&gt;
** cf / copyfile - Kopiert eine Datei (von on zu fn)&lt;br /&gt;
** df / deletefile - Löscht eine Datei&lt;br /&gt;
** fd / forcedirectories - Stellt sicher, dass ein Pfad vorhanden ist&lt;br /&gt;
** rd / removedir - Entfernt ein Verzeichnis&lt;br /&gt;
** rf / renamefile - Benennt eine Datei um, kann auch dazu verwendet werden, eine Datei zu verschieben&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #file_op   y=renamefile   on=c:\temp\debug.txt   fn=c:\temp\test\debug.txt   n=1&lt;br /&gt;
 #cout   c=$VAL(1)&lt;br /&gt;
 &lt;br /&gt;
 #file_op   y=fd   fn=c:\eins\zwei\drei\vier&lt;br /&gt;
&lt;br /&gt;
==#file_search==&lt;br /&gt;
&lt;br /&gt;
Sucht Dateien und schreibt die Ergebnisliste in einen Text.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* clr - (&amp;quot;clear&amp;quot;) wenn Y, wird der Text vor der Suche geleert. Default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;number&amp;quot;) - Nummer des Textes, in den die Ergebnisliste geschrieben wird; default 1, Funktionen werden ersetzt.&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #file_search   fn=c:\*.ini   n=1   y=0   all_=Y&lt;br /&gt;
 #coutl $TEXT(1)&lt;br /&gt;
&lt;br /&gt;
==#file_wait==&lt;br /&gt;
&lt;br /&gt;
Wartet, bis zumindest eine Datei vorhanden ist, die den Kriterien entspricht, und führt dann cmd aus. Wird nach der in to eingestellten Zeit keine Datei gefunden, dann wird mit dem in cmdto eingestellten Kommando abgebrochen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* all - wenn Y, dann werden nach dem Dateinamen auch noch das Dateidatum, die Größe und die Attribute in den Text geschrieben. Default N, Funktionen werden ersetzt&lt;br /&gt;
* cmd - Kommando, das ausgeführt wird, sobald eine Datei gefunden wird; Funktionen werden ersetzt&lt;br /&gt;
* cmdto - Kommando, das ausgeführt wird, sobald die Prozedur wegen eines TimeOuts abgebrochen wird; Funktionen werden ersetzt&lt;br /&gt;
* cnd - (&amp;quot;condition&amp;quot;) Die Prozedur wird nur dann ausgeführt, wenn das Statement in cnd Y ergibt. Default ist Y, Funktionen werden ersetzt&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Suchstring, siehe Beispiel; Funktionen werden ersetzt&lt;br /&gt;
* sleep - Zeit in ms zwischen den einzelnen Suchen nach einer Datei, die den Kriterien entspricht; Default 1000, Funktionen werden ersetzt&lt;br /&gt;
* to (&amp;quot;TimeOut&amp;quot;) - Zeit in ms, nach der die Ausführung abgebrochen wird; Default 15000, Funktionen werden ersetzt&lt;br /&gt;
* y - Typ der Suche. Default AnyFile, Funktionen werden ersetzt&lt;br /&gt;
** AnyFile&lt;br /&gt;
** ReadOnly&lt;br /&gt;
** Hidden&lt;br /&gt;
** SysFile&lt;br /&gt;
** VolumeID&lt;br /&gt;
** Directory&lt;br /&gt;
** Archive&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cmd_clear #cout c=&amp;quot;Gefunden&amp;quot;&lt;br /&gt;
 #cmd_clear2 #cout c=&amp;quot;TimeOut&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #file_wait   fn=C:\temp\test\*.txt   cmd=1   cmdto=2&lt;br /&gt;
&lt;br /&gt;
==#dir_force==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass es den spezifizierten Verzeichnispfad gibt, indem erforderlichenfalls Verzeichnisse angelegt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Names des Pfads&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_force   n=c:\temp\pdf&lt;br /&gt;
&lt;br /&gt;
==#dir_proc==&lt;br /&gt;
&lt;br /&gt;
Durchsucht ein Verzeichnis nach Dateien, die den angegebenen Kriterien entsprechen, und führt für jede gefundene Datei ''cmd'' aus.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cmd (&amp;quot;command&amp;quot;) - Kommando, das für jede gefundene Datei ausgeführt wird&lt;br /&gt;
* dn (&amp;quot;DirectoryName&amp;quot;) - Pfad des Verzeichnisses, in dem die Dateien gesucht werden; Funktionen werden ersetzt.&lt;br /&gt;
* done - Verzeichnis, in das die Dateien nach Abarbeitung verschoben werden (sofern der Parameter nicht leer ist). Funktionen werden ersetzt.&lt;br /&gt;
* fn (&amp;quot;filename&amp;quot;) - Suchkriterium für den Dateinamen; Funktionen werden ersetzt; Default *&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Name der Variablen, in welcher der Dateiname der aktuell zu bearbeitenden Datei inklusive Pfad gespeichert wird; Funktionen werden ersetzt; Default dir_proc&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #dir_proc   dn=c:\temp\in   done=c:\temp\done   fn=*.csv   cmd=importcsv_line&lt;br /&gt;
&lt;br /&gt;
==$FILEINFO()==&lt;br /&gt;
&lt;br /&gt;
Liefert Infos über eine Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Dateiname&lt;br /&gt;
# Typ der Information, es stehen dabei folgende Optionen zur Verfügung&lt;br /&gt;
#* size - Dateigröße in Byte&lt;br /&gt;
#* size_point - Dateigröße in Byte, Punkte alle drei Zeichen von rechts&lt;br /&gt;
#* size_auto - Dateigröße in Byte, kB, MB oder GB, je nach Größe; mit Einheit&lt;br /&gt;
#* size_kb - Dateigröße in kB (analog Windows-Explorer)&lt;br /&gt;
#* date - Datum im Format dd.mm.yyyy&lt;br /&gt;
#* date_yyyy - Datum im Format yyyymmdd&lt;br /&gt;
#* datetime - Datum und Uhrzeit im Format dd.mm.yyyy hh:mm:ss&lt;br /&gt;
#* datetime_yyyy - Datum im Format yyyymmddhhmmss&lt;br /&gt;
#* exists - Y, wenn die Datei existiert, sonst N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=fn   z=&amp;quot;T:\Tools Gruppenrechte\BC3 light\BafClientFM.exe&amp;quot;&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_point)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_auto)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),size_kb)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),date_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),datetime_yyyy)&lt;br /&gt;
 #coutl $FILEINFO($VAR(fn),exists)&lt;br /&gt;
&lt;br /&gt;
Ergebnis&lt;br /&gt;
&lt;br /&gt;
 27668480&lt;br /&gt;
 27.668.480&lt;br /&gt;
 26,39 MB&lt;br /&gt;
 27.020 kB&lt;br /&gt;
 02.05.2023&lt;br /&gt;
 20230502&lt;br /&gt;
 02.05.2023 12:20:09&lt;br /&gt;
 20230502122009&lt;br /&gt;
 Y&lt;br /&gt;
&lt;br /&gt;
==$DIR()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Verzeichnisnamen. Trailing Path Delimiter (\ bei Windows) wird immer angehängt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bezeichnung des Verzeichnisses&lt;br /&gt;
## appdata - Verzeichnis für Anwendungsdaten des Users&lt;br /&gt;
## cappdata - gemeinsames Verzeichnis für Anwendungsdaten aller User&lt;br /&gt;
## cdoc - gemeinsames Dokumentenverzeichnis  aller User&lt;br /&gt;
## cfav / cfavorites - gemeinsames Favoritenverzeichnis aller User&lt;br /&gt;
## cmusic - gemeinsames Musikverzeichnis aller User&lt;br /&gt;
## cpic / cpictures - gemeinsames Bilderverzeichnis aller User&lt;br /&gt;
## cvideo - gemeinsames Videoverzeichnis aller User&lt;br /&gt;
## desktop - Desktopverzeichnis des Rechners&lt;br /&gt;
## '''doc''' / docdir - Dokumentenverzeichnis des Users&lt;br /&gt;
## downloads - Downloadsverzeichnis des Users&lt;br /&gt;
## fav / favorites - Favoritenverzeichnis des Users&lt;br /&gt;
## fonts - Fontsverzeichnis des Rechners&lt;br /&gt;
## music - Musikverzeichnis des Users&lt;br /&gt;
## pic / pictures - Bilderverzeichnis des Users&lt;br /&gt;
## prog / program - Programmverzeichnis des Rechners&lt;br /&gt;
## prog86 / program86 - Programm86-Verzeichnis des Rechners&lt;br /&gt;
## '''root''' - Root-Verzeichnis des BAF-Clients bzw. des BAF-Servers&lt;br /&gt;
## '''userroot''' / usrroot - User-Verzeichnis des BAF-Clients&lt;br /&gt;
## video - Videoverzeichnis des Users&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=$DIR(doc)test.txt&lt;br /&gt;
&lt;br /&gt;
==$FILEDIALOG()==&lt;br /&gt;
&lt;br /&gt;
Führt einen Dateiauswahl-Dialog aus und gibt den gewählten Dateinamen zurück. Im Falle des Abbruchs wird ''abort'' zurück gegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wenn der erste Parameter ''save'' lautet, wird ein Speichern-Dialog, sonst ein Öffnen-Dialog aufgerufen.&lt;br /&gt;
# Filter-Statement, immer Kombinationen aus Text (Text-Dateien *.txt) und Filter-Statement(*.txt), getrennt durch Pipes.&lt;br /&gt;
# Standard-Dateierweiterung&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text_save   fn=&amp;quot;$FILEDIALOG(save,Text-Dateien *.txt|*.txt|Alle Dateien *.*|*.*,txt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(Bitte beachten: Wegen der Leerzeichen im Filter-Statement muss der ganze Parameter in doppelte Anführungszeichen gesetzt werden.)&lt;br /&gt;
&lt;br /&gt;
=ZIP=&lt;br /&gt;
&lt;br /&gt;
==#zip_create==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine ZIP-Datei&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* cnd (&amp;quot;condition&amp;quot;) - Wenn Y, wird die Prozedur ausgeführt; default Y, Funktionen werden ersetzt&lt;br /&gt;
* cnt (&amp;quot;count&amp;quot;) - Anzahl der Dateien, die der ZIP-Datei hinzugefügt werden; Funktionen werden ersetzt&lt;br /&gt;
* dir (&amp;quot;directory&amp;quot;) - Verzeichnis, wenn das nicht bei allen fn1, fn2... angegeben werden soll&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Der Dateiname, unter dem die ZIP-Datei gespeichert wird; Funktionen werden ersetzt&lt;br /&gt;
* fn1, fn2,... (&amp;quot;FileName&amp;quot;) - Die Dateien, die in der ZIP-Datei gespeichert werden; die Anzahl wird mit dem Parameter cnt bestimmt; Funktionen werden ersetzt&lt;br /&gt;
* list - Nummer eines Textes (#text, #text2...), in dem die Dateien gelistet sind, die der ZIP-Datei hinzugefügt werden sollen. Wenn list ein Wert größer 0 hat, werden cnt und fn1, fn2... ignoriert. Default 0, Funktionen werden ersetzt.&lt;br /&gt;
* pw (&amp;quot;PassWord&amp;quot;) - Password der erzeugten ZIP-Datei; Funktionen werden ersetzt.&lt;br /&gt;
* pwc (&amp;quot;PassWordCrypted&amp;quot;) - Wenn Y, dann ist das Passwort mit der Verschlüsselungsfunktion auf der Seite Tools des Code-Dialogs verschlüsselt. Hinweis: Mit dieser Verschlüsselung verhindert man lediglich, dass das Passwort direkt aus dem Code ausgelesen werden kann. Wird der BAF-Client mit dem Delphi-Debugger ausgeführt, lässt sich leicht an die betreffende Stelle ein Breakpoint setzen und das Passwort dann im Klartext auslesen (dieselbe Unit uBafCrypt vorausgesetzt).&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
 #zip_create   fn=$VAR(root).zip   list=1&lt;br /&gt;
 &lt;br /&gt;
 #var_set   n=fn_zip   z=tt_mail_$VAR(reise)-$VAR(reisename)_$PAD($VAR(lfdnr),4,L,0)_$NOWFMT(yyyymmdd).zip&lt;br /&gt;
 #file_op   y=df   fn=$VAR(path)\$VAR(fn_zip)&lt;br /&gt;
 #code cnt=2&lt;br /&gt;
 #code fn1=$VAR(filename).txt&lt;br /&gt;
 #code fn2=$VAR(filename).sab&lt;br /&gt;
 #zip_create   dir=$VAR(path)   fn=$VAR(path)\$VAR(fn_zip)    pw=$VAR(pw)   $CODE$&lt;br /&gt;
&lt;br /&gt;
Die Prozedur #zip_create ersetzt nicht vorherige Dateien. Von daher im Zweifelsfall wie im zweiten Beispiel vorher eine Datei dieses Namens löschen.&lt;br /&gt;
&lt;br /&gt;
=Ini-Dateien=&lt;br /&gt;
&lt;br /&gt;
Der BAF-Client verwendet eine Ini-Datei im Root-Verzeichnis (vor allem für die Datenbankverbindungen) und eine Ini-Datei ''BafClientFM.ini'' im User-Anwendungsverzeichnis (vor allem für die Formularpositionen). Es können aber auch weitere Ini-Dateien verwendet werden.&lt;br /&gt;
&lt;br /&gt;
==#ini_val==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Wert in die Ini-Datei. #ini_val ist eine nummerierte Prozedur: #ini_val schreibt in die erste Ini-Datei, #ini_val2 in die zweite Ini-Datei und so weiter. Diese Ini-Dateien werden zunächst nur im Speicher gehalten und müssen explizit aus einer Datei geladen oder in eine Datei gespeichert werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* i (&amp;quot;item&amp;quot; / &amp;quot;ident&amp;quot;) - Name des Eintrags in der Ini-Datei; Funktionen werden ersetzt&lt;br /&gt;
* n (&amp;quot;name&amp;quot;) - Wenn der Parameter n den Wert ''usr'' oder ''user'' hat, dann bleibt die Nummer der Ini-Datei unberücksichtigt und der Wert wird in die Datei ''BafClientFM.ini'' im im User-Anwendungsverzeichnis geschrieben.&lt;br /&gt;
* sec (&amp;quot;section&amp;quot;) - Abschnitt in der Ini-Datei; Funktionen werden ersetzt; default ''values''&lt;br /&gt;
* z - Wert, der in die Ini-Datei geschrieben wird; Funktionen werden ersetzt.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_val  i=date_last   z=$NOW()&lt;br /&gt;
&lt;br /&gt;
==#ini_load==&lt;br /&gt;
&lt;br /&gt;
Lädt eine Ini-Datei aus einer Datei. Es handelt sich um eine nummerierte Prozedur: #ini_load lädt die Ini-Datei 1, #ini_load2 lädt die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, die geladen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_load   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==#ini_save==&lt;br /&gt;
&lt;br /&gt;
Speichert eine Ini-Datei ineine Datei. Es handelt sich um eine nummerierte Prozedur: #ini_save speichert die Ini-Datei 1, #ini_save2 speichert die Ini-Datei 2 und so weiter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* fn (&amp;quot;FileName&amp;quot;) - Dateiname der Datei, in die gespeichert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #ini_save   fn=$DIR(userroot)werte.ini&lt;br /&gt;
&lt;br /&gt;
==$INI()==&lt;br /&gt;
&lt;br /&gt;
Liest einen Wert aus einer Ini-Datei.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
# Item (Ident)&lt;br /&gt;
# optional: Sektion; wenn nicht vorhanden, dann ''values''. Wenn ''db!'', dann wird als Sektion die aktuell gewählte Datenbankverbindung verwendet (in diesem Fall sollte als erster Parameter ''root'' verwendet werden).&lt;br /&gt;
# optional: Default-Wert; wenn nicht vorhanden, dann ein leerer String&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum)&lt;br /&gt;
 #var_set   n=datum   z=$INI(1,datum,bearbeitung,$TODAY())&lt;br /&gt;
&lt;br /&gt;
==$INITEXT()==&lt;br /&gt;
&lt;br /&gt;
Gibt die komplette Ini-Datei zurück. Wird vor allem beim Debugging verwendet.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer der Ini-Datei, alternativ ''usr'' oder ''root''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $INITEXT(usr)&lt;br /&gt;
&lt;br /&gt;
=Zwischenablage=&lt;br /&gt;
&lt;br /&gt;
Das BAF-Framework unterstützt die Zwischenablage nur für Text.&lt;br /&gt;
&lt;br /&gt;
==#clipboard==&lt;br /&gt;
&lt;br /&gt;
Schreibt einen Text in die Zwischenablage&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
* z - Wert, der in der Zwischenablage gespeichert werden soll; Funktionen werden ersetzt&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #clipboard   z=$TEXT()&lt;br /&gt;
 #clipboard   z=$CHR(dquote)$PVAL(test,zahl,allsel,$CHR(crlf))$CHR(dquote)&lt;br /&gt;
&lt;br /&gt;
==$CLIPBOARD()==&lt;br /&gt;
&lt;br /&gt;
Gibt den Text aus der Zwischenablage zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setvar   n=clp   z=$CLIPBOARD()&lt;br /&gt;
&lt;br /&gt;
=String-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben einen String zurück.&lt;br /&gt;
&lt;br /&gt;
==$BASE64()==&lt;br /&gt;
&lt;br /&gt;
En- oder Decodiert einen Text im Base64-Code&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Encoding oder Decoding:&lt;br /&gt;
## e - Encoding&lt;br /&gt;
## d - Decoding&lt;br /&gt;
# Text, der en-oder decodet werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $BASE64(e,Dies ist ein Test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$CHR()==&lt;br /&gt;
&lt;br /&gt;
Gibt ein Zeichen (ggf zwei Zeichen) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Ansi-Zeichennummer oder eine der folgenden Bezeichnungen:&lt;br /&gt;
## crlf - Zeilenumbruch #13#10&lt;br /&gt;
## cr - Zeichen #13&lt;br /&gt;
## lf - Zeichen #10&lt;br /&gt;
## tab - Tabulator&lt;br /&gt;
## quote - ' (einfache Anführungszeichen)&lt;br /&gt;
## dquote - &amp;quot; (doppelte Anführungszeichen)&lt;br /&gt;
## space / leer - Leerzeichen&lt;br /&gt;
## comma / komma - , (Komma)&lt;br /&gt;
## questionmark / qmark / frage / fragezeichen - ?&lt;br /&gt;
## bro / bracket_open - (&lt;br /&gt;
## brc / bracket_close - )&lt;br /&gt;
## dollar - $&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #exec   cmd=&amp;quot;xtodo_page_add(XU,$PVAL(vl,user_user_id),$PVAL(vl,login),$PVAL(vl,shortname)$CHR(crlf)$PVAL(vl,firstname) $PVAL(vl,lastname))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CONVERT()==&lt;br /&gt;
&lt;br /&gt;
Konvertiert einen String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Konvertierungsfunktion&lt;br /&gt;
## isodate&lt;br /&gt;
## isodatetime&lt;br /&gt;
## truefalse&lt;br /&gt;
## pointfloat&lt;br /&gt;
## urlcode&lt;br /&gt;
## utf8&lt;br /&gt;
# String, der konvertiert werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
==$COPY()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$COPY($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$EXEC()==&lt;br /&gt;
&lt;br /&gt;
Führt ein Kommando aus und gibt ein Funktionsergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Kommando, das ausgeführt werden soll.&lt;br /&gt;
# optional: Name der Variable, die als Funktionsergebnis zurück gegeben werden soll; default ''result''&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=test   z=$EXEC(testkommando)&lt;br /&gt;
&lt;br /&gt;
==$GUID()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt eine GUID und gibt sie zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# optional: Name einer Variablen, in welcher die GUID zusätzlich gespeichert wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   kid=$GUID()&lt;br /&gt;
&lt;br /&gt;
==$HASH()==&lt;br /&gt;
&lt;br /&gt;
Erzeugt einen Hash-Wert vom String im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, von welchem der Hash gebildet werden soll.&lt;br /&gt;
# zu verwendender Hash-Algorithmus:&lt;br /&gt;
## sha512&lt;br /&gt;
## sha512_256&lt;br /&gt;
## sha512_224&lt;br /&gt;
## sha384&lt;br /&gt;
## sha256&lt;br /&gt;
## sha224&lt;br /&gt;
## sha1&lt;br /&gt;
## md5 (Hinweis: MD5 gilt seit Längerem als nicht mehr sicher. Verwenden Sie ihn nur, wenn dies aus Gründen der Abwärts-Kompatbilität zwingend ist.)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$HASH($PVAL(vl,1,2),sha512)&lt;br /&gt;
&lt;br /&gt;
==$INCLUDE()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass der als dritter Parameter übergebene Text am Anfang oder am Ende steht, gegebenenfalls wird er dort eingefügt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## lead(oder leading) - Text muss am Anfang stehen&lt;br /&gt;
## leadci(oder leadingci oder leadingcaseinsensitive) - Text muss am Anfang stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
## trail(oder trailing) - Text muss am Ende stehen&lt;br /&gt;
## trailci(oder trailci oder trailingcaseinsensitive) - Text muss am Ende stehen, Groß- und Kleinschreibung wird ignoriert&lt;br /&gt;
# Text, in den gegebenenfalls eingefügt wird&lt;br /&gt;
# Text, der gegebenenfalls eingefügt wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCLUDE(trailci,test.PDF,.pdf)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$INVLOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt den Key aus einer Nachschlageliste bei Übergabe des Values.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Value des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$INVLOOKUP(general_status,aktiv,Wert nicht vorhanden)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOOKUP()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen Wert aus einer Nachschlageliste.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Nachschlageliste&lt;br /&gt;
# Key des Eintrags&lt;br /&gt;
# Default-Wert; wird verwendet, wenn der Rückgabe-Wert leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$LOOKUP(general_status,1,Status nicht gesetzt)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$LOW()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Kleinbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Kleinbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LOW($EDT(edt1)) = bus&lt;br /&gt;
&lt;br /&gt;
==$LOWNOSPACE()==&lt;br /&gt;
&lt;br /&gt;
Wandelt einen String in Kleinbuchstaben und ersetzt alle Leerzeichen durch Unterstriche.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der gewandelt werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$LOWNOSPACE($PVAL(vl,1,2))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$NOCRLF()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Zeilenumbrüche&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem die Zeilenumbrüche entfernt werden sollen&lt;br /&gt;
# optional: Zeichenfolge, die an Stelle der Zeilenumbrüche eingefügt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=2   z=$NOCRLF($VAL(1),;)&lt;br /&gt;
&lt;br /&gt;
==$NVL()==&lt;br /&gt;
&lt;br /&gt;
Liefert einen Ersatzwert, wenn der Wert leer ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird&lt;br /&gt;
# String, der als Funktionsergebnis zurückgegeben wird, wenn der erste Parameter leer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   where ckey &amp;lt;= $NVL($PVAL(grid,nummer,lookuplive),0)&lt;br /&gt;
&lt;br /&gt;
Liefert $PVAL einen leeren Wert zurück (z.B., weil die Gridzeile neu angelegt wurde und daher noch keine Nummer eingetragen ist), so wird statt dessen 0 verwendet, damit die WHERE-Klausel syntaktisch korrekt ist.&lt;br /&gt;
&lt;br /&gt;
==$ONLYCHAR()==&lt;br /&gt;
&lt;br /&gt;
Entfernt unerwünschte Zeichen aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# optional: Typ der Funktion&lt;br /&gt;
## (leer) - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z', 'ä', 'ö', 'ü', 'Ä','Ö', 'Ü', 'ß']) sind&lt;br /&gt;
## charnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind&lt;br /&gt;
## low - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## upp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## charnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben&lt;br /&gt;
## charnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben&lt;br /&gt;
## uml - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben (['a'..'z', 'A'..'Z') sind, Umlaute werden konvertiert (ä -&amp;gt; ae, ö -&amp;gt; oe, ü -&amp;gt; ue, Ä -&amp;gt; Ae, Ö -&amp;gt; Oe, Ü -&amp;gt; Ue, ß -&amp;gt; ss)&lt;br /&gt;
## umlcharnum - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Umlaute werden konvertiert&lt;br /&gt;
## umllow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumlow - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Kleinbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## umlcharnumupp - Es werden alle Zeichen aus dem String entfernt, die keine Buchstaben oder Zahlen sind, Ergebnis in Großbuchstaben, Umlaute werden konvertiert&lt;br /&gt;
## no191 / not191 - Es werden alle Zeichen mit der ANSI-Nummer 191 (¿) entfernt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg)&lt;br /&gt;
 #coutl $ONLYCHAR(Baden-Württemberg,umllow)&lt;br /&gt;
&lt;br /&gt;
==$PAD()==&lt;br /&gt;
&lt;br /&gt;
Füllt links oder rechts bis zur vorgegebenen Länge mit Zeichen auf.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Der ursprüngliche String&lt;br /&gt;
# Soll-Länge. Ist der ursprüngliche String bereits länger, wird er nicht gekürzt, es werden aber auch keine weiteren Zeichen hinzugefügt&lt;br /&gt;
# Wenn L, werden die Zeichen vorne hinzugefügt, andernfalls hinten&lt;br /&gt;
# Zeichen, die soweit und so oft hinzugefügt werden, bis die Soll-Länge erreicht ist. Umfasst der Parameter mehrere Zeichen, werden diese ggf. nicht alle hinzugefügt.&lt;br /&gt;
# optional: Länge, auf die der ursprüngliche String vor der weiteren Verarbeitung gekürzt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 sql   text1 = '$PAD($VAR(text1),70,R, )'&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ des Ergebnisses&lt;br /&gt;
## curr - Zahl mit zwei Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## curr4 - Zahl mit vier Nachkommastellen in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## date - Datum in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## int - ganze Zahl  in den Grenzen Parameter 2 - Parameter 3&lt;br /&gt;
## ld - Key einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ldv - Value einer Nachschlageliste, Name der Nachschlageliste im Parameter 2 &lt;br /&gt;
## ls - Key eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## lsv - Value eines Specials, Name des Specials im Parameter 2 &lt;br /&gt;
## text, text2, text3... - Zeile eines Textes&lt;br /&gt;
# untere Grenze bzw. Name der Nachschlageliste oder des Specials&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $RANDOM(date,01.01.2022,31.12.2022)&lt;br /&gt;
 #coutl $RANDOM(text2)&lt;br /&gt;
&lt;br /&gt;
==$SUBSTR()==&lt;br /&gt;
&lt;br /&gt;
Kopiert aus dem String im ersten Parameter einen Teil der Zeichen.&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Selbe Funktionalität wie $COPY())&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem kopiert werden soll&lt;br /&gt;
# Position im String, ab dem Zeichen kopiert werden sollen&lt;br /&gt;
# optional: Anzahl der Zeichen, die kopiert werden sollen. Wenn dieser Parameter fehlt, werden alle Zeichen ab der angegebenen Position kopiert.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #grdcol   f=ref   c1=&amp;quot;Ref&amp;quot;   w=30  y=link   ro=Y   cmdn=xtodo_add(link,$SUBSTR($PVAL(grid,ctype,sel),1,2))&lt;br /&gt;
&lt;br /&gt;
==$STREP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string replace&amp;quot;) Ersetzt Zeichen im String durch andere Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, in welchen Zeichen ersetzt werden sollen.&lt;br /&gt;
# Zeichen, die ersetzt werden sollen&lt;br /&gt;
# Zeichen, die an deren Stelle treten sollen&lt;br /&gt;
# optional: Optionen (kombinierbar)&lt;br /&gt;
## i - Groß- und Kleinschreibung ignorieren &lt;br /&gt;
## a - Alle Vorkommen ersetzen (andernfalls wird nur das erste Vorkommen ersetzt)&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=&amp;quot;$STREP($PVAL(vl,1,2), ,_,a)&amp;quot;&lt;br /&gt;
 #page_val   i=vl   col=1   row=3   z=$STREP($PVAL(vl,1,2),$CHR(space),_,a)&lt;br /&gt;
&lt;br /&gt;
Hinweis: Beide Beispiele haben exakt dieselbe Funktion. Im oberen Beispiel steht das Leerzeichen direkt im Text, dafür muss der komplette Parameter in doppelte Anführungszeichen, im unteren Beispiel wird das Leerzeichen durch $CHR(space) eingefügt, dafür können die Leerzeichen unterbleiben.&lt;br /&gt;
&lt;br /&gt;
==$STROP()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string operation&amp;quot;) Sammelsurium von String-Operationen&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ der Operation&lt;br /&gt;
## trim - entfernt führende und folgende Leerzeichen&lt;br /&gt;
## trimleft - entfernt führende Leerzeichen&lt;br /&gt;
## trimright - entferne folgende Leerzeichen&lt;br /&gt;
## quote - setzt den String in einfache Anführungszeichen&lt;br /&gt;
## unquote - entfernt einschließende einfache Anführungszeichen&lt;br /&gt;
## dquote - setzt den String in doppelte Anführungszeichen&lt;br /&gt;
## unqduote - entfernt einschließende doppelte Anführungszeichen&lt;br /&gt;
## ex_filepath - entspricht der Delphi-Funktion ExtractFilePath&lt;br /&gt;
## ex_filedir - entspricht der Delphi-Funktion ExtractFileDir&lt;br /&gt;
## ex_filedrive - entspricht der Delphi-Funktion ExtractFileDrive&lt;br /&gt;
## ex_filename - entspricht der Delphi-Funktion ExtractFileName&lt;br /&gt;
## ex_fileext - entspricht der Delphi-Funktion ExtractFileExt&lt;br /&gt;
# String, der bearbeitet werden soll&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$STROP(quote,Test)&lt;br /&gt;
&lt;br /&gt;
==$STREXTR()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;string extract&amp;quot;) Extrahiert einen Teil aus einem String.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, aus dem extrahiert werden soll&lt;br /&gt;
# Extraktionstyp&lt;br /&gt;
## ffe (&amp;quot;from first exclude&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## ffi (&amp;quot;from first include&amp;quot;) - Extrahiert ab der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tfe (&amp;quot;to first exclude&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tfi (&amp;quot;to first include&amp;quot;) - Extrahiert bis zur Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## fle (&amp;quot;from last exclude&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## fli (&amp;quot;from last include&amp;quot;) - Extrahiert ab dem letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
## tle (&amp;quot;to last  exclude&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge aus&lt;br /&gt;
## tli (&amp;quot;to last include&amp;quot;) - Extrahiert bis zum letzten Vorkommen der Zeichenfolge im dritten Parameter und schließt diese Zeichenfolge ein&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Trennzeichen&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffe,;)&amp;quot;    -- Ergebnis: test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,ffi,;)&amp;quot;    -- Ergebnis: ;test2&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfe,;)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;test2,tfi,;)&amp;quot;    -- Ergebnis: test;&lt;br /&gt;
 #cout   c=&amp;quot;$STREXTR(test;!§§test2,tfe,;!§§)&amp;quot;    -- Ergebnis: test&lt;br /&gt;
&lt;br /&gt;
==$TRIM()==&lt;br /&gt;
&lt;br /&gt;
Entfernt Leerzeichen und Zeilenumbrüche am Rand des Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der getrimmt werden soll&lt;br /&gt;
# optional&lt;br /&gt;
## L - trimmt nur auf der linken Seite&lt;br /&gt;
## R - trimmt nur auf der rechten Seite&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #var_set   n=test   z=$TRIM($VAL(1),R)&lt;br /&gt;
&lt;br /&gt;
==$UPP()==&lt;br /&gt;
&lt;br /&gt;
Wandelt den übergebenen String in Großbuchstaben um.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der in Großbuchstaben gewandelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $UPP($EDT(edt1)) = BUS&lt;br /&gt;
&lt;br /&gt;
==$VT()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VT (&amp;quot;Value Translate&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Vergleichswert 1&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 1 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 2&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 2 dem ersten Parameter entspricht &lt;br /&gt;
# Vergleichswert 3&lt;br /&gt;
# Ergebnis, wenn Vergleichswert 3 dem ersten Parameter entspricht &lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VT(Frau,1,Herr,2,Frau,3)&lt;br /&gt;
 -- Frau -&amp;gt; 3&lt;br /&gt;
 -- Herr -&amp;gt; 2&lt;br /&gt;
 -- Test -&amp;gt; 1&lt;br /&gt;
 -- Firma -&amp;gt; 1&lt;br /&gt;
&lt;br /&gt;
==$VTVL()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VTVL (&amp;quot;Value Translate ValueList&amp;quot;) ersetzt Werte durch andere. Groß- und Kleinschreibung wird beim Vergleich berücksichtigt.&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu $VT werden die zu prüfenden Werte und deren Entsprechungen nicht über Parameter übergeben, sondern aus einer Werte-Liste geholt, die in einem Text gespeichert sein muss.&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich wie folgt aufbauen&lt;br /&gt;
&lt;br /&gt;
 key1=value1&lt;br /&gt;
 key2=value2&lt;br /&gt;
 key3=value3&lt;br /&gt;
 key4=value4&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Eine solche Werte-Liste lässt sich auch mit #sql_opentvl erzeugen, siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalte ersetzt werden soll&lt;br /&gt;
# Else-Ergebnis; wird dann verwendet, wenn keine andere Entsprechung erkannt wird.&lt;br /&gt;
# Nummer des Textes, in dem sich die Werteliste befindet.&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql select userid as ckey, shortname as cvalue from user_user&lt;br /&gt;
 #sql_opentvl n=1&lt;br /&gt;
 #coutl $VTVL(591,(nicht gefunden),1)&lt;br /&gt;
&lt;br /&gt;
==$XR()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $XR (&amp;quot;XmlReplace&amp;quot;) ersetzt in XML nicht zulässige Zeichen:&lt;br /&gt;
* aus &amp;amp; wird $amp ;&lt;br /&gt;
* aus &amp;lt; wird &amp;amp;lt ;&lt;br /&gt;
* aus &amp;gt; wird &amp;amp;gt ;&lt;br /&gt;
* aus &amp;quot; wird &amp;amp;quot ;&lt;br /&gt;
* aus ' wird &amp;amp;apos ;&lt;br /&gt;
&lt;br /&gt;
(Hinweis: Das Leerzeichen vor dem Semikolon soll verhindern, dass die Zeichen hier in der Darstellung ersetzt werden und wird nicht eingefügt.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #text &amp;lt;firmenname&amp;gt;$XR($DATA(dat,firmenname))&amp;lt;/firmenname&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==$XRR()==&lt;br /&gt;
&lt;br /&gt;
Umkehrfunktion von $XR()&lt;br /&gt;
* aus $amp ; wird &amp;amp;&lt;br /&gt;
* aus &amp;amp;lt ; wird &amp;lt;&lt;br /&gt;
* aus &amp;amp;gt ; wird &amp;gt;&lt;br /&gt;
* aus &amp;amp;quot ; wird &amp;quot;&lt;br /&gt;
* aus &amp;amp;apos ; wird '&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Zeichen ggf. ersetzt werden sollen&lt;br /&gt;
&lt;br /&gt;
=Integer-Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben eine ganze Zahl zurück&lt;br /&gt;
&lt;br /&gt;
==$DEC()==&lt;br /&gt;
&lt;br /&gt;
Verringert die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die verringert werden soll.&lt;br /&gt;
# optional: Zahl, um die verringert werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$DEC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ICALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit ganzzahligen Werten durch.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator, es stehen zur Verfügung&lt;br /&gt;
## +&lt;br /&gt;
## -&lt;br /&gt;
## *&lt;br /&gt;
## div&lt;br /&gt;
## mod&lt;br /&gt;
# Erste Zahl&lt;br /&gt;
# Zweite Zahl&lt;br /&gt;
# optional beim Operator +: weitere Summanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$ICALC(mod,17,5)&lt;br /&gt;
&lt;br /&gt;
==$INC()==&lt;br /&gt;
&lt;br /&gt;
Erhöht die Zahl im ersten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl die erhöht werden soll.&lt;br /&gt;
# optional: Zahl, um die erhöht werden soll. Wenn nicht vorhanden, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #setval   n=1   z=$INC($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$INTLEN()==&lt;br /&gt;
&lt;br /&gt;
Ist der String im Parameter eine ganz Zahl, dann wird deren Länge in Zeichen zurückgegeben, andernfalls -1; ein leerer String im ersten Parameter ergibt 0.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, deren Länge ermittelt wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTLEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Länge eines Strings in Zeichen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Länge ermittelt werden soll.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $LEN($EDT(edt1)) = 4&lt;br /&gt;
&lt;br /&gt;
==$LEVENSHTEIN()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Levenshtein-Distanz (https://de.wikipedia.org/wiki/Levenshtein-Distanz) der beiden übergebenen Strings&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# erster String&lt;br /&gt;
# zweiter String&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $LEVENSHTEIN(alpha,beta)&lt;br /&gt;
&lt;br /&gt;
==$POS()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt die Position des Substrings in einem String. Das Funktionsergebnis ist die Position, das erste Zeichen ist 1. 0 wird zurück gegeben, wenn der Substring im String nicht vorkommt.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Substring (nach dem gesucht wird)&lt;br /&gt;
# String (in dem gesucht wird)&lt;br /&gt;
# optional: Wenn ic (ignore case), dann wird bei der Suche die Groß- und Kleinschreibung nicht beachtet.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $POS($EDT(edt1),$VAR(1),ic) &amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
==$RANDOM()==&lt;br /&gt;
&lt;br /&gt;
Ermittelt einen zufälligen Wert zwischen der oberen und unteren Grenze&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Typ&lt;br /&gt;
## int - zufällige Ganzzahl &lt;br /&gt;
## date - zufälliges Datum &lt;br /&gt;
## curr - zufällige Zahl mit zwei Nachkommastellen&lt;br /&gt;
## curr4 - zufällige Zahl mit vier Nachkommastellen&lt;br /&gt;
## text1, text2, text3... - zufällige Zeile aus dem jeweiligen Text; text ist text1; untere und obere Grenze bleiben unberücksichtigt&lt;br /&gt;
## ld - zufälliger Schlüssel-Wert aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ldv - zufälliger Text aus einer Nachschlageliste. Der Name der Nachschlageliste ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## ls - zufälliger Schlüssel-Wert aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
## lsv - zufälliger Text aus einem Special. Der Name des Specials ist als zweiter Parameter (untere Grenze) zu übergeben&lt;br /&gt;
# untere Grenze&lt;br /&gt;
# obere Grenze&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
#coutl $RANDOM(int,1,6)&lt;br /&gt;
&lt;br /&gt;
=Datumsfunktionen=&lt;br /&gt;
&lt;br /&gt;
==$INCDATE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktione  $INCDATE() verändert das Datum im ersten Parameter um die Anzahl Tage im zweiten Parameter.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das verändert werden soll&lt;br /&gt;
# optional: Die Tage, um die verändert werden soll; wenn leer, dann 1.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=$INCDATE($NOW(),-3)   clr=Y&lt;br /&gt;
&lt;br /&gt;
==$INT2TIME()==&lt;br /&gt;
&lt;br /&gt;
Macht aus z.B. 1130 die Zeit 11:30&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zeit im Integer-Format&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_time=$INT2TIME($VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$NOW()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit im Format dd.mm.yyyy hh:mm:ss zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #execsql   k_datechg=$NOW()&lt;br /&gt;
&lt;br /&gt;
==$NOWFMT()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und/oder die aktuelle Uhrzeit im angegebenen Format zurück.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Formatierungsstring (Syntax wie FormatDateTime in Delphi)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$NOWFMT(yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$NOWMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum und die aktuelle Uhrzeit ohne Sekunden (also dd.mm.yyyy hh:mm) zurück&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$NOWMIN()&lt;br /&gt;
&lt;br /&gt;
==$TODAY()==&lt;br /&gt;
&lt;br /&gt;
Gibt das aktuelle Datum im Format dd.mm.yyyy zurück.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Wenn das Datum in einem anderen Format benötigt wird, ist $NOWFMT() das Mittel der Wahl.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
(keine)&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=$TODAY()&lt;br /&gt;
&lt;br /&gt;
==$DFMT()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;date formated&amp;quot;) Formatiert das übergebene Datum. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, ggf. mit Uhrzeit, das formatiert werden soll.&lt;br /&gt;
# Formatierungsstring wie in Delphi&lt;br /&gt;
# optional: Wenn hn (&amp;quot;hide null&amp;quot;), dann wird ein leerer String zurück gegeben, wenn das Datum kleiner/gleich 1&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #sql_exec   k_datechg=&amp;quot;$DFMT($NOW(),yyyy-mm-dd hh:mm:ss)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=Bool'sche Funktionen=&lt;br /&gt;
&lt;br /&gt;
Die folgenden Funktionen geben Y oder N zurück.&lt;br /&gt;
&lt;br /&gt;
==$BFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert einen bool'schen Wert&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'scher Wert&lt;br /&gt;
# optional: Ergebnis, wenn Wert Y ('y', 'J', 'j', '1') ist, default Y&lt;br /&gt;
# optional: Ergebnis, wenn Wert N (also nicht 'Y', 'y', 'J', 'j', '1') ist, default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 #cout   c=$BFMT($VAR(test),x,)&lt;br /&gt;
&lt;br /&gt;
==$BOOL()==&lt;br /&gt;
&lt;br /&gt;
Wertet das bool'sche Statement im Parameter aus.&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
* = gleich&lt;br /&gt;
* == gleich ohne Berücksichtigung der Groß- und Kleinschreibung&lt;br /&gt;
* &amp;lt;&amp;gt; ungleich&lt;br /&gt;
* != ungleich&lt;br /&gt;
* &amp;gt; größer&lt;br /&gt;
* &amp;gt;= größer gleich&lt;br /&gt;
* &amp;lt; kleiner&lt;br /&gt;
* &amp;lt;= kleiner gleich &lt;br /&gt;
* and Und-Verknüpfung&lt;br /&gt;
* or ODER-Verknüpfung&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die Statements werden von links nach rechts ausgewertet, and und or sind gleichwetig, gegebenenfalls müssen Klammern eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Bool'sches Statement, das ausgewertet wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL((17 &amp;gt; 22) or (5 &amp;gt; 3))&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$BOOL(17 &amp;gt; 22 or 5 &amp;gt; 3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATECOMP()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn Datum 2 Operator Datum 1 zutreffend ist. Ansonsten wird N zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Wird kein Operator angegeben, dann wird die Anzahl der Tage Datum 2 - Datum 1 als Zahl zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum 1&lt;br /&gt;
# Datum 2&lt;br /&gt;
# Operator&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024,&amp;lt;)&amp;quot;&lt;br /&gt;
 #cout   c=&amp;quot;$DATECOMP(01.01.2024,17.04.2024)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$DATEMINREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMINREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEMAXREL()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) dem aktuellen Datum ist, das um die Anzahl Tage im zweiten Parameter verändert wurde. Wird gerne verwendet, um das Erreichen von Deadlines zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Datum, das geprüft wird&lt;br /&gt;
# Anzahl an Tage, die dem aktuellen Datum vor der Prüfung hinzu addiert werden&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $DATEMAXREL($DATA(n,datum), 3)&lt;br /&gt;
&lt;br /&gt;
==$DATEBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn das Datum des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in ein Datum wandeln lassen, werden zu 0 (30.12.1899) konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter diesem Datum entspricht. &lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #cout   c=&amp;quot;Test $DATEBETWEEN($TODAY(),1.1.2020,2.2.2022)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$EMPTY()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn der Parameter ein leerer String ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTY($DATE(n,grpname))&lt;br /&gt;
&lt;br /&gt;
==$EMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable ein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $EMPTYVAR(buchungsnr)&lt;br /&gt;
&lt;br /&gt;
==$IN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $INIC() beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Die erste Anweisung gibt Y und die zweite N zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$IN(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$INIC()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der erste Parameter in der Menge der nachfolgenden Parameter befindet. Groß- und Kleinschreibung wird im Gegensatz zu $IN() nicht beachtet beachtet&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Liste, gegen die geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
Beide Anweisungen geben Y zurück&lt;br /&gt;
&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,beta,gamma,delta)&amp;quot;&lt;br /&gt;
 #cout    c=&amp;quot;$INIC(beta,alpha,BETA,gamma,delta)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$ISCURR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen Currency-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISCURR($DATA(n,rechnungssumme))&lt;br /&gt;
&lt;br /&gt;
==$ISDATE()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in ein Datums- oder DatumsZeit-Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Prüfoperation, default ist date&lt;br /&gt;
## date - prüft, ob in ein Datum gewandelt werden kann&lt;br /&gt;
## datetime - prüft, ob in ein Datums-Zeit-Wert gewandelt werden kann&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISDATE($DATA(n,beginn))&lt;br /&gt;
&lt;br /&gt;
==$ISINT()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn sich der Parameter in einen ganzzahligen Wert wandeln lässt&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
~ $ISINT($DATA(n,tage))&lt;br /&gt;
&lt;br /&gt;
==$INTMAX()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht größer (&amp;quot;maximal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMAX($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$INTMIN()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl im ersten Parameter nicht kleiner (&amp;quot;minimal gleich&amp;quot;) als die Zahl im zweiten Parameter ist.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl, die verglichen wird&lt;br /&gt;
# Zahl. mit der vergleichen wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $INTMIN($DATA(n,lfdnr), 17)&lt;br /&gt;
&lt;br /&gt;
==$NEMPTY()==&lt;br /&gt;
&lt;br /&gt;
(&amp;quot;not empty&amp;quot;) Gibt Y zurück, wenn der Parameter nicht leer ist. &lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, dessen Inhalt geprüft wird. Leerzeichen gelten als leerer String.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 &lt;br /&gt;
 ~ $NEMPTY($EDT(edt1))&lt;br /&gt;
&lt;br /&gt;
==$NEMPTYVAR()==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Variable kein leerer String ist, deren Name im Parameter ist. (Leerzeichen zählen auch als leerer String.)&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Name der Variable&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $NEMPTYVAR(kundennr)&lt;br /&gt;
&lt;br /&gt;
==$NOT==&lt;br /&gt;
&lt;br /&gt;
Invertiert einen bool'schen Wert. Aus Y (y, J, j, 1) wird N und aus N wird Y.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der invertiert wird&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $NOT(2)&lt;br /&gt;
&lt;br /&gt;
==$NUMBETWEEN==&lt;br /&gt;
&lt;br /&gt;
Gibt Y zurück, wenn die Zahl des ersten Parameters im angegebenen Bereich liegt.&lt;br /&gt;
&lt;br /&gt;
Alle Paremeter, die sich nicht in eine Zahl wandeln lassen, werden zu 0 konvertiert.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert, der geprüft wird&lt;br /&gt;
# Untere Grenze des Bereichs&lt;br /&gt;
# Obere Grenze des Bereichs&lt;br /&gt;
# und weitere: Das Ergebnis ist auch dann Y, wenn der erste Parameter dieser Zahl entspricht. Siehe Beispiel.&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56)&amp;quot;&lt;br /&gt;
 #page_check   c=&amp;quot;Die Schuhgröße muss zwischen 28 und 56 liegen&amp;quot;   chk=&amp;quot;$NUMBETWEEN($PVAL(vl,schuhgroesse),28,56,)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Die beiden Beispiele unterscheiden sich auf den ersten Blick kaum. Bei der ersten Zeile muss jedoch eine Schuhgröße eingegeben werden. Bleibt das Feld im VL-Segment leer, so wird dieser fehlende Wert nach 0 konvertiert und liegt nicht zwischen 28 und 56.&lt;br /&gt;
&lt;br /&gt;
Anders bei der zweiten Zeile: Das Komma vor der schließenden Klammer sorgt für einen vierten Parameter, der ebenfalls leer ist und damit nach 0 gewandelt wird. Auf diese Weise werden die leere Eingaben (und die Eingabe von 0) gültig.&lt;br /&gt;
&lt;br /&gt;
==$REGEX()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $REGEX() (&amp;quot;regular expressions&amp;quot;) prüft, ob der String in Parameter 1 den Anforderungen von Parameter 2 entspricht (Ergebnis Y) oder nicht (Ergebnis N).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# String, der geprüft werden soll&lt;br /&gt;
# Regulärer Ausdruck, mit dem der String in Parameter 2 geprüft wird.&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 ~ $REGEX($VAR(med),^[A-Z]{3}$)&lt;br /&gt;
&lt;br /&gt;
==$TEXT_HASLINE()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $TEXT_HASLINE() prüft, ob die als Parameter 2 übergebene Textzeile in einem Text vorkommt. Es wird nur auf komplette Textzeilen geprüft. Wird zum Beispiel verwendet, um eine Liste von Kundennummern zu erstellen, und dann auf einzelne Nummern zu prüfen.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Nummer des Textes&lt;br /&gt;
# Textzeile, deren Vorkommen geprüft wird&lt;br /&gt;
# Ergebnis, wenn die Textzeile vorkommt; default Y&lt;br /&gt;
# Ergebnis, wenn die Textzeile nicht vorkommt; default N&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $TEXT_HASLINE(1,990000018,1,0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==$VIBAN()==&lt;br /&gt;
&lt;br /&gt;
Die Funktion $VIBAN() (&amp;quot;validate IBAN&amp;quot;) prüft eine IBAN anhand der Prüfziffern (3. und 4. Stelle).&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# IBAN, die geprüft werden soll&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #coutl $VIBAN(DE12345)&lt;br /&gt;
&lt;br /&gt;
=Currency-Funktionen=&lt;br /&gt;
&lt;br /&gt;
==$CCALC()==&lt;br /&gt;
&lt;br /&gt;
Führt eine Berechnung mit Festkommawerten durch&lt;br /&gt;
&lt;br /&gt;
'''Operatoren'''&lt;br /&gt;
&lt;br /&gt;
** + - Addition&lt;br /&gt;
** - - Subtraktion&lt;br /&gt;
** * - Multiplikation&lt;br /&gt;
** / - Division&lt;br /&gt;
** % - Division und Multiplikation des Ergebnisses mit 100&lt;br /&gt;
** +4 - Addition und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** -4 - Subtraktion und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** *4 - Multiplikation und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** /4 - Division und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
** %4 - Division, Multiplikation des Ergebnisses mit 100 und Ausgabe mit 4 Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
** B, b, B4, b4 - Bruttobetrag, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** E, e, E4, e4 - Enthaltene MWSt, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** M, m, M4, m4 - MWSt, erster Parameter ist der Netto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
** N, n, N4, n4 - Nettobetrag, erster Parameter ist der Brutto-Betrag, zweiter Parameter ist der MWSt-Satz in %&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Operator&lt;br /&gt;
# und weitere: Operanden&lt;br /&gt;
&lt;br /&gt;
'''Beispiele'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 10&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(+,1,2,3,4)&amp;quot;&lt;br /&gt;
 -- Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #val_set   n=1   z=1038,87&lt;br /&gt;
 #coutl $CCALC(N,$VAL(1),19)  -  $CCALC(E,$VAL(1),19)  -&lt;br /&gt;
&lt;br /&gt;
==$CURR()==&lt;br /&gt;
&lt;br /&gt;
Currency-Werte müssen in Funktionen mit einem Punkt als Dezimaltrennzeichen eingegeben werden, da das Komma die Parameter trennt. Sofern Konstanten verwendet werden, lässt sich das einfach so eingeben, sobald aber die Werte aus anderen Funktionen kommen (zum Beispiel $DATA()), müssen sie dann mit $CURR() in dieses Format umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Vorkommastellen&lt;br /&gt;
# Nachkommastellen&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 -- Ergebnis 43,48&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,$CURR(2,3))&amp;quot;&lt;br /&gt;
 -- zum Vergleich; Ergebnis 16,67&lt;br /&gt;
 #cout   c=&amp;quot;$CCALC(/,100,2,3)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==$CFMT()==&lt;br /&gt;
&lt;br /&gt;
Formatiert Curreny-Werte&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Wert&lt;br /&gt;
# optional: Formatierungsstring, default 0.00&lt;br /&gt;
# optional: wenn hn (&amp;quot;hide null&amp;quot;), dann werden leere Strings als Wert auch als leerer String ausgegeben&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
&lt;br /&gt;
 #val_set   n=1   z=###,###,###,##0.00&lt;br /&gt;
 #val_set   n=2   z=1337,42&lt;br /&gt;
 #cout   c=$CFMT($VAL(2),$VAL(1))&lt;br /&gt;
&lt;br /&gt;
==$ONLYNUM()==&lt;br /&gt;
&lt;br /&gt;
Stellt sicher, dass in einem String nur Zahlen (ggf. auch Kommas oder Punkte) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
'''Parameter'''&lt;br /&gt;
&lt;br /&gt;
# Zahl&lt;br /&gt;
# Art der Operation; default numkomma&lt;br /&gt;
## flnnc (&amp;quot;from last not numeric character&amp;quot;) - Ab dem letzten Zeichen, das keine Ziffer ist&lt;br /&gt;
## num - Nur Ziffern, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numkomma - Nur Ziffern und Kommata, alle anderen Zeichen werden entfernt&lt;br /&gt;
## numpoint - Nur Ziffern und Punkte, alle anderen Zeichen werden entfernt&lt;br /&gt;
## ufnnc (&amp;quot;until first not numeric character&amp;quot;) - vom Anfang bis zum ersten Zeichen, das keine Ziffer ist&lt;br /&gt;
&lt;br /&gt;
'''Beispiel'''&lt;br /&gt;
 -- Ergebnis 123456&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,num)&lt;br /&gt;
 -- Ergebnis 123&lt;br /&gt;
 #coutl   $ONLYNUM(123-456,ufnnc)&lt;br /&gt;
 -- Ergebnis 456 &lt;br /&gt;
 #coutl   $ONLYNUM(123-456,flnnc)&lt;/div&gt;</summary>
		<author><name>Michaelebner</name></author>
		
	</entry>
</feed>