---
title: Anweisungen
---

**Anweisungen** verknüpfen Komponenten über Sektions- und Kapitelgrenzen hinweg: Eine Sektion *speichert* Werte unter einem Schlüssel, andere Sektionen *holen* sie wieder ab und füllen damit ihre eigenen Komponenten automatisch aus.

Damit lassen sich Stammdaten - Kundennummer, Anlagenname, Standort, Prüfer - einmal erfassen und in allen weiteren Sektionen automatisch bereitstellen, ohne dass der Anwender sie erneut eintippt.

---

## Inhalt

1. [Die Datenwolke](#die-datenwolke)
2. [Wo Anweisungen konfiguriert werden](#wo-anweisungen-konfiguriert-werden)
3. [setValue: Werte speichern](#setvalue-werte-speichern)
4. [getValue: Werte abholen](#getvalue-werte-abholen)
5. [Durchgerechnetes Beispiel](#durchgerechnetes-beispiel)
6. [Wann Anweisungen ausgeführt werden](#wann-anweisungen-ausgefuhrt-werden)
7. [Was der Anwender im Dokument sieht](#was-der-anwender-im-dokument-sieht)
8. [Gut zu wissen](#gut-zu-wissen)

---

## Die Datenwolke

Alle Anweisungen arbeiten auf einem gemeinsamen Speicher, der **Datenwolke**. Sie gilt für das gesamte geöffnete Dokument:

- Eine **`setValue`**-Anweisung speichert den Wert einer Komponente unter einem **Schlüssel** in der Datenwolke.
- Eine **`getValue`**-Anweisung holt ihn dort wieder ab.

Man kann sich die Datenwolke wie ein schwarzes Brett vorstellen, an dem jede Sektion ihre Werte aushängt und andere Sektionen sie abholen.

Der Schlüssel ist typischerweise ein fachlicher Wert - eine Anlagen-, Kunden- oder Prüfnummer. Dadurch finden sich Sektionen, die fachlich zusammengehören, ohne dass sie fest miteinander verdrahtet werden müssten.

```text
Sektion "Kopfdaten"                                      Sektion "Pruefung1"

  anlagennummer  = 4711  ─┐                          ┌─► anlagenName  (wird gefüllt)
  anlagenName            ─┼─ setValue ─► [ 4711 ] ───┤
  standort               ─┘                 ▲        └─► standort     (wird gefüllt)
                                            │
                                    Schlüssel = Wert
                                    von "anlagennummer"
```

Was in der Datenwolke liegt, ist immer **dreistufig** aufgebaut:

```json
{
  "4711": {
    "Kopfdaten": {
      "anlagenName": "Kesselhaus Nord",
      "standort": "Werk 2 / Halle 3"
    }
  }
}
```

| Ebene | Inhalt | Woher |
|---|---|---|
| 1 | **Schlüssel** (`4711`) | aus dem `Target` der `setValue`-Anweisung |
| 2 | **Sektionsname** (`Kopfdaten`) | Name der Sektion, die gespeichert hat |
| 3 | **Komponentenname → Wert** | aus dem `Source` der `setValue`-Anweisung |

Mehrere Sektionen können unter demselben Schlüssel speichern - dann stehen auf Ebene 2 mehrere Einträge nebeneinander. Alles, was unter einem Schlüssel liegt, wird im Folgenden als **Bündel** bezeichnet.

:::note[Die Datenwolke wird bei jedem Durchlauf neu aufgebaut]
Sie ist kein dauerhaft gespeicherter Zwischenspeicher. Beim Öffnen eines Dokuments und bei jedem Sektionswechsel wird die Datenwolke geleert und aus den aktuellen Werten neu befüllt. Gespeichert werden nur die Werte der Komponenten selbst.
:::

---

## Wo Anweisungen konfiguriert werden

Anweisungen gehören zu einer **Sektion** und werden im Template-Editor gepflegt:

**Template bearbeiten → Schritt 2 „Aufbau" → Sektion bearbeiten → Schaltfläche „Komponenten Anweisungen"**

Es öffnet sich das Fenster **Anweisungen** mit einer Liste aller Anweisungen der Sektion:

| Spalte | Bedeutung |
|---|---|
| **Type** | `setValue` (speichern) oder `getValue` (abholen) |
| **Source** | Quelle - je nach Typ ein Komponentenname oder ein Platzhalter |
| **Target** | Ziel - je nach Typ ein Schlüssel oder ein Komponentenname |
| **Params** | nur bei `getValue`: Auswahlparameter, über das Info-Symbol einblendbar |
| **Aktion** | Bearbeiten, Duplizieren, Löschen |

Über **Anweisung hinzufügen** wird eine neue Zeile angelegt und sofort zum Bearbeiten geöffnet. Das Bearbeitungsformular enthält:

| Formularfeld | Beschreibung |
|---|---|
| **Type** | Pflichtangabe. Auswahl zwischen `getValue` und `setValue`. |
| **Source** | Bedeutung siehe unten - bei `getValue` zwingend erforderlich. |
| **Target** | **Pflichtangabe.** Ohne Ziel lässt sich die Anweisung nicht übernehmen. |
| **Parameter anzeigen** | Blendet die Parameter ein (nur für `getValue` relevant). |
| **Name** | Name des Wertes, der aus dem Bündel geholt werden soll. |
| **Array** | Legt fest, wie das Bündel ausgewertet wird (siehe [getValue](#getvalue-werte-abholen)). |
| **Index** | Position in der Liste der speichernden Sektionen, ab `0`. |
| **Filter (JSON)** | Optionale Einschränkung im Format `{"key": "value"}`. Fehlerhaftes JSON wird mit *Ungültiges JSON Format erkannt!* abgewiesen. |

Die **Reihenfolge** der Anweisungen ist fachlich relevant: Innerhalb einer Sektion werden sie von oben nach unten abgearbeitet. Sie lässt sich per Ziehgriff ändern, solange keine Anweisung gerade bearbeitet wird.

Mit **Übernehmen** wird die Liste in die Sektion geschrieben; anschließend das Template wie gewohnt speichern.

:::note[Anweisungen wandern ins Dokument]
Beim Erzeugen eines Dokuments werden die Anweisungen aus dem Template übernommen und im Dokument gespeichert. Bestehende Dokumente arbeiten also weiter mit den Anweisungen, mit denen sie angelegt wurden; Änderungen am Template wirken sich auf neu erzeugte Dokumente aus.
:::

---

## setValue: Werte speichern

Eine `setValue`-Anweisung legt **einen** Wert in der Datenwolke ab.

- **Source** = *was* gespeichert wird
- **Target** = *unter welchem Schlüssel* es liegt

### Source

| Eintrag | Bedeutung |
|---|---|
| `komponentenname` | Der Wert dieser Komponente **in derselben Sektion**. Der Normalfall. |
| `$chapterName` | Technischer Name des Kapitels |
| `$chapterTitle` | Angezeigter Titel des Kapitels |
| `$chapterType` | Kapiteltypen des Kapitels (alle, als Liste) |
| `$sectionName` | Technischer Name der Sektion |
| `$sectionTitle` | Angezeigter Titel der Sektion |
| `$sectionType` | Typ der Sektion |

Der Eintrag aus **Source** wird gleichzeitig zum Namen des Wertes auf Ebene 3 der Datenwolke - bei Platzhaltern **einschließlich** des `$`. Ein mit `$sectionName` gespeicherter Wert heißt in der Datenwolke also `"$sectionName"`.

### Target

| Eintrag | Bedeutung |
|---|---|
| fester Text (ohne `$`) | Wird wörtlich als Schlüssel verwendet, z. B. `kundenstamm`. Alle Sektionen mit diesem Ziel speichern in dasselbe Bündel. |
| `$komponentenname` | Der **Wert** dieser Komponente in derselben Sektion wird zum Schlüssel - z. B. `$anlagennummer` → Schlüssel `4711`. |
| `$sektion.komponentenname` | Der Wert einer Komponente aus einer **anderen Sektion desselben Kapitels**. |
| `$chapterName`, `$chapterTitle`, `$sectionName`, `$sectionTitle`, `$sectionType` | Die jeweilige Struktur-Angabe wird zum Schlüssel. |
| `$chapterType` | Nur der **erste** Kapiteltyp wird zum Schlüssel. |

:::warning[`$chapterType` verhält sich in Source und Target unterschiedlich]
Als **Source** wird die vollständige Liste der Kapiteltypen gespeichert, als **Target** nur der erste Eintrag daraus.
:::

### Beispiel

Drei Anweisungen in der Sektion `Kopfdaten`:

```json
[
  { "type": "setValue", "source": "anlagenName",  "target": "$anlagennummer" },
  { "type": "setValue", "source": "standort",     "target": "$anlagennummer" },
  { "type": "setValue", "source": "$sectionName", "target": "$anlagennummer" }
]
```

Ergibt in der Datenwolke (bei `anlagennummer` = `4711`):

```json
{
  "4711": {
    "Kopfdaten": {
      "anlagenName": "Kesselhaus Nord",
      "standort": "Werk 2 / Halle 3",
      "$sectionName": "Kopfdaten"
    }
  }
}
```

Die dritte Anweisung speichert bewusst eine **Kennung**, mit der sich das Bündel später gezielt filtern lässt - siehe [Filter](#filter).

---

## getValue: Werte abholen

Eine `getValue`-Anweisung holt einen Wert aus der Datenwolke und schreibt ihn in eine Komponente.

| Angabe | Bedeutung |
|---|---|
| **Target** | Name der Komponente, die gefüllt werden soll. Sie muss **in derselben Sektion** liegen. |
| **Source** | Beginnt immer mit `$`. Der **Wert** der angegebenen Quelle ist der Schlüssel, unter dem in der Datenwolke nachgeschlagen wird. |
| **Params** | Bestimmt, welcher Wert aus dem Bündel genommen wird. |

### Source [#source_1]

| Eintrag | Bedeutung |
|---|---|
| `$komponentenname` | Wert einer Komponente in **derselben** Sektion |
| `$sektion.komponentenname` | Wert einer Komponente in einer **anderen Sektion desselben Kapitels** |

Steht in `anlagennummer` der Wert `4711`, so schlägt `$anlagennummer` das Bündel `"4711"` nach.

### Params

Vor der Auswertung werden leere Werte und leere Sektionen aus dem Bündel entfernt. Danach entscheidet der Schalter **Array**:

**Array = an (Normalfall)**

Das Bündel wird als **Liste der speichernden Sektionen** behandelt:

1. optional über **Filter** eingeschränkt,
2. daraus der Eintrag an Position **Index** genommen (`0` = erster Eintrag),
3. und aus diesem Eintrag der Wert mit dem Namen **Name** gelesen.

**Name** ist hier der Komponentenname, wie er in der `setValue`-Anweisung als *Source* stand.

**Array = aus (Sonderfall)**

Der Wert **Name** wird direkt auf der obersten Ebene des Bündels gesucht. Diese Ebene ist nach **Sektionsnamen** geschlüsselt - als Ergebnis kommt daher das komplette Wertepaket einer Sektion zurück, kein einzelner Wert. Für gewöhnliche Werteübernahmen ist diese Variante nicht geeignet.

### Filter

Der Filter schränkt die Liste der Sektionen ein, bevor **Index** greift. Er wird als JSON-Objekt angegeben; **alle** enthaltenen Bedingungen müssen zutreffen:

```json
{"$sectionName": "Kopfdaten"}
```

Ist der Wert einer Bedingung eine Liste, genügt es, wenn der gespeicherte Wert **einer** der Einträge ist:

```json
{"$sectionType": ["Kopf", "Deckblatt"]}
```

Gefiltert wird immer über Werte, die auch tatsächlich gespeichert wurden. Damit ein Filter greifen kann, muss die speichernde Sektion die passende Kennung also per `setValue` mit in die Datenwolke legen.

---

## Durchgerechnetes Beispiel

**Ziel:** Anlagenname und Standort werden einmal in den Kopfdaten erfasst und erscheinen in jeder Prüfsektion automatisch.

### Aufbau

Kapitel `Anlage` mit den Sektionen `Kopfdaten` und `Pruefung1`:

| Sektion | Komponenten |
|---|---|
| `Kopfdaten` | `anlagennummer`, `anlagenName`, `standort` |
| `Pruefung1` | `anlagenName`, `standort`, `messwert` |

### Anweisungen in der Sektion `Kopfdaten`

```json
[
  { "type": "setValue", "source": "anlagenName",  "target": "$anlagennummer" },
  { "type": "setValue", "source": "standort",     "target": "$anlagennummer" },
  { "type": "setValue", "source": "$sectionName", "target": "$anlagennummer" }
]
```

### Anweisungen in der Sektion `Pruefung1`

```json
[
  {
    "type": "getValue",
    "source": "$Kopfdaten.anlagennummer",
    "target": "anlagenName",
    "params": {
      "name": "anlagenName",
      "array": true,
      "index": 0,
      "filter": { "$sectionName": "Kopfdaten" }
    }
  },
  {
    "type": "getValue",
    "source": "$Kopfdaten.anlagennummer",
    "target": "standort",
    "params": {
      "name": "standort",
      "array": true,
      "index": 0,
      "filter": { "$sectionName": "Kopfdaten" }
    }
  }
]
```

### Was dabei passiert

Der Anwender trägt in den Kopfdaten `4711`, `Kesselhaus Nord` und `Werk 2 / Halle 3` ein. In der Datenwolke steht:

```json
{
  "4711": {
    "Kopfdaten": {
      "anlagenName": "Kesselhaus Nord",
      "standort": "Werk 2 / Halle 3",
      "$sectionName": "Kopfdaten"
    }
  }
}
```

Beim Wechsel in `Pruefung1` läuft die erste `getValue`-Anweisung:

1. **Source** `$Kopfdaten.anlagennummer` → Wert `4711` → Schlüssel des Bündels
2. Bündel `"4711"` holen und leere Einträge entfernen
3. Als Liste der Sektionen betrachten: `[ Kopfdaten ]`
4. **Filter** `{"$sectionName": "Kopfdaten"}` → der Eintrag bleibt erhalten
5. **Index** `0` → das Wertepaket der Sektion `Kopfdaten`
6. **Name** `anlagenName` → `"Kesselhaus Nord"`
7. Der Wert wird in die Komponente `anlagenName` der Sektion `Pruefung1` geschrieben

Für weitere Prüfsektionen werden dieselben beiden Anweisungen einfach kopiert.

---

## Wann Anweisungen ausgeführt werden [#wann-anweisungen-ausgefuhrt-werden]

Anweisungen laufen automatisch, während ein Dokument bearbeitet wird:

1. Beim Öffnen des Dokuments und bei jedem **Sektionswechsel** wird die Datenwolke geleert.
2. Alle `setValue`-Anweisungen **aller** Sektionen des Dokuments werden ausgeführt - die Datenwolke ist damit vollständig.
3. Die `getValue`-Anweisungen der **aktuellen** Sektion werden ausgeführt und füllen deren Komponenten.
4. Anschließend laufen die `setValue`-Anweisungen erneut. Dadurch können soeben abgeholte Werte direkt weitergespeichert werden - Ketten aus `getValue` → `setValue` funktionieren also innerhalb desselben Durchlaufs.

:::warning[In schreibgeschützten Dokumenten laufen keine Anweisungen]
Abgeschlossene oder für den Anwender schreibgeschützte Dokumente führen keine Anweisungen aus. Sie zeigen ausschließlich die gespeicherten Werte - genau so, wie sie zuletzt erfasst wurden.
:::

### Aufräumen bei geänderten Quellen [#aufraumen-bei-geanderten-quellen]

Ändert sich der Wert einer Quelle oder wird eine Sektion bzw. ein Kapitel gelöscht, prüft flexiDok zusätzlich alle Sektionen darauf, ob automatisch gefüllte Komponenten noch zu ihrer Quelle passen. Dabei gilt:

- Eine automatisch gefüllte Komponente wird **geleert**, wenn ihre Quelle nun einen anderen Wert liefert oder gar nicht mehr auffindbar ist.
- Eine **leere** Komponente wird beim Aufräumen nie automatisch befüllt - das geschieht erst, wenn der Anwender die Sektion betritt.
- Betrifft das Leeren eine als Pflicht gekennzeichnete Komponente, wird die Sektion als unvollständig markiert.
- Kaskaden werden mit aufgelöst: Leert das Aufräumen eine Komponente, die ihrerseits Quelle für eine weitere Komponente ist, wird auch diese geprüft.

Sind Komponenten geleert worden, erscheint der Hinweis **Betroffene Sektionen** mit einer Liste der betroffenen Sektionen. Dieser Hinweis meldet jede automatische Bereinigung - auch dann, wenn sie fachlich völlig korrekt ist.

---

## Was der Anwender im Dokument sieht

Jede Komponente, die Ziel einer `getValue`-Anweisung der gerade geöffneten Sektion ist, wird im Dokument mit einem **@-Symbol** gekennzeichnet. Der Tooltip dazu lautet *Feld wird automatisch ausgefüllt*.

So ist auf einen Blick erkennbar, welche Angaben aus einer anderen Sektion stammen und nicht von Hand gepflegt werden müssen.

---

## Gut zu wissen

### Bei `getValue` muss die Quelle mit `$` beginnen [#bei-getvalue-muss-die-quelle-mit-beginnen]

`Source` ohne führendes `$` wird bei `getValue` nicht als Verweis erkannt - die Zielkomponente bleibt dann leer. Richtig ist `$anlagennummer` bzw. `$Kopfdaten.anlagennummer`.

### Ziel und Quelle haben feste Reichweiten

- Das **Ziel** einer `getValue`-Anweisung muss immer in **derselben Sektion** liegen wie die Anweisung.
- Verweise der Form `$sektion.komponente` reichen genau eine Ebene weit: in eine andere Sektion **desselben Kapitels**. Kapitelübergreifende Verweise dieser Art gibt es nicht.
- Kapitelübergreifend arbeiten lässt sich trotzdem - über den **Schlüssel**: Die Datenwolke gilt für das ganze Dokument, deshalb erreicht ein unter `4711` gespeicherter Wert jede Sektion, die unter `4711` nachschlägt.

### Gleiche Schlüssel treffen sich [#gleiche-schlussel-treffen-sich]

Weil die Datenwolke für das ganze Dokument gilt, landen identische Schlüssel aus verschiedenen Kapiteln im **selben** Bündel. Das ist der eigentliche Nutzen des Verfahrens - aber auch eine Fehlerquelle: Ein fester Schlüssel wie `stammdaten` sammelt die Werte **aller** Sektionen ein, die ihn verwenden. Fachliche Nummern als Schlüssel sind deshalb meist die bessere Wahl.

### Lieber Filter als feste Indizes

Sektionen, die nichts (mehr) speichern, fallen aus dem Bündel heraus - die Positionen der übrigen Einträge verschieben sich dadurch. Ein fest eingetragener **Index** greift dann auf die falsche Sektion zu. Robuster ist es, in der speichernden Sektion eine Kennung (etwa `$sectionName`) mitzuschicken und beim Abholen darüber zu **filtern**; **Index** steht dann in der Regel auf `0`.

### Mehrfachauswahlen verhalten sich je nach Auswahlmenge unterschiedlich

Werte aus Mehrfachauswahlen werden als Liste gespeichert. Enthält die Liste genau **einen** Eintrag, wird dieser einzeln gespeichert; ist sie **leer**, wird nichts gespeichert. Eine Zielkomponente bekommt also je nach Auswahl unterschiedliche Formen - bei der Konfiguration einplanen.

### Leere Quellen liefern nichts

Ist die Quellkomponente leer, existiert kein Schlüssel und es wird nichts abgeholt; die Zielkomponente bleibt leer. Automatische Übernahmen setzen also voraus, dass der Anwender den Schlüsselwert zuerst erfasst - es lohnt sich, die entsprechende Komponente im Template möglichst weit vorne und als Pflicht einzuplanen.

### Fehlkonfigurationen fallen nicht auf

Eine falsch konfigurierte Anweisung erzeugt keine Fehlermeldung - die Zielkomponente bleibt einfach leer. Wenn eine Übernahme nicht funktioniert, sollte in dieser Reihenfolge geprüft werden:

1. Ist das **Target** der `getValue`-Anweisung eine Komponente **derselben** Sektion? Stimmt die Schreibweise des technischen Komponentennamens?
2. Beginnt **Source** mit `$` und existiert die Quellkomponente (bzw. die Sektion) im selben Kapitel?
3. Ist die Quelle **gefüllt**? Ohne Wert gibt es keinen Schlüssel.
4. Stimmen der Ziel-Schlüssel der `setValue`-Anweisung und die Quelle der `getValue`-Anweisung wirklich überein?
5. Passt **Name** in den Parametern zum **Source** der speichernden `setValue`-Anweisung?
6. Ist **Array** aktiviert und der **Index** korrekt - oder greift ein zu enger **Filter**?

### Parameter gelten nur für `getValue` [#parameter-gelten-nur-fur-getvalue]

Bei `setValue`-Anweisungen können Parameter zwar eingetragen werden, sie werden aber weder ausgewertet noch in der Übersicht angezeigt.
