Dies ist die alte 4D Dokumentations-Website. Die neue und aktualisierte Dokumentation finden Sie unter developer.4d.com

Home

 
4D v20 R7
QUERY BY ATTRIBUTE

QUERY BY ATTRIBUTE 


 

QUERY BY ATTRIBUTE ( {Tabellenname}{;}{KonjOp ;} ObjektFeld ; AttributPfad ; SuchOp ; Wert {; *} ) 
Parameter Typ   Beschreibung
Tabellenname  Tabelle in Tabelle zur Rückgabe einer Auswahl Datensätze
Ohne Angabe Haupttabelle
KonjOp  Operator in Verbindungsparameter bei mehrfacher Suche
ObjektFeld  Feld in Objektfeld zum Suchen von Attributen
AttributPfad  String in Name oder Pfad des Attributs
SuchOp  String, Operator in Suchoperator (Vergleichsoperator)
Wert  Text, Zahl, Datum, Zeit in Zu vergleichender Wert
Operator in Weiterer Suchbegriff folgt

QUERY BY ATTRIBUTE sucht nach Datensätzen, die zum Suchstring passen, definiert über die Parameter ObjektFeld, AttributPfad, SuchOp und Wert, und gibt eine Datensatzauswahl für Tabellenname zurück.

QUERY BY ATTRIBUTE ändert die aktuelle Auswahl von Tabellenname für den aktuellen Prozess und macht den ersten Datensatz der neuen Auswahl zum aktuellen Datensatz. Wird der Parameter Tabellenname weggelassen, gilt der Befehl für die Standardtabelle. Ist keine Standardtabelle vorhanden, tritt ein Fehler auf.

Der optionale Parameter KonjOp verbindet QUERY BY ATTRIBUTE Aufrufe in mehrfachen Suchen. Die logischen Operatoren sind dieselben wie im Befehl QUERY:

KonjunktionSymbol für QUERY BY ATTRIBUTE
UND&
ODER|
Außer#

Der Parameter KonjOp wird nicht bei einer einfachen Suche bzw. für den ersten Aufruf von QUERY BY ATTRIBUTE in einer mehrfachen Suche verwendet. Lassen Sie ihn in einer mehrfachen Suche weg, wird standardmäßig der Operator UND (&) verwendet.

In ObjektFeld übergeben Sie das Objektfeld, nach dessen Attribut(en) Sie suchen wollen. Gehört es zu einer Eine-Tabelle, definiert in Tabellenname mit einer automatischen oder manuellen Verknüpfung, kann ObjektFeld zu einer anderen Tabelle gehören.
QUERY BY ATTRIBUTE unterstützt eigene Attribute in 4D Write Pro, wenn Dokumente in Objektfeldern gespeichert sind. Weitere Informationen dazu finden Sie im Abschnitt 4D Write Pro Dokumente in 4D Objektfeldern speichern.

In AttributPfad übergeben Sie den Pfad des Attributs, dessen Werte Sie für jeden Datensatz vergleichen wollen, z.B. "Kinder.weiblich.Alter". Übergeben Sie eine einzelne Bezeichnung, z.B. "Ort", geben Sie das entsprechende Attribut an, das auf der ersten Ebene des Objektfelds gefunden wird.
Ist ein Attribut "x" ein Array, sucht QUERY BY ATTRIBUTE nach Datensätzen mit einem Attribut "x", in dem mindestens ein Element zum Suchkriterium passt. Zur Suche in Array Attributen muss im Befehl QUERY BY ATTRIBUTE angegeben werden, dass Attribut "x" ein Array ist, d.h. an den Namen in AttributPfad wird "[]" angefügt (siehe Beispiel 3).
Sie können einen Buchstaben in Klammern hinzufügen, z.B. [b] um Argumente zu verlinken (siehe nachfolgenden Abschnitt Suchkriterien mit Array Attributen verlinken).

Hinweise:

  • Beachten Sie, dass Attributnamen Groß- und Kleinschreibung berücksichtigen. Im gleichen Datensatz wird also zwischen dem Attributnamen "MeinAtt" und "meinAtt" unterschieden.
  • Mehrere Attributnamen werden zusammengezogen. Beispiel: " mein erstes Attribut .mein zweites Attribut " wird interpretiert als "mein erstes Attribut.mein zweites Attribut".
  • Sie können keine Attribute verwenden, die im Namen Sonderzeichen wie "." oder "[ ]" enthalten, da diese im Suchstring als Tokens interpretiert werden. Weitere Informationen dazu finden Sie im Abschnitt Identifier für Objekteigenschaft

