# Statements

Statements sind die Grundbausteine der Ninox Logik. Sie steuern, was ausgeführt wird, mit welchen Datensätzen deine Logik arbeitet und wann sie sich wiederholt.\
Wenn du diese Muster kennst, kannst du einfache Logik in Workflows verwandeln, die leichter zu lesen, zu testen und zu pflegen sind.

{% hint style="info" %}
Wenn du neu im Skripting bist, konzentriere dich zuerst auf drei Grundlagen:

* verwende `if`, um Entscheidungen zu treffen
* verwende `select`, um Datensätze zu finden
* verwende `for ... in ... do ... end`, um diese Datensätze einzeln zu verarbeiten
  {% endhint %}

| Statement                            | Funktion                                                                |
| ------------------------------------ | ----------------------------------------------------------------------- |
| `create`                             | Erstellt einen neuen Datensatz in einer Tabelle                         |
| `delete`                             | Löscht einen Datensatz oder eine Auswahl von Datensätzen                |
| `else if`                            | Fügt einem `if`-Statement weitere Bedingungen hinzu                     |
| `for ... from ... to ... do ... end` | Durchläuft einen Zahlenbereich                                          |
| `for ... in ... do ... end`          | Durchläuft jedes Element in einer Liste oder Auswahl                    |
| `if ... then ... else ... end`       | Gibt je nach Bedingung unterschiedliche Logik zurück oder führt sie aus |
| `order by`                           | Sortiert eine Datensatzauswahl nach einem Feld oder Ausdruck            |
| `select ... where`                   | Fragt Datensätze ab und filtert sie nach einer Bedingung                |
| `switch ... case`                    | Ordnet einen Wert einem von mehreren festen Ergebnissen zu              |
| `while ... do ... end`               | Wiederholt Logik, solange eine Bedingung wahr bleibt                    |

## **`if ... then ... else ... end` verwenden**

Verwende `if ... then ... else ... end`, wenn Ninox zwischen zwei Ergebnissen entscheiden soll.

Die Bedingung nach `if` muss ein Yes/No-Ergebnis zurückgeben:

* `true` bedeutet, dass der `then`-Zweig ausgeführt wird
* `false` bedeutet, dass der `else`-Zweig ausgeführt wird

Das Grundmuster sieht so aus:

```ninox
if condition then
	resultIfTrue
else
	resultIfFalse
end
```

### **Einen Wert oder einen anderen zurückgeben**

Dieses Beispiel prüft den Wert in `Total` und gibt eine Zahlungsmethode zurück:

```ninox
if total >= 30 then
	"Card"
else
	"Cash"
end
```

Wenn `total` `30` oder mehr ist, lautet das Ergebnis `Card`. Wenn `total` unter `30` liegt, lautet das Ergebnis `Cash`.

Dieses Muster funktioniert gut in einem Logikfeld, wenn das Feld abhängig von einer Bedingung ein Ergebnis zurückgeben soll.

### **Vergleichsoperatoren in einer Bedingung verwenden**

Bedingungen verwenden oft Vergleichsoperatoren. Häufige Operatoren sind:

* `=` gleich
* `!=` ungleich
* `>` größer als
* `>=` größer oder gleich
* `<` kleiner als
* `<=` kleiner oder gleich
* `not` ist nicht wahr

Zum Beispiel:

```ninox
if total >= 30 then
	"Card"
else
	"Cash"
end
```

Hier gibt `total >= 30` entweder `true` oder `false` zurück. Ninox nutzt dieses Ergebnis dann, um den nächsten Zweig zu wählen.

### **`else` weglassen, wenn nichts passieren soll**

Du musst nicht jedes Mal einen `else`-Zweig hinzufügen. Verwende dieses Muster, wenn Logik nur ausgeführt werden soll, wenn eine Bedingung erfüllt ist:

```ninox
let paymentMethod := "Cash";
if total >= 30 then
	paymentMethod := "Card"
end;
paymentMethod
```

Diese Logik arbeitet in drei Schritten:

* `paymentMethod` startet mit `Cash`
* wenn `total` `30` oder mehr ist, ändert Ninox den Wert zu `Card`
* die letzte Zeile gibt den endgültigen Wert zurück

