Add concept paper on argument hints and a formula assistant

Two options, not decided yet; kept with the project so the reasoning is at hand when one is picked.
This commit is contained in:
wkh
2026-10-24 00:38:01 +02:00
parent 59b99e5715
commit 1db1562a38
+216
View File
@@ -0,0 +1,216 @@
# Formelhilfe: Argumenthinweis und Formelassistent
Stand: 23.10.2026 · Status: **Optionen, nicht beschlossen**
Dieses Papier hält zwei Ausbaustufen fest, die beim Eingeben von Formeln
helfen sollen. Option A ist klein und für sich nützlich, Option B baut auf
ihr auf.
## Ausgangslage
- Beim Tippen eines Funktionsnamens zeigt eine Liste passende Funktionen mit
ihrer Signatur, z. B. `IF(Bedingung; Dann; Sonst?)`
(`composables/useFormulaAutocomplete.ts`, `components/FormulaSuggest.vue`).
- Sobald die öffnende Klammer steht, verschwindet die Liste. Danach zeigt
nichts mehr an, welches Argument gerade eingegeben wird oder was es
bedeutet.
- Die Signaturen der 36 eingebauten Funktionen liegen als Freitext in
`BUILTIN_SIGNATURES` (`engine/functions.ts`). Deutsche Kurzbeschreibungen
stehen in `FUNCTION_DESCRIPTIONS` (`data/codeReference.ts`), werden bisher
aber nur in der Befehlsreferenz des Makro- und Funktionseditors angezeigt.
- Eigene Funktionen des Dokuments haben benannte Parameter
(`FunctionDef.params`).
- Es gibt keine Funktion, die eine Formel auswertet, ohne sie in eine Zelle
zu schreiben.
## Option A: Argumenthinweis
### Verhalten
Steht der Cursor innerhalb eines Funktionsaufrufs, erscheint unter dem
Editor eine Zeile wie in Excel:
> IF(Bedingung; **Dann**; Sonst?)
> Liefert *Dann*, wenn die Bedingung wahr ist, sonst *Sonst*.
- Das Argument, in dem der Cursor steht, ist fett. Gezählt wird über die
`;` auf der Ebene dieser Funktion.
- Bei verschachtelten Aufrufen gilt die innerste Funktion um den Cursor:
In `=IF(SUM(A1;|` wird `SUM` angezeigt.
- Bei Argumenten, die sich wiederholen dürfen (`Zahl1; Zahl2; …`), bleibt
ab dem zweiten Argument der letzte Platzhalter hervorgehoben.
- Gilt im Zelleditor und in der Formelleiste, für eingebaute und für eigene
Funktionen.
- Die Vervollständigungsliste hat Vorrang. Ist sie offen, wird der Hinweis
ausgeblendet.
- Innerhalb einer Zeichenkette (`"…"`) und außerhalb jedes Aufrufs wird
nichts angezeigt. Escape schließt den Hinweis, bis der Cursor in einen
anderen Aufruf wechselt.
### Umsetzung
- Engine: `functionCallAtCaret(formula, caret)` liefert `{ name, argIndex }`
oder `null`. Dazu wird der Text bis zum Cursor zerlegt und ein Stapel der
offenen Klammern mit Funktionsnamen und Anzahl der `;` geführt. Der Aufbau
entspricht den vorhandenen Hilfen `currentIdentifierAtCaret` und
`cycleReferenceLocks` in `engine/refs.ts`.
- Signatur zerlegen: Die Parameter werden aus dem Hinweistext gelesen
(`?` = optional, `…` = Wiederholung). Bei eigenen Funktionen kommen sie
aus `FunctionDef.params`.
- Oberfläche: Eine kleine Komponente `ArgumentHint.vue`, die Zelleditor
(`TableGrid.vue`) und Formelleiste (`FormulaBar.vue`) gleich einbinden,
wie heute schon `FormulaSuggest.vue`.
- Tests für `functionCallAtCaret` (Verschachtelung, Zeichenketten, leere
Argumente, `…`) und für das Zerlegen der Signaturen.
### Aufwand
Klein, ungefähr ein Tag einschließlich Tests.
## Option B: Formelassistent
### Ablauf
1. Ein Klick auf „fx“ in der Formelleiste öffnet den Assistenten. Als
Tastenkürzel bietet sich Umschalt+F3 an (wie „Funktion einfügen“ in
Excel). Ohne laufende Bearbeitung beginnt die Formel in der aktiven
Zelle.
2. **Funktion wählen:** Suchfeld und Kategorien (Mathematik, Statistik,
Text, Logik, Datum & Zeit, Nachschlagen, eigene Funktionen). Zu jeder
Funktion werden Signatur und Beschreibung angezeigt.
3. **Argumente eingeben:** Für jeden Parameter gibt es ein Feld mit Namen,
kurzer Erklärung und der Kennzeichnung „optional“. Wiederholbare
Argumente bekommen ein neues Feld, sobald das letzte gefüllt ist. Neben
jedem Feld steht sein aktueller Wert, im Fehlerfall die Meldung.
4. **Bezüge übernehmen:** Ist ein Feld aktiv, übernimmt ein Klick oder Ziehen
in der Tabelle den Bezug, ebenso die Pfeiltasten. Dafür meldet sich das
Feld als Formeleditor an (`registerFormulaEditor`). Der Zeigemodus, die
farbigen Bezüge und die Zieh-Griffe funktionieren so ohne Änderung.
5. **Vorschau:** Unten stehen die fertige Formel und ihr Ergebnis, laufend
aktualisiert.
6. **Übernehmen** fügt den Aufruf an der Cursorstelle ein, **Abbrechen**
lässt die Formel unverändert.
Steht der Cursor beim Öffnen in einem bestehenden Aufruf, öffnet der
Assistent genau diese Funktion mit ihren Argumenten in den Feldern.
„Übernehmen“ ersetzt dann nur diesen Aufruf. Dafür wird der Helfer aus
Option A um die Textgrenzen des Aufrufs und seiner Argumente erweitert.
### Voraussetzungen
- **Parameter genauer beschreiben:** Statt des Hinweistextes eine
strukturierte Beschreibung je Funktion, z. B.
`{ name, category, description, params: [{ name, description, optional, repeat }] }`.
`BUILTIN_SIGNATURES` und die Befehlsreferenz werden daraus erzeugt, damit
es nur eine Quelle gibt. Heute ist der Hinweistext teils ungenau:
`XLOOKUP(Suchwert; Suchbereich; Rückgabebereich; …)` verschweigt die
optionalen Argumente `WennNichtGefunden` und `Vergleichsmodus`.
- **Formel ohne Zelle auswerten:** Neue Store-Funktion, die einen
Formeltext im Zusammenhang einer Zelle (Tabelle, Spalte, Zeile) auswertet,
ohne das Dokument zu ändern, kein `markDirty()`, kein Eintrag im Rückgängig-
Verlauf. Wird für die Vorschau und die Werte der einzelnen Felder
gebraucht.
### Umsetzung
- `FormulaWizard.vue` als Dialog auf Basis von `BaseModal.vue`, der aber die
Tabelle nicht verdeckt (seitlich oder verschiebbar), damit Bezüge gewählt
werden können.
- Store: Auswertung ohne Zelle (siehe oben), sonst nur vorhandene
Schnittstellen (`registerFormulaEditor`, `pointClick`/`pointDrag`,
`formulaRefs`).
- Die Argumentfelder brauchen die gleiche Verarbeitung wie die Formelleiste
(Zeigemodus mit Pfeiltasten, Vervollständigung, F4). Diese wird dafür aus
`FormulaBar.vue` herausgelöst, damit sie nicht ein drittes Mal entsteht.
- Tests: strukturierte Beschreibung vollständig für alle Funktionen in
`FUNCTIONS`, Zusammensetzen und Zerlegen eines Aufrufs, Auswertung ohne
Zelle verändert das Dokument nicht.
### Aufwand
Mittel bis groß, ungefähr drei bis fünf Tage. Davon entfällt etwa ein Tag
auf die Beschreibungen der Parameter aller Funktionen.
## Reihenfolge
A zuerst. Der Helfer `functionCallAtCaret` und das Zerlegen der Signaturen
werden in B wiederverwendet. Die strukturierte Beschreibung aus B kann
nachträglich auch den Hinweis in A verbessern (Erklärung je Argument statt
nur je Funktion).
## Festlegung: deutsche und englische Funktionsnamen
Funktionen können deutsch oder englisch eingegeben werden (`=SUMME(A1:A5)`
oder `=SUM(A1:A5)`). **Gespeichert wird immer der englische Name.** Der
deutsche Name ist nur ein Alias für die Eingabe.
- **Umwandlung beim Übernehmen:** Beim Bestätigen der Eingabe (Enter, Tab,
Verlassen des Feldes) werden deutsche Funktionsnamen durch die englischen
ersetzt, an derselben Stelle wie das Schließen fehlender Klammern
(`completeFormula`). Ersetzt wird nur ein Name direkt vor `(`, nie in
Zeichenketten, Tabellen- oder Blattnamen oder benannten Bereichen.
Groß- und Kleinschreibung spielt keine Rolle.
- **Dateiformat und Engine bleiben unverändert:** `.num`/`.json`, Export,
Zusammenarbeit und Auswertung sehen nur englische Namen. Ältere Dokumente
brauchen keine Umstellung.
- **Zuordnung:** Eine Tabelle deutscher Aliasse je Funktion, angelehnt an
die deutschen Excel-Namen, z. B. `SUMME`→`SUM`, `MITTELWERT`→`AVERAGE`,
`ANZAHL`→`COUNT`, `ANZAHL2`→`COUNT2`, `VERKETTEN`→`CONCATENATE`,
`TEXTKETTE`→`CONCAT`, `WENN`→`IF`, `UND`→`AND`, `ODER`→`OR`,
`NICHT`→`NOT`, `DATUM`→`DATE`, `ZEIT`→`TIME`, `HEUTE`→`TODAY`,
`JETZT`→`NOW`, `JAHR`→`YEAR`, `MONAT`→`MONTH`, `TAG`→`DAY`,
`STUNDE`→`HOUR`, `SEKUNDE`→`SECOND`, `WOCHENTAG`→`WEEKDAY`,
`ISOKALENDERWOCHE`→`ISOWEEKNUM`, `KALENDERWOCHE`→`WEEKNUM`,
`EDATUM`→`EDATE`, `MONATSENDE`→`EOMONTH`, `TAGE`→`DAYS`,
`NETTOARBEITSTAGE`→`NETWORKDAYS`, `ARBEITSTAG`→`WORKDAY`,
`DATWERT`→`DATEVALUE`, `ZEITWERT`→`TIMEVALUE`, `XVERWEIS`→`XLOOKUP`.
Gleichnamige (`MIN`, `MAX`, `MINUTE`, `DATEDIF`) brauchen keinen Alias.
Ein Test stellt sicher, dass jedes Alias auf eine vorhandene Funktion
zeigt und kein Alias einem englischen Namen gleicht.
- **Vervollständigung, Hinweis und Assistent:** Die Vorschlagsliste findet
eine Funktion über beide Namen (Tippen von `SUM` oder `SUMME` schlägt
dieselbe Funktion vor) und zeigt den deutschen Namen mit dem englischen
daneben. Argumenthinweis (Option A) und Assistent (Option B) erkennen
beide Schreibweisen.
- **Eigene Funktionen:** Sie haben nur den Namen, den der Benutzer ihnen
gibt. Es gibt für sie keinen Alias, und ihr Name wird weder bei der
Eingabe noch bei der Anzeige umgewandelt.
- **Keine Überschneidung mit eingebauten Namen:** Der Name einer eigenen
Funktion darf weder einem englischen Funktionsnamen noch einem deutschen
Alias gleichen, ohne Rücksicht auf Groß- und Kleinschreibung (`Sum`,
`SUMME`, `wenn` sind alle abgewiesen). Sonst wäre unklar, welche Funktion
gemeint ist. Die Prüfung gehört dorthin, wo heute schon englische Namen
abgewiesen werden (`hasFunction` beim Anlegen und Umbenennen in
`store/document.ts`), und wird um die deutschen Aliasse erweitert.
Bestehende Dokumente können schon eine eigene Funktion enthalten, die wie
ein neuer deutscher Alias heißt (z. B. `WENN`). Für diesen Fall braucht es
beim Öffnen einen Hinweis mit der Aufforderung, sie umzubenennen. Bis
dahin gewinnt die eigene Funktion, damit sich vorhandene Ergebnisse nicht
ändern.
- **Anzeige deutsch:** Überall, wo der Benutzer eine Formel sieht oder
bearbeitet (Zelleditor, Formelleiste), stehen die deutschen Namen. Die
Umwandlung englisch→deutsch geschieht nur für die Anzeige, beim Öffnen
des Editors und beim Füllen der Formelleiste. Beim Übernehmen wird wieder
englisch gespeichert. Wird eine Formel nur geöffnet und unverändert
bestätigt, ergibt die Rückumwandlung denselben Text, das Dokument gilt
dann nicht als geändert. Export und Kopieren in andere Programme liefern
den gespeicherten, englischen Text.
- **Nicht in Makros und Funktionen mit Schleife:** Deren Code kennt nur die
englischen Namen. Dort wird nichts umgewandelt, und die Befehlsreferenz in
diesen Editoren zeigt weiterhin englische Namen. Ein deutscher Name wird
dort wie jeder andere unbekannte Funktionsname behandelt.
## Offene Fragen
- **Einzeilige eigene Funktionen:** Gilt die deutsche Eingabe auch für den
Rumpf einer eigenen Funktion ohne Schleife (`kind: 'expression'`)? Der
Rumpf ist eine einzelne Formel, wird aber im Funktionseditor bearbeitet,
nicht in einer Zelle.
- **Kategorien:** Die Einteilung oben ist ein Vorschlag. Heute gehören alle
Funktionen zur Kategorie „Formelfunktionen“.
- **Nur lesen:** Bei Dokumenten ohne Schreibrecht sollen Hinweis und
Assistent zum Nachschlagen verfügbar sein, „Übernehmen“ aber nicht.
- **Zusammenhang mit einer Hilfe in der App:** Eine Hilfe mit Tastenkürzeln
und Funktionsliste (bisher nur angedacht) könnte dieselbe strukturierte
Beschreibung nutzen.