Der Parameter SuchOp ist der Vergleichsoperator zwischen ObjektFeld und Wert. Sie können folgende Symbole übergeben:

VergleichSymbol für QUERY BY ATTRIBUTE
Ist gleich =
Ist ungleich * #
Kleiner als <
Größer als >
Kleiner als oder gleich <=
Größer als oder gleich >=

(*) Bei Verwendung mit Array Elementen bedeutet der Operator # "enthält kein Element".

Hinweis: Sie können den Vergleichsoperator auch in Textform angeben. Weitere Informationen dazu finden Sie unter dem Befehl QUERY.

Der Inhalt von Wert wird mit AttributPfad verglichen. Wert kann jeder Ausdruck sein, der denselben Datentyp wie AttributPfad bewertet. Er wird einmal zu Beginn der Suche bewertet und nicht für jeden Datensatz. Für eine Suche nach einem String innerhalb eines anderen (Suche mit "enthält") setzen Sie in Wert den Joker (@), um den gesuchten String zu isolieren, also z.B. "@Schmid@". In diesem Fall profitiert die Suche jedoch nur teilweise von dem Index (Kompaktheit der Datenspeicherung).

Die Struktur einer Suche nach Attribut lautet wie folgt:

 QUERY BY ATTRIBUTE([Tabellenname];[Tabellenname]ObjektFeld;"Attribut1.Attribut2";=;Wert)