Dieses Muster ist nützlich, wenn du zuerst einen Standardwert brauchst und ihn nur in bestimmten Fällen ändern willst.

{% hint style="info" %}
Verwende einen `else`-Zweig, wenn du zwei explizite Ergebnisse brauchst. Lass ihn weg, wenn die Logik nur auf einen Fall reagieren soll.
{% endhint %}

### **Prüfen, ob ein Feld leer ist**

Verwende `null`, um zu prüfen, ob ein Feld keinen Wert hat.\
`null` bedeutet leer. Es bedeutet **nicht** `0`.

```
if total = null then
	"Please enter an amount!"
end
```

Eine weitere Möglichkeit ist:

```ninox
if not total then
	"Please enter an amount!"
end
```

Wenn `total` leer ist, gibt Ninox die Nachricht `Please enter an amount!` zurück.

Um zu prüfen, ob ein Feld einen Wert enthält, verwende den internen Feldnamen direkt in der Bedingung. Die Bedingung gibt `true` zurück, wenn das Feld Inhalt hat, und `false`, wenn es leer ist.

Das ist nützlich, wenn deine Logik von einer Nutzereingabe abhängt und vor einer Berechnung reagieren soll.

### **Häufige Fehler vermeiden**

Diese Punkte kommen in bedingter Logik häufig vor:

* `null` wie `0` behandeln
* den falschen Vergleichsoperator verwenden
* vergessen, dass eine Bedingung `true` oder `false` zurückgeben muss

Vergleiche diese beiden Prüfungen:

```ninox
if total = 0 then
	"No amount entered"
end
```

```ninox
if total = null then
	"No amount entered"
end
```

Die erste prüft auf den numerischen Wert `0`. Die zweite prüft, ob das Feld leer ist. Dieser Unterschied ist wichtig.

### **Wann du bedingte Logik verwendest**

Verwende `if`-Statements, wenn du:

* unterschiedliche Texte oder Werte zurückgeben willst
* eine Variable nur in bestimmten Fällen setzen willst
* Eingaben vor dem Fortfahren prüfen willst
* leere Felder sicher behandeln willst

Bedingte Logik ist einer der wichtigsten Bausteine in Ninox. Du verwendest sie in Logikfeldern, Buttons und Automatisierungen.

### **Mehrere Bedingungen mit `else if` verwenden**

Verwende `else if`, wenn du mehr als zwei mögliche Ergebnisse brauchst. So kann Ninox Bedingungen von oben nach unten prüfen, bis eine passt.

```ninox
if total = null then
	"Please enter an amount!"
else if total >= 30 then
	"Card"
else
	"Cash"
end
```

Dieses Beispiel gibt eines von drei Ergebnissen zurück:

* `Please enter an amount!`, wenn `total` leer ist
* `Card`, wenn `total` `30` oder mehr ist
* `Cash` in allen anderen Fällen

Die Reihenfolge ist hier wichtig. Ninox prüft zuerst die erste Bedingung. Wenn `total` leer ist, überspringt Ninox den Rest der Logik.

{% hint style="info" %}
Setze die spezifischsten oder wichtigsten Prüfungen an den Anfang. So vermeidest du unerwartete Ergebnisse.
{% endhint %}

### **`switch ... case` für viele feste Ergebnisse verwenden**

Verwende `switch ... case`, wenn ein Ausdruck zu mehreren bekannten Ergebnissen führen kann. Das ist oft leichter zu lesen und wird von Ninox schneller ausgeführt als eine lange Kette aus `else if`-Zweigen.

Das Grundmuster sieht so aus:

```ninox
switch expression do
case value1:
	result1
case value2:
	result2
default:
	fallbackResult
end
```

### **Beispiel mit einem Auswahlfeld**

Dieses Beispiel prüft das Auswahlfeld `payment_method` und gibt eine passende Nachricht zurück:

```ninox
switch payment_method do
case 1:
	"Payment method: " + text(payment_method) + "."
case 2:
	"Payment method: " + text(payment_method) + ". Only from €30."
case 3:
	"Payment method: " + text(payment_method) + ". Do not forget your signature."
default:
	"Please select a payment method."
end
```

