Berechnungsfelder (kc:calc)¶
Ein Berechnungsfeld ermittelt seinen Wert automatisch aus anderen Feldern — der Anwender kann es nicht von Hand ausfüllen (es wird schreibgeschützt angezeigt). Der Wert aktualisiert sich live, sobald sich eine seiner Quellen ändert, und wird beim Speichern ganz normal in der Datenbank abgelegt.
Es gibt zwei Berechnungsarten:
- Summe einer Tabellenspalte — summiert eine numerische Spalte einer Detail-Tabelle (1:n) über alle Zeilen.
- Rechnung aus Feldern — verknüpft andere Zahlenfelder mit
+,−,×oder÷.
Zusammenklicken reicht — das JSON ist zum Nachschauen da
Berechnungsfelder richtest du vollständig im Formular-Editor ein, ohne eine Zeile zu tippen. Die eingeklappten Kästen „Hinter den Kulissen" auf dieser Seite zeigen, was der Editor dabei in das Formular schreibt. Aufklappen lohnt sich, wenn du verstehen willst, warum etwas so funktioniert — zum Arbeiten brauchst du es nicht.
Im Formular-Editor einrichten¶
Berechnungsfelder gibt es nur für Zahlenfelder (number/integer). Lege
also zuerst ein Zahlenfeld an und öffne seine Eigenschaften — dort erscheint der
Reiter „Berechnung".
- Art der Berechnung wählen:
- Summe einer Tabellenspalte — nur verfügbar, wenn das Formular mindestens eine Detail-Tabelle mit einer Zahlenspalte enthält.
- Rechnung aus Feldern (+ − × ÷) — nur verfügbar, wenn es weitere Zahlenfelder gibt.
- Bei Summe: Detail-Tabelle und die zu summierende Spalte auswählen.
- Bei Rechnung: die Rechenart (Summe/Differenz/Produkt/Quotient) wählen und über „+ Operand hinzufügen" die beteiligten Felder auflisten.
- Optional Nachkommastellen für die Rundung des Ergebnisses angeben.
Das Feld wird daraufhin in der Vorschau und im ausgefüllten Formular schreibgeschützt dargestellt.
Was der Editor dabei hinterlegt¶
Was du im Reiter „Berechnung" zusammenklickst, notiert der Editor am Feld als
Eigenschaft namens kc:calc. Darin steht die Rechnung in ihre Bestandteile
zerlegt — Rechenart, beteiligte Felder — und nicht als frei getippte Formel.
Das ist Absicht: So kann in einem Formular nie fremder Code landen, der beim
Rechnen ausgeführt wird.
Zwei Dinge sind praktisch daran, auch wenn du nie selbst ins Schema schaust: Eine Berechnung lässt sich mit dem Formular mitnehmen (Export/Import), und wenn etwas nicht rechnet, zeigt ein Blick in diese Eigenschaft, welche Felder beteiligt sind.
Hinter den Kulissen: Summe einer Tabellenspalte
"posten_summe": {
"type": "number",
"title": "Summe der Posten",
"kc:decimals": 2,
"kc:numberSuffix": " €",
"kc:calc": { "type": "sum", "table": "posten", "column": "betrag" }
}
table— Feld-ID der Detail-Tabelle (kc:childTable).column— Property-Name der zu summierenden Spalte.
Hinter den Kulissen: Rechnung aus Feldern
"zeilenbetrag": {
"type": "number",
"title": "Zeilenbetrag",
"kc:decimals": 2,
"kc:calc": { "type": "arithmetic", "op": "multiply", "operands": ["menge", "einzelpreis"] }
}
op—add·subtract·multiply·divide. Die Operanden werden von links gefaltet:subtract=a − b − c …,divide=a ÷ b ÷ c ….operands— Liste von Feld-IDs.
Nachkommastellen¶
Die im Reiter „Berechnung" eingetragenen Nachkommastellen landen als
decimals (0–12) in derselben Eigenschaft:
decimals rundet das berechnete Ergebnis. Unabhängig davon steuert
kc:decimals/kc:numberSuffix/kc:numberDecimalSep/kc:numberThousandSep nur
die Anzeige (siehe Datenmodell & Formate).
Leerwert-Regeln¶
Damit halb ausgefüllte Formulare keine irreführenden Zahlen zeigen, gilt:
| Berechnung | leerer Operand | Ergebnis |
|---|---|---|
sum |
leere Zelle zählt als 0 |
Summe der vorhandenen Zeilen (keine Zeilen → 0) |
add / subtract |
leer = 0 |
leer nur, wenn alle Operanden leer sind |
multiply / divide |
ein leerer Operand | Ergebnis bleibt leer (kein 0, keine ∞) |
divide |
Teiler 0 |
Ergebnis bleibt leer |
Verkettung¶
Ein Berechnungsfeld darf ein anderes berechnetes Feld als Operand nutzen — ein Gesamtbetrag darf sich also aus zwei bereits berechneten Zwischensummen zusammensetzen.
Hinter den Kulissen: berechnetes Feld als Operand
Die Auswertung läuft nach jeder Wertänderung erneut und konvergiert über mehrere Durchläufe automatisch zum Endergebnis — die Reihenfolge der Felder im Schema spielt keine Rolle. (Kreisbezüge — A rechnet aus B, B aus A — sind zu vermeiden; sie führen zu keinem stabilen Ergebnis.)
Zeilen-interne Berechnung (Detail-Tabelle)¶
kc:calc funktioniert auch auf einer Spalte einer Detail-Tabelle — dann
wird der Wert pro Zeile aus den Nachbarspalten derselben Zeile berechnet.
Typischer Fall: Betrag = Menge × Einzelpreis je Position.
Hinter den Kulissen: Berechnung innerhalb einer Tabellenzeile
"posten": {
"type": "array",
"kc:childTable": {
"type": "object",
"properties": {
"p_menge": { "type": "number", "title": "Menge" },
"p_einzelpreis": { "type": "number", "title": "Einzelpreis" },
"betrag": {
"type": "number", "title": "Betrag",
"kc:calc": { "type": "arithmetic", "op": "multiply", "operands": ["p_menge", "p_einzelpreis"] }
}
}
}
}
Die Berechnung steht bei der Spalte, die sie füllt — und die Operanden sind Spalten derselben Tabelle. Genau das macht sie zeilen-intern.
Im Formular-Editor öffnet man dazu die Spalte (Detail-Spalten-Editor) und nutzt den
Reiter „Berechnung" wie bei einem Top-Level-Feld; als Operanden stehen die
numerischen Nachbarspalten zur Auswahl. Innerhalb einer Zeile gibt es nur
die Rechenarten (+ − × ÷) — die Summe einer Tabellenspalte ist eine
zeilenübergreifende Aggregation und gehört auf ein Top-Level-Feld.
Beide Ebenen greifen sauber ineinander: eine berechnete Spalte (betrag) kann
per Top-Level-sum über alle Zeilen aufsummiert werden.
Beispiel-Formular¶
Das Beispielformular „Kalkulation (Berechnungsfelder)" (Katalog Showcase,
installierbar unter System-Administration → Formular-Bausteine → Beispiele) demonstriert alle Fälle: Produkt (Menge × Einzelpreis),
zeilen-interner Positionsbetrag in der Tabelle, Spaltensumme (Posten → Betrag)
und die verkettete Gesamtsumme.
Grenzen¶
- Operanden sind Feld-IDs — Konstanten oder freie Formeln sind nicht vorgesehen (bewusst, siehe oben).
- Kreisbezüge (A rechnet aus B, B aus A) sind zu vermeiden.
Geltungsbereich: berechnet wird im Web-Formular¶
kc:calc wird im Browser ausgewertet — vom Web-Renderer, live bei jeder
Änderung einer Quelle. Der so ermittelte Wert wird beim Speichern über das
Web-Formular ganz normal mit persistiert. Für die Anzeige und den PDF-Export
gilt dann dieser gespeicherte Wert (das PDF rechnet nicht neu, sondern zeigt den
persistierten Stand).
Bewusst nicht serverseitig nachgerechnet wird bei Datensätzen, die ohne das Web-Formular entstehen oder geändert werden:
- über die REST-Services /
forms.createim Scripting angelegte Sätze, - von einem Workflow-Schritt erzeugte/berechnete Sätze,
- direkte DB-Schreibzugriffe.
Solche Sätze tragen im Berechnungsfeld den Wert, der beim Anlegen übergeben wurde
(oder den Default) — nicht automatisch die Formel-Auswertung. Wer Berechnungs
felder außerhalb des Web-Formulars korrekt füllen will, rechnet den Wert im Skript
selbst aus (die Rechenarten sind simpel: Summe einer Spalte bzw. + − × ÷ über
Feld-IDs) oder öffnet den Satz einmal im Web-Formular und speichert ihn.
Warum nur im Web (bewusste Entscheidung): Ein zweiter, serverseitiger Rechner müsste die Frontend-Semantik (Rundung, Komma-/Punkt- Behandlung, leere Operanden) exakt spiegeln — sonst driften Web- und Server- Wert auseinander und ein Speichern könnte einen zuvor angezeigten Wert unbemerkt verändern. Statt dieses Drift-Risikos ist
kc:calcals Web- berechnet + persistiert definiert; für Nicht-Web-Pfade ist die Berechnung Sache des Skripts.