Beachten Sie, dass immer davon ausgegangen wird, dass das Feld ein nicht-leeres Objekt mit festgelegten Attributen enthält. Nachfolgendes Beispiel gibt alle Datensätze zurück, in denen [Tabellenname]ObjektFeld ein Objekt mit einem Attribut Attribut1 enthält, das wiederum ein Objekt mit einem Attribut Attribut2 ist, dessen Wert ungleich Wert ist:

 QUERY BY ATTRIBUTE([Tabellenname];[Tabellenname]ObjektFeld;"Attribut1.Attribut2";#;Wert)

Deshalb gibt diese Suche nicht Objekte zurück, die weder Attribut1 noch Attribut2 enthalten.

Suchen nach Attribut mit dem Operator "#" können unterschiedliche Ergebnisse haben. Es kann vorkommen, dass ein Attribut in einem Datensatz nicht vorhanden ist. Sehen Sie hierzu folgende Anweisung:

 QUERY BY ATTRIBUTE([People];[People]Animals;"dog.name";#;"Rex")

Diese Suche gibt Datensätze mit den Personen zurück, die einen Hund haben, dessen Name nicht Rex ist. Sie gibt jedoch keine Datensätze für Personen zurück , die keinen Hund oder einen Hund ohne Namen haben, z,B. Datensätze, deren Eigenschaft dog.name den Wert null hat.
Dahinter steckt folgendes Konzept: Die Suchmaschine kann keine nicht vergleichbaren Werte vergleichen, das sind fehlende oder nicht vorhandende Daten. Deshalb werden Datensätze, die nicht mit dem Suchkriterium vergleichbar sind, aus der Suche ausgeschlossen.

Folgendes Beispiel ist generischer: 

 

 QUERY BY ATTRIBUTE([Table];[Table]ObjectField;"attribute1.attribute2";#;value)

Diese Suche gibt Datensätze zurück, für die [Table]ObjectField ein Objekt mit einem Attribut Attribute1 enthält, das selbst ein Objekt mit einem Attribut attribute2 ist, dessen Wert ungleich value ist. Es gibt keine Datensätze zurück, wo

  • das Objektfeld nicht attribute1 enthält
  • das Objektfeld nicht attribute1.attribute2 enthält
  • das Objektfeld attribute1.attribute2=null enthält

Dieses Prinzip gilt auch bei Array Attributen. Diese Suche gibt z.B. Datensätze der Personen zurück, die eine oder mehrere Adressen haben, aber keine davon in Paris:

 

 QUERY BY ATTRIBUTE([People];[People]OB_Field;"locations[].city";#;"paris")

Hinweis: Wollen Sie gezielt Datensätze mit undefiniertem Attribut erhalten, können Sie ein leeres Objekt verwenden (siehe unten Beispiel 2). Beachten Sie jedoch, dass die Suche nach NULL Werten in Array Elementen nicht unterstützt wird.

Für mehrfache Suchen nach Attributen gelten folgende Regeln:

  • Das erste Suchkriterium darf keinen Verknüpfungsoperator enthalten.
  • Jedes nachfolgende Kriterium kann mit einem Verknüpfungsoperator beginnen. Lassen Sie ihn weg, wird standardmäßig der Operator UND (&) verwendet.
  • Die einzelnen Suchaufrufe müssen den Parameter * verwenden. Der letzte Aufruf benötigt keinen *.
  • QUERY BY ATTRIBUTE kann mit QUERY Befehlen gemischt werden.
  • Um die Suche auszuführen, lassen Sie im letzten Aufruf von QUERY BY ATTRIBUTE den Parameter * weg. Als Alternative können Sie auch den Befehl QUERY nur mit der Tabelle ausführen, d.h. ohne die anderen Parameter (der Sucheditor erscheint nicht; an seiner Stelle wird die gerade definierte mehrfache Suche ausgeführt).

Hinweis: Jede Tabelle besitzt ihre eigenen aktuellen Suchläufe. Sie können also mehrere Suchläufe gleichzeitig anlegen, d.h. eine pro Tabelle. Für die eindeutige Zuordnung müssen Sie den Parameter Tabellenname angeben oder die Standardtabelle setzen.

Egal, auf welche Weise eine Suche definiert wurde, gilt folgendes:

  • Dauert die Ausführung der aktuellen Suchoperation etwas länger, zeigt 4D automatisch eine Meldung mit einem Ablaufbalken. Sie lässt sich über die Befehle MESSAGES ON und MESSAGES OFF ein- und ausschalten. Erscheint ein Ablaufbalken, kann der Benutzer bei Bedarf auf die Schaltfläche Stopp klicken, um die Suche zu unterbrechen. Ist die Suche abgeschlossen, wird OK auf 1 gesetzt; wird sie unterbrochen, wird OK auf 0 (Null) gesetzt.
  • Sind indizierte Objektfelder spezifiziert, wird die Suche, immer wenn möglich, optimiert (nach indizierten Feldern wird zuerst gesucht) und reduziert so den Zeitaufwand.

Datumsangaben werden in Objekten gemäß den Einstellungen der Datenbank gespeichert; standardmäßig wird die Zeitzone berücksichtigt (siehe Selector JSON use local time unter dem Befehl SET DATABASE PARAMETER).

!1973-05-22! -> "1973-05-21T23:00:00.000Z"

Diese Einstellung wird auch beim Suchen berücksichtigt. Sie müssen sich nicht darum kümmern, wenn Sie Ihre Anwendung immer am gleichen Ort verwenden und die Einstellungen auf allen Rechnern, die auf die Daten zugreifen, gleich sind. Folgende Suche gibt dann z.B. Datensätze mit dem Attribut Geburtsdatum ist gleich !1973-05-22! (gesichert als "1973-05-21T23:00:00.00Z") korrekt zurück. Dieses Beispiel gilt für Deutschland GMT Winterzeit - 1 h: 22.Mai 1973 0:00 ist somit 21.Mai 1973 23:00:

 QUERY BY ATTRIBUTE([Persons];[Persons]OB_Info;"Geburtsdatum";=;!1973-05-22!)

Wollen Sie nicht die GMT Einstellungen verwenden, schreiben Sie folgende Anweisung:

 SET DATABASE PARAMETER(JSON use local time;0)

Beachten Sie, dass die Reichweite dieser Einstellung nur der Prozess ist. Führen Sie diese Anweisung aus, wird 1. Oktober 1965 auch als "1965-10-01T00:00:00.000Z" gespeichert. Sie müssen denselben Parameter jedoch vor dem Starten Ihrer Suchen setzen:

 SET DATABASE PARAMETER(JSON use local time;0)
 QUERY BY ATTRIBUTE([Persons];[Persons]OB_Info;"Geburtsdatum";=;!1976-11-27!)

Mit diesem Befehl können Sie die virtuelle Eigenschaft "length" verwenden. Sie ist automatisch für alle Attribute vom Typ Array verfügbar und gibt die Größe des Array zurück, z.B. die Anzahl der darin enthaltenen Elemente. Sie lässt sich beim Ausführen des Befehls QUERY BY ATTRIBUTE verwenden (siehe Beispiel 4).

(Neu in 4D v16 R2) Beim Suchen in Array Attributen mit mehreren Suchkriterien, verbunden durch den Operator UND, möchten Sie sicherstellen, dass nur Datensätze mit Elementen, auf die alle Kriterien zutreffen, zurückgegeben werden. Dazu müssen Sie die Suchkriterien mit Array Elementen verlinken, damit nur die Elemente mit verlinkten Kriterien gefunden werden.

Nehmen wir als Beispiel folgende beiden Datensätze:

Datensatz 1:
[People]name: "martin"
[People]OB_Field:
    "locations" : [ {
                "kind":"home",[People]
                "city":"paris"
            } ]

Datensatz 2:
[People]name: "smith"
[People]OB_Field:
    "locations" : [ {
                "kind":"home",
                "city":"lyon"
            } , {
                "kind":"office",
                "city":"paris"
            } ]

Sie möchten Personen finden mit der Adressenart "home" in der Stadt "paris". Schreiben Sie:

 QUERY BY ATTRIBUTE([People];[People]OB_Field;"locations[].city";=;"paris";*)
 QUERY BY ATTRIBUTE([People];[People]OB_Field;"locations[].kind";=;"home")

... gibt die Suche "martin" und "smith" zurück, da "smith" ein Element "locations" hat mit "kind" ist gleich "home" und ein Element "locations" mit "city" ist gleich "paris", selbst wenn die Elemente unterschiedlich sind.

Wollen Sie nur Datensätze erhalten mit den passenden Kriterien im gleichen Element, müssen Sie die Kriterien verlinken. Gehen Sie folgendermaßen vor:

  • Sie setzen einen Buchstaben zwischen die [] im ersten Pfad, um den gleichen Buchstaben in allen verbundenen Kriterien zu verlinken und zu wiederholen. Zum Beispiel: locations[a].city und locations[a].kind. Sie können jeden beliebigen Klein- oder Großbuchstaben des lateinischen Alphabeths verwenden.
  • Um ein weiteres verbundenes Kriterium in derselben Suche hinzuzufügen, verwenden Sie einen anderen Buchstaben (siehe Beispiele unten). Sie können in einer Suche bis zu 26 Kombinationen verwenden. 

Wieder mit den o.a. Datensätzen schreiben Sie nun:

 QUERY BY ATTRIBUTE([People];[People]OB_Field;"locations[a].city";=;"paris";*)
 QUERY BY ATTRIBUTE([People];[People]OB_Field;"locations[a].kind";=;"home")

... gibt die Suche nur "martin" zurück, da sie ein Element "locations" hat mit "kind" ist gleich "home" und "city" ist gleich "paris". Die Suche gibt nicht "smith" zurück, da die Werte "home" und "paris" nicht im gleichen Array Element sind. Das Beispiel 3 veranschaulicht dieses Feature.

Hinweis: Eine verbundene Syntax in einer einzelnen Suchzeile führt zum gleichen Ergebnis wie eine Standardsuche, außer beim Verwenden des Operators "#": Da dies zu ungültigen Ergebnissen führen kann, wird diese spezifische Syntax nicht unterstützt.

In diesem Beispiel ist das Attribut "Alter" entweder ein String oder eine Ganzzahl. Wir wollen Personen im Alter 20 bis 29 finden. Die beiden ersten Zeilen suchen das Attribut als Ganzzahl (>=20 und < 30), die letzte Zeile sucht das Feld als String (startet mit "2", ist aber ungleich "2")

 QUERY BY ATTRIBUTE([Persons];[Persons]OB_Info;"Alter";>=;20;*)
 QUERY BY ATTRIBUTE([Persons];&;[Persons]OB_Info;"Alter";<;30;*)
 QUERY BY ATTRIBUTE([Persons];|;[Persons]OB_Info;"Alter";=;"2@";*)
 QUERY BY ATTRIBUTE([Persons];&;[Persons]OB_Info;"Alter";#;"2") // zuletzt kein * setzen, um die Ausführung zu starten

Mit dem Befehl QUERY BY ATTRIBUTE können Sie auch nach Datensätzen suchen, die bestimmte Attribute haben bzw. nicht haben. Dazu müssen Sie ein leeres Objekt verwenden:

  //Finde Datensätze, für die im Objektfeld email definiert ist
 C_OBJECT($undefined)
 QUERY BY ATTRIBUTE([Persons];[Persons]Info;"email";#;$undefined)

  //Finde Datensätze, für die im Objektfeld PLZ NICHT definiert ist
 C_OBJECT($undefined)
 QUERY BY ATTRIBUTE([Persons];[Persons]Info;"PLZ";=;$undefined)

Hinweis: Diese spezifische Syntax wird nicht in Attributen vom Typ Array unterstützt. Die Suche nach NULL Werten in Array Elementen liefert ein ungültiges Ergebnis.

Nach einem Feld mit Array Attributen suchen. Mit den beiden folgenden Datensätzen:

Datensatz 1:
[People]name: "martin"
[People]OB_Field:
    "locations" : [ {
                "kind":"office",
                "city":"paris"
            } ]

Datensatz 2:
[People]name: "smith"
[People]OB_Field:
    "locations" : [ {
                "kind":"home",
                "city":"lyon"
            } , {
                "kind":"office",
                "city":"paris"
            } ]

... findet QUERY BY ATTRIBUTE Personen mit einer Adresse in "paris". Dazu schreiben Sie folgende Anweisung:

  //Das Array Attribut mit der Syntax "[]"
 QUERY BY ATTRIBUTE([People];[People]OB_Field;"locations[].city";=;"paris")
  //wählt "martin" und "smith"

Hinweis: Haben Sie im selben Array Attribut mehrere Kriterien definiert, wird das passende Kriterium nicht zwingend auf dasselbe Array Element angewendet. Im folgenden Beispiel gibt die Suche "smith" zurück, weil es ein Element "locations" mit "kind" ist gleich "home" hat und ein Element "locations" mit "city" ist gleich "paris", selbst wenn es nicht dasselbe Element ist:

 QUERY BY ATTRIBUTE([People];[People]OB_Field;"locations[].kind";=;"home";*)
 QUERY BY ATTRIBUTE([People];&;[People]OB_Field;"locations[].city";=;"paris")
  //wählt "smith"

Dieses Beispiel zeigt die Verwendung der virtuellen Eigenschaft "length". Ihre Anwendung hat ein Objektfeld [Customer]full_Data  mit folgenden Daten:

Sie wollen die Datensätze aller Kunden mit zwei oder mehr Kindern erhalten. Dafür schreiben Sie folgenden Code:

 QUERY BY ATTRIBUTE([Customer];[Customer]full_Data;"Children.length";>=;2)

Hier sehen Sie die verschiedenen möglichen Kombinationen für verlinkte Argumente von Arrays. Wir gehen von folgenden Datensätzen aus:

Datensatz1:
[Person]Name: "Sam"
[Person]ObjectField:
    "Children": [ {
        "Name": "Harry",
        "Age": "15",
        "Toy": [ {
            "Name": "Car",
            "Color": "Blue"
         }, {
            "Name": "Teddy Bear",
            "Color": "Brown"
        } ]
      }, {
        "Name": "Betty",
        "Age": "9",
        "Toy": [ {
            "Name": "Car",
            "Color": "Green"
       }, {
            "Name": "Puzzle",
            "Color": "Blue"
        } ]
      } ]

Datensatz2:
[Person]Name: "Louis"
[Person]ObjectField:
    "Children": [ {
        "Name": "Harry",
        "Age": "15",
        "Toy": [ {
            "Name": "Water gun",
            "Color": "Blue"
        } ]
      }, {
        "Name": "Betty",
        "Age": "3",
        "Toy": [ {
            "Name": "Car",
            "Color": "Blue"
        }, {
            "Name": "Puzzle",
            "Color": "Green"
        } ]
      } ]

Datensatz3:
[Person]Name: "Victor"
[Person]ObjectField:   
    "Children": [ {
        "Name": "Harry",
        "Age": "9",
        "Toy": [ {
            "Name": "Doll",
            "Color": "Pink"
        }, {
            "Name": "Puzzle",
            "Color": "Blue"
        } ]
      }, {
        "Name": "Betty",
        "Age": "15",
        "Toy": [ {
            "Name": "Water gun",
            "Color": "Blue"
        } ]
      } ]

Die Suche nach Personen mit einem Kind, genannt "Betty" und 15 Jahre alt:

 QUERY BY ATTRIBUTE([Person];[Person]ObjectField;"Children[a].Name";=;"Betty";*)
 QUERY BY ATTRIBUTE([Person];&;[Person]ObjectField;"Children[a].Age";=;"15")
  //ergibt "Victor"
 
 QUERY BY ATTRIBUTE([Person];[Person]ObjectField;"Children[].Name";=;"Betty";*)
 QUERY BY ATTRIBUTE([Person];&;[Person]ObjectField;"Children[].Age";=;"15")
  //ergibt "Sam", "Louis" und "Victor"

Die Suche nach Personen mit einem Kind, genannt "Betty", 15 Jahre alt und mit einem Kind, genannt "Harry", 9 Jahre alt:

 QUERY BY ATTRIBUTE([Person];[Person]ObjectField;"Children[a].Name";=;"Betty";*)
 QUERY BY ATTRIBUTE([Person];&;[Person]ObjectField;"Children[a].Age";=;"15";*)
 QUERY BY ATTRIBUTE([Person];[Person]ObjectField;"Children[b].Name";=;"Harry";*)
 QUERY BY ATTRIBUTE([Person];&;[Person]ObjectField;"Children[b].Age";=;"9")
  //ergibt "Victor"
 
 QUERY BY ATTRIBUTE([Person];[Person]ObjectField;"Children[].Name";=;"Betty";*)
 QUERY BY ATTRIBUTE([Person];&;[Person]ObjectField;"Children[].Age";=;"15";*)
 QUERY BY ATTRIBUTE([Person];[Person]ObjectField;"Children[].Name";=;"Harry";*)
 QUERY BY ATTRIBUTE([Person];&;[Person]ObjectField;"Children[].Age";=;"9")
  //ergibt "Sam" und "Victor"

Die Suche nach Personen mit einem 15 jährigen Kind, genannt "Harry" mit dem Spielzeug "blue car" toy (Suche in einem Array von Arrays):

 QUERY BY ATTRIBUTE([Person];[Person]ObjectField;"Children[a].Name";=;"Harry";*)
 QUERY BY ATTRIBUTE([Person];&;[Person]ObjectField;"Children[a].Age";=;"15";*)
 QUERY BY ATTRIBUTE([Person];&;[Person]ObjectField;"Children[a].Toy[b].Name";=;"Car";*)
 QUERY BY ATTRIBUTE([Person];&;[Person]ObjectField;"Children[a].Toy[b].Color";=;"Blue")
  //ergibt "Sam"
 
 QUERY BY ATTRIBUTE([Person];[Person]ObjectField;"Children[].Name";=;"Harry";*)
 QUERY BY ATTRIBUTE([Person];&;[Person]ObjectField;"Children[].Age";=;"15";*)
 QUERY BY ATTRIBUTE([Person];&;[Person]ObjectField;"Children[].Toy[].Name";=;"Car";*)
 QUERY BY ATTRIBUTE([Person];&;[Person]ObjectField;"Children[].Toy[].Color";=;"Blue")
  //ergibt "Sam" und "Louis"

Wurde die Suche korrekt ausgeführt, wird die Systemvariable OK auf 1 gesetzt.

Die Variable OK wird auf 0 (Null) gesetzt, wenn:

  • Der Benutzer im Suchdialog auf die Schaltfläche Abbrechen klickt,
  • Die Suche im Modus 'Suchen und Sperren' (siehe Befehl SET QUERY AND LOCK) mindestens einen gesperrten Datensatz gefunden hat. In diesem Fall wird auch die Systemmenge LockedSet aktualisiert.



Siehe auch 

Download HDI database
QUERY SELECTION BY ATTRIBUTE
Struktur der 4D Programmiersprache Objekte

 
EIGENSCHAFTEN 

Produkt: 4D
Thema: Suchen
Nummer: 1331

Dieser Befehl ändert die Systemvariable OKDieser Befehl ändert den aktuellen DatensatzDieser Befehl ändert die aktuelle AuswahlDieser Befehl kann in preemptive Prozessen laufen

 
SEITENINHALT 
 
GESCHICHTE 

Erstellt: 4D v15
Geändert: 4D v16 R2

 
ARTIKELVERWENDUNG

4D Programmiersprache ( 4D v20 R7)