Wenn das Feld eine der konfigurierten Optionen enthält, gibt Ninox den passenden Text zurück. Wenn keine Option ausgewählt ist, gibt Ninox die Standardnachricht zurück.

In diesem Beispiel:

* `case 1` bezieht sich auf die Option mit dem Index `1`
* `case 2` bezieht sich auf die Option mit dem Index `2`
* `case 3` bezieht sich auf die Option mit dem Index `3`

Das funktioniert gut bei Auswahlfeldern mit einer festen Liste von Optionen.

Alle statischen Auswahl- und Mehrfachauswahlfelder verwenden interne Options-IDs wie `1`, `2` und `3`. Deshalb verwendet das Beispiel `case 1`, `case 2` und `case 3`.

{% hint style="info" %}
Verwende `switch`, wenn ein Wert genau einem bekannten Ergebnis zugeordnet werden soll. Auswahlfelder sind dafür ein typisches Beispiel.
{% endhint %}

### **Wann du `else if` oder `switch` verwendest**

Verwende `else if`, wenn:

* jede Bedingung anders ist
* du Vergleiche wie `>= 30` brauchst
* spätere Bedingungen von früheren Prüfungen abhängen

Verwende `switch`, wenn:

* ein Feld oder Ausdruck gegen feste Werte geprüft wird
* du bei vielen Optionen eine klarere Logik willst
* du mit einem Auswahlfeld oder einer anderen bekannten Ergebnismenge arbeitest

### **Tief verschachtelte Bedingungen vermeiden**

Verschachtelte Bedingungen werden schnell schwer lesbar. Statt viele `if`-Blöcke ineinander zu stapeln, verwende lieber:

* `else if` für geordnete Prüfungen
* `switch` für feste Ergebnisse

So bleibt deine Logik kürzer, leichter zu testen und später einfacher zu aktualisieren.

## **`select` zum Abfragen von Datensätzen verwenden**

Verwende `select`, um Datensätze aus einer Tabelle zu lesen.

Dieses Statement gibt eine Datensatzauswahl zurück. Sie ist der Ausgangspunkt für viele Berichte, Ansichten und Automatisierungen.

Das Grundmuster sieht so aus:

```ninox
select internal_table_name
```

Damit bekommst du alle Datensätze aus der Tabelle zurück.

```ninox
select customers_new
```

Damit bekommst du alle Datensätze aus der Tabelle "Customers (New)" mit dem internen Tabellennamen `customers_new` zurück.

### **Datensätze mit `where` filtern**

Verwende `where`, um das Ergebnis auf Datensätze zu begrenzen, die einer Bedingung entsprechen.

```ninox
select customers where country = "Germany" or country = "Austria" or country = "Switzerland"
```

Damit bekommst du nur Datensätze zurück, bei denen `country` einem dieser Werte entspricht:

* `Germany`
* `Austria`
* `Switzerland`

Dieses Muster ist nützlich, wenn du nur eine Teilmenge anzeigen willst, zum Beispiel eine Region, eine Gruppe von Statuswerten oder einen Datumsbereich.

### **In einer Abfrage auf leere Werte prüfen**

Du kannst innerhalb einer Abfrage auch auf leere Werte prüfen.

```ninox
select customers where email = null
```

Damit bekommst du nur Kundendatensätze zurück, bei denen das Feld "Email" leer ist.

Das hilft dir, wenn du unvollständige Datensätze vor dem Senden von Nachrichten oder vor einem Export finden willst.

### **Eine vorhandene Auswahl filtern**

Du kannst Datensätze auch nach der Auswahl filtern. Das ist nützlich, wenn du zuerst eine größere Menge auswählst und sie dann mit zusätzlichen Bedingungen eingrenzt. So musst du die ursprüngliche Auswahl nicht jedes Mal neu laden.

```ninox
let myCustomers := select customers_new;
myCustomers[country = "Germany"]
```

Das wählt zuerst alle Datensätze aus und filtert dann das Ergebnis. Verwende die Klammern, wenn du bereits eine Auswahl hast und sie weiter eingrenzen willst.

### **Für bessere Performance `select ... where` bevorzugen**

Diese beiden Muster können ähnliche Ergebnisse liefern:

```ninox
select customers_new where country = "Germany"
```

```ninox
let customers := select customers_new;
customers[country = "Germany"]
```

Der erste Ansatz ist meist schneller, weil Ninox von Anfang an nur passende Datensätze auswählt.

Der zweite Ansatz lädt zuerst alle Datensätze und filtert sie erst danach.

{% hint style="info" %}
Bevorzuge `select ... where`, wenn Performance wichtig ist, besonders in großen Tabellen.
{% endhint %}

### **Wann du `select` verwendest**

Verwende `select`, wenn du:

* Datensätze für einen Bericht oder eine Ansicht laden willst, die noch nicht mit dem aktuellen Datensatz verknüpft sind
* Datensätze für die spätere Verwendung in deiner Logik filtern willst
* eine Auswahl an Funktionen wie `count`, `first`, `last` oder `item` übergeben willst

## **`order by` zum Sortieren von Datensätzen verwenden**

Verwende `order by`, um eine Datensatzauswahl nach einem Feld oder Ausdruck zu sortieren. Verwende das Statement nach einer Auswahl, wenn du Datensätze in einer vorhersehbaren Reihenfolge verarbeiten willst.

Das Grundmuster sieht so aus:

```ninox
(select invoices) order by total
```

Damit sortierst du die Datensätze aus `invoices` nach `total` von klein nach groß.

### **Eine gefilterte Auswahl sortieren**

Du kannst `order by` mit `where` oder einem Filter in Klammern kombinieren.

Das nächste Beispiel ist etwas fortgeschrittener. Du kannst es vorerst überspringen, wenn du nur nach einem normalen Feld sortieren willst.

```ninox
(select invoices where date = today()) order by number(substr(invoice_no, 3))
```

Dieses Beispiel macht zwei Dinge:

* es wählt nur Rechnungen mit dem heutigen Datum aus
* es sortiert sie nach dem numerischen Teil von `invoice_no`

Hier ist `3` die Startposition der Zahl innerhalb des Texts.

Für eine Rechnungsnummer wie `NO-12574` gilt:

* `N` steht an Position `0`
* `O` steht an Position `1`
* `-` steht an Position `2`
* `1` steht an Position `3`

Das zeigt, dass der Wert nach `order by` kein Feldname sein muss. Es kann auch ein Ausdruck sein.

### **Textwerte bewusst sortieren**

Textwerte werden nach Zeichenreihenfolge sortiert. Das entspricht nicht immer der alphabetischen Reihenfolge, die Nutzer erwarten. Gemischte Groß- und Kleinschreibung kann zu überraschenden Ergebnissen führen.

Angenommen, das Feld `First name` enthält diese Werte:

* `Aaron`
* `beate`
* `Conrad`
* `dahlia`
* `Eddi`
* `fatima`

Wenn du diese Auswahl direkt sortierst:

```ninox
concat(((select example_for_order_by) order by first_name).first_name)
```

Dann kann dieses Ergebnis zurückkommen:

`Aaron, Conrad, Eddi, beate, dahlia, fatima`

Dieses Ergebnis folgt einer Sortierung, die Groß- und Kleinschreibung berücksichtigt. Namen mit einem Großbuchstaben am Anfang stehen vor Namen mit einem Kleinbuchstaben am Anfang.

Um den Text vor dem Sortieren zu normalisieren, verwende `upper()` oder `lower()`:

```ninox
concat(((select example_for_order_by) order by upper(first_name)).first_name)
```

Das gibt zurück:

`Aaron, beate, Conrad, dahlia, Eddi, fatima`

Die angezeigten Namen behalten ihre ursprüngliche Schreibweise. Nur der Wert für die Sortierung wird normalisiert.

{% hint style="info" %}
Wenn du Textfelder sortierst, normalisiere die Werte mit `upper()` oder `lower()`, wenn du eine Sortierung ohne Berücksichtigung von Groß- und Kleinschreibung willst.
{% endhint %}

### **`sort()` oder `rsort()` verwenden, wenn du nur Werte brauchst**

Verwende `order by`, wenn du sortierte Datensätze brauchst. Verwende `sort()`, wenn du nur eine sortierte Werteliste brauchst.

```ninox
concat(sort((select example_for_order_by).first_name))
```

Damit bekommst du die Namen in aufsteigender alphabetischer Reihenfolge, ohne die Datensätze selbst zu sortieren.

Um die Ergebnisse absteigend zu sortieren, verwende die Funktion `rsort()`.

```ninox
concat(rsort((select invoices).total))
```

### **Wann du `order by` verwendest**

Verwende `order by`, wenn du:

* Datensätze vor der Verwendung von `first`, `last` oder `item` sortieren willst
* die Ausgabe eines Berichts steuern willst
* nach einem berechneten Ausdruck statt nach einem gespeicherten Feld sortieren willst

Wenn du nur eine Liste von Feldwerten brauchst, verwende stattdessen `sort()` oder `rsort()`.

### **Logik mit Schleifen wiederholen**

Schleifen führen denselben Logikblock mehrmals aus.

Verwende sie, wenn du:

* viele Datensätze aktualisieren willst
* jedes Element in einer Liste verarbeiten willst
* eine Berechnung mit numerischen Positionen wiederholen willst
* fortfahren willst, bis sich eine Bedingung ändert

In den meisten Fällen ist `for ... in ... do ... end` der beste Einstieg.

#### **`for ... in ... do ... end` verwenden**

Verwende diese Schleife, um jedes Element in einer Liste oder Auswahl zu durchlaufen.

Das Grundmuster sieht so aus:

```ninox
for item in list do
	statement
end
```

### **Beispiel: ausgewählte Datensätze aktualisieren**

Dieses Beispiel wählt Kunden mit dem Status `2` aus und ändert jeden einzelnen auf den Status `1`:

```ninox
let myCustomers := select customers_new where status = 2;
for cust in myCustomers do
	cust.status := 1
end
```

Diese Logik arbeitet in zwei Schritten:

* die erste Zeile speichert die passenden Datensätze
* die Schleife aktualisiert jeden ausgewählten Datensatz einzeln

Das ist eines der häufigsten Schleifenmuster in Ninox.

{% hint style="info" %}
Verwende `for ... in ... do ... end`, wenn du bereits eine Liste, ein Array oder eine Datensatzauswahl hast.
{% endhint %}

#### **`for ... from ... to ... do ... end` verwenden**

Verwende diese Schleife, wenn du einen Zahlenbereich durchlaufen willst.

Sie beginnt mit dem Wert nach `from` und stoppt vor dem Wert nach `to`.

Das Grundmuster sieht so aus:

```ninox
for item from 0 to 3 do
	statement
end
```

Dabei gilt:

* `0` ist der erste Wert
* `3` ist der Stoppwert und wird nicht mehr verarbeitet
* die Schrittweite beträgt `1`

### **Beispiel: Werte nach Position addieren**

```ninox
let array := [10, 20, 30, 20, 10];
let result := 0;
for i from 0 to 3 do
	result := result + item(array, i)
end;
result
```

Damit addierst du die Werte an den Positionen `0`, `1` und `2`:

* `10`
* `20`
* `30`

Das Ergebnis ist `60`.

### **Die Schrittweite mit `step` ändern**

Verwende `step`, wenn du nicht in Schritten von `1` erhöhen willst.

```ninox
let array := [10, 20, 30, 20, 10];
let result := 0;
for i from 0 to 5 step 2 do
	result := result + item(array, i)
end;
result
```

Damit verwendest du die Positionen `0`, `2` und `4`.

Das Ergebnis ist `50`.

{% hint style="info" %}
`for i in range(0, 10)` ist gleichbedeutend mit `for i from 0 to 10`.
{% endhint %}

#### **`while ... do ... end` verwenden**

Verwende `while`, wenn sich Logik wiederholen soll, solange eine Bedingung wahr bleibt.

Das Grundmuster sieht so aus:

```ninox
while condition do
	statement
end
```

Diese Schleife läuft weiter, bis die Bedingung `false` wird.

### **Beispiel: eine Folge aufbauen**

```ninox
let i := 0;
let result := "";
while i < 10 do
	if result = "" then
		result := text(i)
	else
		result := result + " " + text(i)
	end;
	i := i + 1
end;
result
```

Das gibt genau Folgendes zurück:

`0 1 2 3 4 5 6 7 8 9`

Die Schleife funktioniert, weil sich `i` bei jedem Durchlauf ändert. Sobald `i` den Wert `10` erreicht, ist die Bedingung `false` und die Schleife stoppt.

{% hint style="warning" %}
Achte immer darauf, dass eine `while`-Schleife stoppen kann. Wenn die Bedingung nie `false` wird, läuft die Schleife weiter und kann dein System blockieren.
{% endhint %}

### **Wann du welche Schleife verwendest**

Verwende `for ... in ... do ... end`, wenn:

* du Datensätze durchläufst
* du Array-Elemente durchläufst
* du bereits eine vorbereitete Auswahl hast

Verwende `for ... from ... to ... do ... end`, wenn:

* du numerische Positionen brauchst
* du mit Array-Indizes arbeitest
* du die Schrittweite mit `step` steuern willst

Verwende `while ... do ... end`, wenn:

* die Anzahl der Durchläufe nicht im Voraus feststeht
* die Schleife stoppen soll, wenn sich eine Bedingung ändert

Für die meisten Datensatzaktualisierungen und die Verarbeitung von Listen solltest du `for ... in ... do ... end` bevorzugen.

## **`create` zum Erstellen von Datensätzen verwenden**

Verwende `create`, um einen neuen Datensatz in einer Tabelle zu erstellen.

Das Grundmuster sieht so aus:

```ninox
create table_name
```

### **Einen Datensatz erstellen und seine Felder aktualisieren**

Wenn du den neuen Datensatz mit Daten füllen willst, speichere ihn zuerst in einer Variable.

Verwende dann den Punktoperator, um seine Felder zu aktualisieren.

```ninox
let newCustomer := create customers;
newCustomer.(
	name := "Company ABC";
	status := 1
)
```

Diese Logik macht zwei Dinge:

* sie erstellt einen neuen Datensatz in `customers`
* sie schreibt Werte in Felder des neuen Datensatzes

In diesem Beispiel bekommt der Kunde im neuen Datensatz einen Namen und einen Status.

Dieses Muster ist nützlich, wenn du einen Datensatz erstellen und direkt mehrere Felder füllen willst.

{% hint style="info" %}
Speichere den neuen Datensatz in einer Variable, wenn du nach dem Erstellen mehrere Felder aktualisieren willst.
{% endhint %}

## **`delete` zum Löschen von Datensätzen verwenden**

Verwende `delete`, um einen oder mehrere Datensätze zu löschen.

### **Den aktuellen Datensatz löschen**

Verwende `delete this`, wenn du den aktuellen Datensatz löschen willst.

```ninox
delete this
```

Das ist in einem Button nützlich, wenn das Löschen zusammen mit einer anderen Aktion erfolgen soll.

Du kannst zum Beispiel zuerst eine Nachricht senden oder verknüpfte Datensätze aktualisieren und danach den aktuellen Datensatz löschen.

### **Mehrere Datensätze löschen**

Kombiniere `delete` mit `select`, wenn du mehrere Datensätze auf einmal löschen willst.

```ninox
delete select customers where archived = true
```

Damit löschst du alle Datensätze in `customers`, bei denen `archived` `true` ist.

{% hint style="warning" %}
Sei bei Löschungen mehrerer Datensätze vorsichtig. Teste zuerst das `select`, damit du genau weißt, welche Datensätze gelöscht werden.
{% endhint %}

### **Wann du `create` und `delete` verwendest**

Verwende `create`, wenn du einen neuen Datensatz zusammen mit weiteren Aktionen erstellen willst, zum Beispiel:

* den neuen Datensatz mit dem aktuellen Datensatz verknüpfen
* wichtige Felder sofort füllen
* nach dem Erstellen weitere Automatisierungen ausführen

Verwende `delete`, wenn du:

* den aktuellen Datensatz löschen willst
* Datensätze bereinigen willst, die einer Bedingung entsprechen
* das Löschen mit einem weiteren automatisierten Schritt verbinden willst


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ninox.com/ninox-scripting/de/automate-your-workflows/explore-core-scripting-elements/statements.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
