feat: content import system - Markdown parser, importer, 7 decks + 3 tutorials + 5 cheatsheets
Dieser Commit ist enthalten in:
Ursprung
1c59b667f2
Commit
6a504254b0
17 geänderte Dateien mit 2658 neuen und 0 gelöschten Zeilen
163
edu/content/flashcards/deck-commands.md
Normale Datei
163
edu/content/flashcards/deck-commands.md
Normale Datei
|
|
@ -0,0 +1,163 @@
|
|||
# Flashcard Deck: Omnis Commands
|
||||
|
||||
**Thema**: Die wichtigsten Omnis-Befehle
|
||||
**Schwierigkeit**: Anfaenger -> Fortgeschritten
|
||||
**Karten**: 25
|
||||
|
||||
---
|
||||
|
||||
## Karte 1 | Basis
|
||||
**Q:** Was macht der Befehl `Calculate`?
|
||||
**A:** Berechnet einen Ausdruck und weist das Ergebnis einer Variablen zu. `Calculate lX as 5 + 3` -> lX = 8. Aequivalent zu `let x = 5 + 3` in JS.
|
||||
|
||||
---
|
||||
|
||||
## Karte 2 | Basis
|
||||
**Q:** Was macht der Befehl `Do`?
|
||||
**A:** Fuehrt eine Methode oder einen Notation-Ausdruck aus. `Do iObj.$method() Returns lResult`. Wie ein Funktionsaufruf.
|
||||
|
||||
---
|
||||
|
||||
## Karte 3 | Basis
|
||||
**Q:** Was macht `Quit method`?
|
||||
**A:** Beendet die aktuelle Methode und gibt optional einen Wert zurueck. `Quit method lResult` = `return lResult` in JS.
|
||||
|
||||
---
|
||||
|
||||
## Karte 4 | Basis
|
||||
**Q:** Was macht `OK message`?
|
||||
**A:** Zeigt ein Dialogfeld mit einer Nachricht. `OK message {Hallo [lName]!}` - wie `alert()` in JS. Variablen in `[]` werden ersetzt.
|
||||
|
||||
---
|
||||
|
||||
## Karte 5 | Basis
|
||||
**Q:** Was ist der Unterschied zwischen `[lVar]` und `@[lVar]` in SQL?
|
||||
**A:** `[lVar]` = direkte Text-Substitution (SQL-Injection-Gefahr!). `@[lVar]` = Bind-Variable (sicher, parametrisiert). **Immer `@[lVar]` in SQL verwenden!**
|
||||
|
||||
---
|
||||
|
||||
## Karte 6 | Basis
|
||||
**Q:** Was macht `If / Else / End If`?
|
||||
**A:** Bedingte Ausfuehrung - identisch zu anderen Sprachen. `If lAge >= 18 ... Else ... End If`. WICHTIG: `End If` ist Pflicht!
|
||||
|
||||
---
|
||||
|
||||
## Karte 7 | Basis
|
||||
**Q:** Was macht `For ... End For`?
|
||||
**A:** Zaehlschleife: `For lI from 1 to 10 step 1 ... End For`. Oder Listen-Iteration: `For each line in list from 1 to lList.$linecount step 1 ... End For`.
|
||||
|
||||
---
|
||||
|
||||
## Karte 8 | Basis
|
||||
**Q:** Was macht `While ... End While`?
|
||||
**A:** Bedingungsschleife: `While lCounter < 100 ... End While`. Wie `while` in jeder anderen Sprache.
|
||||
|
||||
---
|
||||
|
||||
## Karte 9 | Mittel
|
||||
**Q:** Was macht `Switch / Case / Default / End Switch`?
|
||||
**A:** Fallunterscheidung: `Switch lStatus / Case 'A' ... Case 'B' ... Default ... End Switch`. Wie `switch` in JS, aber OHNE `break` noetig!
|
||||
|
||||
---
|
||||
|
||||
## Karte 10 | Mittel
|
||||
**Q:** Was macht `Quit all methods`?
|
||||
**A:** Bricht die GESAMTE Methodenkette ab (alle aufrufenden Methoden). Wie ein sofortiger Hard-Exit. Vorsichtig verwenden!
|
||||
|
||||
---
|
||||
|
||||
## Karte 11 | Mittel
|
||||
**Q:** Was macht `Enter data`?
|
||||
**A:** Uebergibt die Kontrolle an den Benutzer, damit er Daten eingeben kann. Die Methode pausiert, bis der User fertig ist. Gibt es in modernen Sprachen nicht!
|
||||
|
||||
---
|
||||
|
||||
## Karte 12 | Mittel
|
||||
**Q:** Was macht `Yes/No message`?
|
||||
**A:** Zeigt einen Dialog mit Ja/Nein-Buttons. Ergebnis in `#F`: `Yes/No message {Sicher?} / If flag true ... End If`. Wie `confirm()` in JS.
|
||||
|
||||
---
|
||||
|
||||
## Karte 13 | Mittel
|
||||
**Q:** Was ist `#F` (der Flag)?
|
||||
**A:** Ein globaler Boolean-Wert, der von vielen Befehlen gesetzt wird. `Returns #F` bei SQL-Operationen. Wie ein impliziter Return-Code. Abfrage mit `If flag true`.
|
||||
|
||||
---
|
||||
|
||||
## Karte 14 | Mittel
|
||||
**Q:** Was macht `Breakpoint`?
|
||||
**A:** Haelt die Ausfuehrung an und oeffnet den Debugger - wie `debugger;` in JavaScript.
|
||||
|
||||
---
|
||||
|
||||
## Karte 15 | Mittel
|
||||
**Q:** Was macht `Begin/End reversible block`?
|
||||
**A:** Definiert Code, der automatisch rueckgaengig gemacht wird, wenn die aeussere Methode endet. Fuer temporaere Aenderungen (Cursor, Fenster-Zustand etc.).
|
||||
|
||||
---
|
||||
|
||||
## Karte 16 | Mittel
|
||||
**Q:** Was macht `Set main file`?
|
||||
**A:** Setzt die Hauptdatei (Tabelle) fuer Datenoperationen. Legacy-Konzept aus der Omnis-eigenen DB, wird bei SQL-DAMs weniger gebraucht.
|
||||
|
||||
---
|
||||
|
||||
## Karte 17 | Fortgeschritten
|
||||
**Q:** Was macht `Do inherited`?
|
||||
**A:** Ruft die gleichnamige Methode der Superklasse auf - wie `super.method()` in JS oder `super().method()` in Python.
|
||||
|
||||
---
|
||||
|
||||
## Karte 18 | Fortgeschritten
|
||||
**Q:** Was macht `Install menu`?
|
||||
**A:** Installiert ein Menu-Objekt in der Menueleiste. Omnis hat ein eigenes Menu-System (nicht HTML-basiert fuer Desktop-Apps).
|
||||
|
||||
---
|
||||
|
||||
## Karte 19 | Fortgeschritten
|
||||
**Q:** Was macht `Prepare for insert` / `Prepare for edit`?
|
||||
**A:** Bereitet einen Datensatz zum Einfuegen/Bearbeiten vor. Setzt interne Flags und initialisiert Felder. Teil des Omnis-Daten-Workflows.
|
||||
|
||||
---
|
||||
|
||||
## Karte 20 | Fortgeschritten
|
||||
**Q:** Was macht `Update files`?
|
||||
**A:** Schreibt geaenderte Daten zurueck in die Datenbank. Wie `COMMIT` in SQL + `$flush()`. Teil des legacy Daten-Workflow.
|
||||
|
||||
---
|
||||
|
||||
## Karte 21 | Basis
|
||||
**Q:** Was macht `Set current list`?
|
||||
**A:** Setzt die "aktive" Liste fuer Listenbefehle. `Set current list lMyList`. Legacy-Ansatz - besser: direkte $-Notation verwenden.
|
||||
|
||||
---
|
||||
|
||||
## Karte 22 | Mittel
|
||||
**Q:** Was macht `Redraw`?
|
||||
**A:** Erzwingt das Neuzeichnen eines UI-Elements. `Do $cinst.$objs.myField.$redraw()` oder `Redraw {myField}`. Wie `forceUpdate()` in React.
|
||||
|
||||
---
|
||||
|
||||
## Karte 23 | Mittel
|
||||
**Q:** Was macht `Send to back / Bring to front`?
|
||||
**A:** Aendert die Z-Order von UI-Elementen (welches Element vorne liegt). Desktop-UI-Konzept.
|
||||
|
||||
---
|
||||
|
||||
## Karte 24 | Fortgeschritten
|
||||
**Q:** Was macht `Do redirect`?
|
||||
**A:** Leitet eine Methode auf ein anderes Objekt um. `Do redirect (lOtherObj, 'methodName')`. Wie Delegation/Proxy in JS.
|
||||
|
||||
---
|
||||
|
||||
## Karte 25 | Fortgeschritten
|
||||
**Q:** Was macht `Queue` Befehle (Queue set, Queue send, etc.)?
|
||||
**A:** Reiht Events in die Event-Queue ein, die nach der aktuellen Methode verarbeitet werden. Wie `setTimeout(fn, 0)` / `queueMicrotask()` in JS - asynchrone Ausfuehrung.
|
||||
|
||||
---
|
||||
|
||||
## Spaced Repetition Tracking
|
||||
|
||||
| Karte | Zuletzt | Naechste | Schwierigkeit |
|
||||
|-------|---------|----------|---------------|
|
||||
| (wird beim Ueben gefuellt) | | | |
|
||||
102
edu/content/flashcards/deck-gotchas.md
Normale Datei
102
edu/content/flashcards/deck-gotchas.md
Normale Datei
|
|
@ -0,0 +1,102 @@
|
|||
# Flashcard Deck: Gotchas & Haeufige Fehler
|
||||
|
||||
**Thema**: Typische Fallen und wie man sie vermeidet
|
||||
**Karten**: 15
|
||||
|
||||
---
|
||||
|
||||
## Karte 1 | Kritisch
|
||||
**Q:** Warum liefert meine Berechnung manchmal unerwartet 0 oder leer?
|
||||
**A:** NULL-Propagation! Wenn IRGEND ein Wert in einem Ausdruck NULL ist, wird das GANZE Ergebnis NULL. Loesung: Immer vorher auf NULL pruefen mit `isnull(lVar)` oder `nullValuesWhenORtestedBecomeZero` setzen.
|
||||
|
||||
---
|
||||
|
||||
## Karte 2 | Kritisch
|
||||
**Q:** Ich rufe eine Methode auf, aber sie wird nicht gefunden. Warum?
|
||||
**A:** Die Methode ist wahrscheinlich auf der SUPERKLASSE definiert. Omnis-Klassen erben Methoden. Pruefe: `oSuperData`, `T_Super`, `wMainWindow`, `wBaseWindow`. Auch: Tippfehler im $-Methodennamen!
|
||||
|
||||
---
|
||||
|
||||
## Karte 3 | Kritisch
|
||||
**Q:** Mein `lList.spalte` gibt immer leer zurueck. Warum?
|
||||
**A:** Die Liste hat keine aktuelle Zeile gesetzt (`$line = 0`). Setze zuerst `$line`: `Do lList.$line.$assign(1)` oder nutze `For each line in list`.
|
||||
|
||||
---
|
||||
|
||||
## Karte 4 | Kritisch
|
||||
**Q:** `Do $cinst.$objs.feld.$contents = "Test"` funktioniert nicht. Warum?
|
||||
**A:** Man kann Notation-Properties NICHT mit `=` setzen! Immer `$assign()` verwenden: `Do $cinst.$objs.feld.$contents.$assign("Test")`. Das ist DER haeufigste Anfaengerfehler!
|
||||
|
||||
---
|
||||
|
||||
## Karte 5 | Wichtig
|
||||
**Q:** Mein Remote Form reagiert traege. Warum?
|
||||
**A:** Jeder `$event()` macht einen Server-Roundtrip! Loesung: Validierung und UI-Logik in `$eventclient()` (Browser-seitig) ausfuehren. Nur Datenbankzugriff im Server-Event.
|
||||
|
||||
---
|
||||
|
||||
## Karte 6 | Wichtig
|
||||
**Q:** Mein SQL mit `[lVar]` erzeugt seltsame Fehler bei Sonderzeichen. Warum?
|
||||
**A:** `[lVar]` macht direkte Text-Substitution - Apostroph im Namen -> SQL-Fehler oder SQL-Injection! Immer `@[lVar]` (Bind-Variable) oder `:1`-Parameter verwenden!
|
||||
|
||||
---
|
||||
|
||||
## Karte 7 | Wichtig
|
||||
**Q:** Meine Aenderungen an einer Variable werden in einem anderen Window nicht sichtbar. Warum?
|
||||
**A:** Variable-Scoping! `lVar` (lokal) lebt nur in der Methode. `iVar` (Instanz) nur im Objekt. Fuer fenster-uebergreifend: `tVar` (Task) verwenden oder Daten explizit uebergeben.
|
||||
|
||||
---
|
||||
|
||||
## Karte 8 | Wichtig
|
||||
**Q:** Ich habe eine Klasse geaendert, aber die Aenderung wirkt sich nicht aus. Warum?
|
||||
**A:** Moeglicherweise laeuft noch eine alte Instanz! Schliesse alle offenen Fenster/Instanzen und oeffne neu. Oder: Die Methode ist auf der Superklasse und du aenderst die falsche Klasse.
|
||||
|
||||
---
|
||||
|
||||
## Karte 9 | Mittel
|
||||
**Q:** Warum zaehlt `$linecount` von 1 und nicht von 0?
|
||||
**A:** Omnis-Listen sind 1-basiert (wie VB, anders als JS/Python). `$line = 1` ist die ERSTE Zeile. `$line = 0` bedeutet "keine Zeile gewaehlt".
|
||||
|
||||
---
|
||||
|
||||
## Karte 10 | Mittel
|
||||
**Q:** Mein `$search` findet nichts, obwohl der Wert existiert. Warum?
|
||||
**A:** String-Vergleich ist Case-Sensitive in Omnis! `"Harry" <> "harry"`. Loesung: `Do lList.$search(upp(lList.name) = upp(lSearchTerm))` oder `low()` verwenden.
|
||||
|
||||
---
|
||||
|
||||
## Karte 11 | Mittel
|
||||
**Q:** Was passiert wenn ich `Calculate lList as lOtherList` mache?
|
||||
**A:** Du bekommst eine KOPIE, keine Referenz! Aenderungen an `lList` aendern `lOtherList` NICHT. Das ist anders als bei Arrays in JavaScript!
|
||||
|
||||
---
|
||||
|
||||
## Karte 12 | Mittel
|
||||
**Q:** Mein `$sendall` wirft einen Fehler bei leeren Listen. Warum?
|
||||
**A:** `$sendall` auf eine leere Liste ist eigentlich ok, aber wenn der Ausdruck auf Spalten zugreift die nicht existieren, kommt ein Fehler. Immer vorher pruefen: `If lList.$linecount > 0`.
|
||||
|
||||
---
|
||||
|
||||
## Karte 13 | Fortgeschritten
|
||||
**Q:** Mein `Quit method` gibt nichts zurueck, obwohl ich einen Wert angebe. Warum?
|
||||
**A:** Der Aufrufer muss `Returns lVar` verwenden! Ohne `Returns` geht der Rueckgabewert verloren: `Do iObj.$method() Returns lResult` (richtig) vs `Do iObj.$method()` (Wert geht verloren).
|
||||
|
||||
---
|
||||
|
||||
## Karte 14 | Fortgeschritten
|
||||
**Q:** In Solution2: Warum sehe ich einen Datensatz mit `valid = false`?
|
||||
**A:** Soft-Delete! `valid = false` bedeutet "geloescht" aber noch in der DB. Immer `WHERE valid = true` in Abfragen verwenden. Solution2 nutzt `valid` konsequent statt physischem DELETE.
|
||||
|
||||
---
|
||||
|
||||
## Karte 15 | Fortgeschritten
|
||||
**Q:** Mein Report druckt leere Seiten. Warum?
|
||||
**A:** Die Report-Klasse hat keine Daten! Reports brauchen eine definierte Liste als Datenquelle (`$dataname`). Pruefe: Wurde die Liste vor dem Report-Aufruf korrekt befuellt?
|
||||
|
||||
---
|
||||
|
||||
## Spaced Repetition Tracking
|
||||
|
||||
| Karte | Zuletzt | Naechste | Schwierigkeit |
|
||||
|-------|---------|----------|---------------|
|
||||
| (wird beim Ueben gefuellt) | | | |
|
||||
166
edu/content/flashcards/deck-lists.md
Normale Datei
166
edu/content/flashcards/deck-lists.md
Normale Datei
|
|
@ -0,0 +1,166 @@
|
|||
# Flashcard Deck: Listen & Rows
|
||||
|
||||
**Thema**: Omnis Listen - der universelle Datencontainer
|
||||
**Schwierigkeit**: Anfaenger -> Fortgeschritten
|
||||
**Karten**: 20
|
||||
|
||||
---
|
||||
|
||||
## Karte 1 | Basis
|
||||
**Q:** Was ist eine "List" in Omnis?
|
||||
**A:** Ein zweidimensionaler Datencontainer mit benannten, typisierten Spalten und beliebig vielen Zeilen. Wie ein Array von Objects in JS, ein DataFrame in Python, oder ein RecordSet in VB.
|
||||
|
||||
---
|
||||
|
||||
## Karte 2 | Basis
|
||||
**Q:** Was ist eine "Row" in Omnis?
|
||||
**A:** Eine einzelne Datenzeile mit benannten Spalten. Wie ein Object/Dictionary. Eine List besteht aus vielen Rows.
|
||||
|
||||
---
|
||||
|
||||
## Karte 3 | Basis
|
||||
**Q:** Wie erstellst du eine Liste mit Spalten?
|
||||
**A:**
|
||||
```omnis
|
||||
Do lList.$cols.$add('id', kInteger)
|
||||
Do lList.$cols.$add('name', kCharacter, kSimplechar, 100)
|
||||
Do lList.$cols.$add('price', kNumber, k2dp, 10)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Karte 4 | Basis
|
||||
**Q:** Wie fuegst du eine Zeile zu einer Liste hinzu?
|
||||
**A:**
|
||||
```omnis
|
||||
Do lList.$add()
|
||||
Calculate lList.id as 1
|
||||
Calculate lList.name as "Produkt A"
|
||||
Calculate lList.price as 29.99
|
||||
```
|
||||
`$add()` fuegt eine Zeile hinzu UND macht sie zur aktuellen Zeile.
|
||||
|
||||
---
|
||||
|
||||
## Karte 5 | Basis
|
||||
**Q:** Wie iterierst du ueber alle Zeilen einer Liste?
|
||||
**A:**
|
||||
```omnis
|
||||
For each line in list from 1 to lList.$linecount step 1
|
||||
# lList.spaltenname gibt den Wert der aktuellen Zeile
|
||||
Calculate lTotal as lTotal + lList.price
|
||||
End For
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Karte 6 | Mittel
|
||||
**Q:** Wie suchst du in einer Liste?
|
||||
**A:** `Do lList.$search(lList.name = "Produkt A")` - Setzt `$line` auf den Treffer. `If flag true` prueft ob gefunden.
|
||||
|
||||
---
|
||||
|
||||
## Karte 7 | Mittel
|
||||
**Q:** Wie sortierst du eine Liste?
|
||||
**A:** `Do lList.$sort(lList.name, kTrue)` - Sortiert nach Spalte "name". `kTrue` = aufsteigend, `kFalse` = absteigend.
|
||||
|
||||
---
|
||||
|
||||
## Karte 8 | Mittel
|
||||
**Q:** Wie entfernst du eine Zeile aus einer Liste?
|
||||
**A:** `Do lList.$remove(lList.$line)` entfernt die aktuelle Zeile. `Do lList.$remove(3)` entfernt Zeile 3. `Do lList.$clear()` leert alle Zeilen.
|
||||
|
||||
---
|
||||
|
||||
## Karte 9 | Mittel
|
||||
**Q:** Was ist `$linecount`?
|
||||
**A:** Die Anzahl der Zeilen in einer Liste. `Calculate lAnzahl as lList.$linecount`. Wie `array.length` in JS.
|
||||
|
||||
---
|
||||
|
||||
## Karte 10 | Mittel
|
||||
**Q:** Was ist `$line`?
|
||||
**A:** Die aktuelle Zeilennummer einer Liste (1-basiert!). Wird durch `$search`, `$add`, Klick auf Grid gesetzt. `0` = keine Zeile gewaehlt.
|
||||
|
||||
---
|
||||
|
||||
## Karte 11 | Mittel
|
||||
**Q:** Wie liest du eine bestimmte Zeile (nicht die aktuelle)?
|
||||
**A:** `Calculate lVal as lList.[3].name` liest Spalte "name" von Zeile 3. Die eckigen Klammern addressieren die Zeilennummer.
|
||||
|
||||
---
|
||||
|
||||
## Karte 12 | Fortgeschritten
|
||||
**Q:** Was macht `$sendall()`?
|
||||
**A:** Fuehrt einen Ausdruck fuer JEDE Zeile der Liste aus (wie `forEach` + `map` in einem):
|
||||
```omnis
|
||||
Do lList.$sendall($ref.price.$assign($ref.price * 1.19))
|
||||
```
|
||||
`$ref` = aktuelle Zeile.
|
||||
|
||||
---
|
||||
|
||||
## Karte 13 | Fortgeschritten
|
||||
**Q:** Wie filterst du eine Liste?
|
||||
**A:** `$search` mit `kTrue` im 2. Parameter zeigt nur Treffer:
|
||||
```omnis
|
||||
Do lList.$search(lList.status = 'active', kTrue)
|
||||
```
|
||||
Nicht-Treffer werden "ausgeblendet" (nicht geloescht). `Do lList.$search(kTrue)` zeigt wieder alle.
|
||||
|
||||
---
|
||||
|
||||
## Karte 14 | Fortgeschritten
|
||||
**Q:** Was ist der Unterschied zwischen `$merge()` und `$add()`?
|
||||
**A:** `$add()` fuegt eine leere Zeile hinzu. `$merge(lOtherList)` fuegt ALLE Zeilen einer anderen Liste hinzu - wie `array.concat()` in JS.
|
||||
|
||||
---
|
||||
|
||||
## Karte 15 | Fortgeschritten
|
||||
**Q:** Wie definierst du eine Liste aus einer Schema-Klasse?
|
||||
**A:** `Do lList.$definefromsqlclass('scMySchema')` - Uebernimmt die Spaltenstruktur aus dem Schema. Wie ein Typ/Interface fuer die Liste.
|
||||
|
||||
---
|
||||
|
||||
## Karte 16 | Fortgeschritten
|
||||
**Q:** Was ist `$colcount`?
|
||||
**A:** Die Anzahl der Spalten einer Liste. `Calculate lCols as lList.$colcount`. Fuer dynamische Listen nuetzlich.
|
||||
|
||||
---
|
||||
|
||||
## Karte 17 | Fortgeschritten
|
||||
**Q:** Wie kopierst du eine Liste?
|
||||
**A:** `Calculate lCopy as lOriginal` erstellt eine **Kopie** (nicht Referenz!). Omnis-Listen sind Value-Types, nicht Reference-Types wie in JS!
|
||||
|
||||
---
|
||||
|
||||
## Karte 18 | Fortgeschritten
|
||||
**Q:** Wie befuellst du eine Liste aus SQL?
|
||||
**A:**
|
||||
```omnis
|
||||
Do lStmt.$execdirect('SELECT * FROM orders') Returns #F
|
||||
If flag true
|
||||
Do lStmt.$fetch(lList, kFetchAll) Returns #F
|
||||
End If
|
||||
```
|
||||
`kFetchAll` holt alle Zeilen auf einmal.
|
||||
|
||||
---
|
||||
|
||||
## Karte 19 | Fortgeschritten
|
||||
**Q:** Was ist `$selected` bei einer Liste?
|
||||
**A:** Ein Boolean-Flag pro Zeile, das anzeigt ob die Zeile "ausgewaehlt" ist (z.B. per Checkbox im Grid). `lList.$selected` liest/setzt den Wert der aktuellen Zeile.
|
||||
|
||||
---
|
||||
|
||||
## Karte 20 | Fortgeschritten
|
||||
**Q:** Was ist der Unterschied zwischen Listen und Rows beim SQL-Fetch?
|
||||
**A:** `$fetch(lList, kFetchAll)` holt mehrere Zeilen in eine Liste. `$fetch(lRow, kFetchOne)` holt nur eine Zeile in eine Row. Row = einzelner Datensatz, Liste = Ergebnismenge.
|
||||
|
||||
---
|
||||
|
||||
## Spaced Repetition Tracking
|
||||
|
||||
| Karte | Zuletzt | Naechste | Schwierigkeit |
|
||||
|-------|---------|----------|---------------|
|
||||
| (wird beim Ueben gefuellt) | | | |
|
||||
193
edu/content/flashcards/deck-notation.md
Normale Datei
193
edu/content/flashcards/deck-notation.md
Normale Datei
|
|
@ -0,0 +1,193 @@
|
|||
# Flashcard Deck: $ Notation
|
||||
|
||||
**Thema**: Das Omnis $-Notationssystem
|
||||
**Schwierigkeit**: Anfaenger -> Fortgeschritten
|
||||
**Karten**: 30
|
||||
|
||||
---
|
||||
|
||||
## Karte 1 | Basis
|
||||
**Q:** Was bedeutet `$cinst` in Omnis?
|
||||
**A:** Die aktuelle Instanz - aequivalent zu `this` in JavaScript oder `self` in Python. Zeigt auf das aktuelle Window/Objekt.
|
||||
|
||||
---
|
||||
|
||||
## Karte 2 | Basis
|
||||
**Q:** Wie liest du den Inhalt eines Feldes "customerName" auf dem aktuellen Window?
|
||||
**A:** `Calculate lVal as $cinst.$objs.customerName.$contents`
|
||||
|
||||
---
|
||||
|
||||
## Karte 3 | Basis
|
||||
**Q:** Wie SETZT du den Inhalt eines Feldes? Warum geht `= ` nicht?
|
||||
**A:** `Do $cinst.$objs.customerName.$contents.$assign("Meier")` - Man muss `$assign()` verwenden, weil Notation-Pfade Objekte sind, keine einfachen Variablen.
|
||||
|
||||
---
|
||||
|
||||
## Karte 4 | Basis
|
||||
**Q:** Was ist der Unterschied zwischen `$objs` und `$bobjs`?
|
||||
**A:** `$objs` = Objekte auf dem aktuellen Fenster/Form. `$bobjs` = "Background objects" / Objekte auf einer Superklasse (geerbte Objekte).
|
||||
|
||||
---
|
||||
|
||||
## Karte 5 | Basis
|
||||
**Q:** Was gibt `$clib` zurueck?
|
||||
**A:** Die aktuelle Library (das Omnis-Projekt / .lbs Datei), in der der Code laeuft.
|
||||
|
||||
---
|
||||
|
||||
## Karte 6 | Basis
|
||||
**Q:** Wie greifst du auf eine andere Klasse in der gleichen Library zu?
|
||||
**A:** `Do $clib.$classes.ClassName.$open() Returns lRef`
|
||||
|
||||
---
|
||||
|
||||
## Karte 7 | Mittel
|
||||
**Q:** Was bedeutet `$ctask`?
|
||||
**A:** Der aktuelle Task - eine Art globaler Kontext/Session. Task-Variablen (`tVar`) leben hier.
|
||||
|
||||
---
|
||||
|
||||
## Karte 8 | Mittel
|
||||
**Q:** Wie machst du ein Feld unsichtbar?
|
||||
**A:** `Do $cinst.$objs.fieldName.$visible.$assign(kFalse)`
|
||||
|
||||
---
|
||||
|
||||
## Karte 9 | Mittel
|
||||
**Q:** Wie rufst du eine Methode auf einem anderen Objekt auf?
|
||||
**A:** `Do iMyObject.$methodName(param1, param2) Returns lResult`
|
||||
|
||||
---
|
||||
|
||||
## Karte 10 | Mittel
|
||||
**Q:** Was ist `$cols` bei einer Liste?
|
||||
**A:** Die Spalten-Sammlung einer Liste. `lList.$cols.$add('name', kCharacter, kSimplechar, 255)` fuegt eine Spalte hinzu.
|
||||
|
||||
---
|
||||
|
||||
## Karte 11 | Mittel
|
||||
**Q:** Wie zaehlt man die Zeilen einer Liste?
|
||||
**A:** `Calculate lCount as lList.$linecount`
|
||||
|
||||
---
|
||||
|
||||
## Karte 12 | Mittel
|
||||
**Q:** Was macht `$line`?
|
||||
**A:** Gibt die aktuelle Zeilennummer einer Liste zurueck oder setzt sie. `Do lList.$line.$assign(5)` springt zu Zeile 5.
|
||||
|
||||
---
|
||||
|
||||
## Karte 13 | Mittel
|
||||
**Q:** Wie greifst du auf den Wert einer Spalte "price" in der aktuellen Zeile einer Liste zu?
|
||||
**A:** `Calculate lPrice as lList.price` (wenn `$line` gesetzt ist) oder `Calculate lPrice as lList.[lRow].price` fuer eine bestimmte Zeile.
|
||||
|
||||
---
|
||||
|
||||
## Karte 14 | Fortgeschritten
|
||||
**Q:** Was ist `$sendall()`?
|
||||
**A:** Fuehrt einen Befehl fuer ALLE Zeilen einer Liste aus - wie `forEach` in JS. Beispiel: `Do lList.$sendall($ref.price.$assign($ref.price * 1.19))` (19% MwSt auf alle Preise)
|
||||
|
||||
---
|
||||
|
||||
## Karte 15 | Fortgeschritten
|
||||
**Q:** Was bedeutet `$ref` in `$sendall`?
|
||||
**A:** `$ref` ist die Referenz auf die aktuelle Zeile innerhalb von `$sendall` - wie der Callback-Parameter in `Array.forEach(item => ...)`.
|
||||
|
||||
---
|
||||
|
||||
## Karte 16 | Fortgeschritten
|
||||
**Q:** Wie findest du eine Zeile in einer Liste per Suche?
|
||||
**A:** `Do lList.$search(lList.id = lSearchID)` - Setzt `$line` auf die gefundene Zeile. `#F` (Flag) zeigt Erfolg.
|
||||
|
||||
---
|
||||
|
||||
## Karte 17 | Fortgeschritten
|
||||
**Q:** Was ist `$getAllCols()`?
|
||||
**A:** Laedt alle Spalten einer Datenbankabfrage in die Liste, ohne sie einzeln zu benennen.
|
||||
|
||||
---
|
||||
|
||||
## Karte 18 | Basis
|
||||
**Q:** Was macht `kTrue` vs `kFalse`?
|
||||
**A:** Omnis-Konstanten fuer Boolean true/false. Immer mit `k`-Praefix (k = Konstante).
|
||||
|
||||
---
|
||||
|
||||
## Karte 19 | Mittel
|
||||
**Q:** Wie oeffnest du ein Window (Fenster)?
|
||||
**A:** `Do $clib.$windows.wMyWindow.$open('*') Returns lWinRef`
|
||||
|
||||
---
|
||||
|
||||
## Karte 20 | Mittel
|
||||
**Q:** Was bedeutet der `'*'` Parameter bei `$open`?
|
||||
**A:** Oeffnet das Fenster als neue Instanz. Ohne `'*'` wird eine bestehende Instanz wiederverwendet.
|
||||
|
||||
---
|
||||
|
||||
## Karte 21 | Fortgeschritten
|
||||
**Q:** Wie iterierst du ueber alle Objekte auf einem Window?
|
||||
**A:** `For each $cinst.$objs as lObj` - wie `for (const el of document.querySelectorAll('*'))` in JS.
|
||||
|
||||
---
|
||||
|
||||
## Karte 22 | Fortgeschritten
|
||||
**Q:** Was ist der Unterschied zwischen `$cclass` und `$cinst`?
|
||||
**A:** `$cclass` = die Klasse (Bauplan/Template), `$cinst` = die konkrete Instanz (laufendes Objekt). Wie `MyClass` vs `myInstance` in JS.
|
||||
|
||||
---
|
||||
|
||||
## Karte 23 | Basis
|
||||
**Q:** Wie gibt eine Methode einen Wert zurueck?
|
||||
**A:** `Quit method lReturnValue` - aequivalent zu `return lReturnValue` in JS.
|
||||
|
||||
---
|
||||
|
||||
## Karte 24 | Mittel
|
||||
**Q:** Was ist `$event`?
|
||||
**A:** Die Standard-Event-Handler-Methode einer Klasse. Wird bei UI-Events aufgerufen (wie `onClick`). Parameter `pEventCode` enthaelt den Event-Typ.
|
||||
|
||||
---
|
||||
|
||||
## Karte 25 | Fortgeschritten
|
||||
**Q:** Unterschied `$event` vs `$eventclient` bei Remote Forms?
|
||||
**A:** `$event` = laeuft auf dem SERVER. `$eventclient` = laeuft im BROWSER (JavaScript). Fuer schnelle UI-Reaktionen `$eventclient` verwenden.
|
||||
|
||||
---
|
||||
|
||||
## Karte 26 | Fortgeschritten
|
||||
**Q:** Wie greifst du von einer Instanz auf die Instanz-Variable eines anderen offenen Windows zu?
|
||||
**A:** `Calculate lVal as $iwindows.wOtherWindow.$ivar.iMyVariable`
|
||||
|
||||
---
|
||||
|
||||
## Karte 27 | Mittel
|
||||
**Q:** Was macht `$add()` bei einer Liste?
|
||||
**A:** Fuegt eine neue leere Zeile am Ende hinzu. `Do lList.$add()`. Danach Werte setzen mit `Calculate lList.colName as "wert"`.
|
||||
|
||||
---
|
||||
|
||||
## Karte 28 | Mittel
|
||||
**Q:** Wie loeschst du eine Zeile aus einer Liste?
|
||||
**A:** `Do lList.$remove(lList.$line)` - entfernt die aktuelle Zeile. Oder `Do lList.$remove(5)` fuer Zeile 5.
|
||||
|
||||
---
|
||||
|
||||
## Karte 29 | Fortgeschritten
|
||||
**Q:** Was ist `$define()` bei einem Schema/Query?
|
||||
**A:** Definiert die Spaltenstruktur. `Do lSchema.$define(col1, col2, ...)` - wie ein CREATE TABLE fuer eine Omnis-Datenstruktur.
|
||||
|
||||
---
|
||||
|
||||
## Karte 30 | Fortgeschritten
|
||||
**Q:** Wie navigierst du durch die gesamte Omnis-Objekthierarchie?
|
||||
**A:** Von oben: `$root` -> `$libs` -> Library -> `$classes` -> Class -> `$methods` / `$objs` / `$ivars`. Alles ist ein Baum mit `$` Pfaden!
|
||||
|
||||
---
|
||||
|
||||
## Spaced Repetition Tracking
|
||||
|
||||
| Karte | Zuletzt | Naechste | Schwierigkeit |
|
||||
|-------|---------|----------|---------------|
|
||||
| (wird beim Ueben gefuellt) | | | |
|
||||
132
edu/content/flashcards/deck-solution2.md
Normale Datei
132
edu/content/flashcards/deck-solution2.md
Normale Datei
|
|
@ -0,0 +1,132 @@
|
|||
# Flashcard Deck: Solution2 Architektur & Konventionen
|
||||
|
||||
**Thema**: Solution2 ERP-System kennenlernen
|
||||
**Karten**: 20
|
||||
|
||||
---
|
||||
|
||||
## Karte 1 | Basis
|
||||
**Q:** Was ist Solution2?
|
||||
**A:** Ein vollstaendiges deutsches ERP-System (Enterprise Resource Planning) gebaut auf Omnis Studio. Abdeckung: Verkauf, Einkauf, Fertigung, Lager, Qualitaet, Buchhaltung, HR, Mobile.
|
||||
|
||||
---
|
||||
|
||||
## Karte 2 | Basis
|
||||
**Q:** Welche Datenbank nutzt Solution2?
|
||||
**A:** PostgreSQL. Datenbank `masterdemo`, Schema `soluser`. Verbindung ueber den PostgreSQL-DAM (`PGSQLDAM`).
|
||||
|
||||
---
|
||||
|
||||
## Karte 3 | Basis
|
||||
**Q:** Was bedeutet das Praefix `w` bei einer Solution2-Klasse?
|
||||
**A:** Window-Klasse = UI-Formular. z.B. `wOrders` = das Auftragsformular, `wLogin` = der Login-Dialog.
|
||||
|
||||
---
|
||||
|
||||
## Karte 4 | Basis
|
||||
**Q:** Was bedeutet das Praefix `o`?
|
||||
**A:** Object-Klasse = Business-Logik. z.B. `oCreateInvoice` = Logik fuer Rechnungserstellung, `oLogin` = Login-Validierung.
|
||||
|
||||
---
|
||||
|
||||
## Karte 5 | Basis
|
||||
**Q:** Was bedeutet `T_` als Praefix?
|
||||
**A:** Table-Klasse = Daten-Cursor/Datenliste. z.B. `T_Orders` = Auftragsliste, `T_Super` = Basis-Table-Klasse fuer alle.
|
||||
|
||||
---
|
||||
|
||||
## Karte 6 | Basis
|
||||
**Q:** Welche 4 Audit-Spalten hat JEDE Solution2-Tabelle?
|
||||
**A:** `created` (TIMESTAMP), `modtime` (TIMESTAMP), `revisor` (INTEGER = Employee-ID), `valid` (BOOLEAN = Soft-Delete). Immer pruefen und setzen!
|
||||
|
||||
---
|
||||
|
||||
## Karte 7 | Mittel
|
||||
**Q:** Was ist das Dual-Signature-Pattern?
|
||||
**A:** Viele Geschaeftsdokumente benoetigen Vier-Augen-Prinzip: `firstsigned` (1. Unterschrift), `needsecondsignature` (braucht 2.?), `secondrevisor` (wer prueft), `secondsigned` (2. Unterschrift erteilt).
|
||||
|
||||
---
|
||||
|
||||
## Karte 8 | Mittel
|
||||
**Q:** Was ist `oSuperData`?
|
||||
**A:** Die Basis-Superklasse fuer fast alle Business-Logik-Objekte (`o`-Klassen). Enthaelt gemeinsame Methoden fuer Datenzugriff, Validierung, Navigation.
|
||||
|
||||
---
|
||||
|
||||
## Karte 9 | Mittel
|
||||
**Q:** Wie funktioniert das RBAC (Berechtigungssystem) in Solution2?
|
||||
**A:** Form-Path-basiert! Berechtigungsgruppen werden Navigation-Pfaden zugewiesen. `T_ModuleAccess2Methods` steuert den Zugriff auf Modul-Methoden. Nicht per Screen, sondern per Modul.
|
||||
|
||||
---
|
||||
|
||||
## Karte 10 | Mittel
|
||||
**Q:** Welche Library enthaelt den Login und die Navigation?
|
||||
**A:** `solution2` (die Haupt-Library). Klassen: `wLogin`, `oLogin`, `oLogon`, `oNavigate`, `wEnterprise`.
|
||||
|
||||
---
|
||||
|
||||
## Karte 11 | Mittel
|
||||
**Q:** Was macht die `solution2Services`-Library?
|
||||
**A:** Hintergrund-/Service-Layer: Push-Notifications, Warehouse-Success-Handler, Order-Callbacks, Container-Management, Zugriffskontrolle.
|
||||
|
||||
---
|
||||
|
||||
## Karte 12 | Mittel
|
||||
**Q:** Wie heisst der Auftrags-zu-Rechnung-Prozess?
|
||||
**A:** Orders -> Lieferschein (deliverynoteitems) -> Rechnungsfreigabe (customerinvoicerequirement mit invoicingallowed=true) -> Rechnung (customerinvoices) -> Buchhaltungsexport.
|
||||
|
||||
---
|
||||
|
||||
## Karte 13 | Fortgeschritten
|
||||
**Q:** Was ist die `MobileWork`-Library?
|
||||
**A:** Der Web/Mobile-Client von Solution2, gebaut mit Omnis JS Remote Forms. Klassen: `jsMainForm`, `jsMainFrame`, `jsMainMenu`. Laeuft im Browser.
|
||||
|
||||
---
|
||||
|
||||
## Karte 14 | Fortgeschritten
|
||||
**Q:** Was sind die wichtigsten Tabellen im Verkauf?
|
||||
**A:** `orders` (Auftraege, 103 Spalten!), `orderitems` (Positionen), `deliverynoteitems` (Lieferschein), `customerinvoices` (Rechnungen, 90 Spalten), `customerinvoiceitems` (Rechnungspositionen).
|
||||
|
||||
---
|
||||
|
||||
## Karte 15 | Fortgeschritten
|
||||
**Q:** Was ist ZUGFeRD/Factur-X in Solution2?
|
||||
**A:** E-Rechnungsformate. Solution2 erzeugt und verarbeitet elektronische Rechnungen ueber `oOmnis2Zugferd` und `oXML_eInvoice` in der AdminAccounting-Library. Pflicht in EU seit 2025!
|
||||
|
||||
---
|
||||
|
||||
## Karte 16 | Fortgeschritten
|
||||
**Q:** Was ist die `BasicTools`-Library?
|
||||
**A:** Shared Utilities: HTML-Generierung (`cHTML`), Datei-Import (`oImportFile`), Edit-Utilities (`oEdit`), Fehleranzeige.
|
||||
|
||||
---
|
||||
|
||||
## Karte 17 | Mittel
|
||||
**Q:** In welcher Library ist der Einkauf?
|
||||
**A:** `Purchase` - Bestellungen, Lieferanten, Wareneingaenge, E-Rechnungen. Klassen: `wSupplierInvoices`, `wPurchaseOrderStockReceipt`, `T_SupplierInvoices`.
|
||||
|
||||
---
|
||||
|
||||
## Karte 18 | Mittel
|
||||
**Q:** Wie heissen die Klassen fuer die Fertigung?
|
||||
**A:** In der `Manufacturing`-Library: `oPartList` (Stueckliste), `rCalculateProductCosts` (Kalkulation), `scResourceSpecification` (Ressourcen).
|
||||
|
||||
---
|
||||
|
||||
## Karte 19 | Fortgeschritten
|
||||
**Q:** Was ist `T_SuperVersion`?
|
||||
**A:** Erweiterte Basis-Table-Klasse mit Versionierung. Fuer Tabellen die eine Aenderungshistorie benoetigen.
|
||||
|
||||
---
|
||||
|
||||
## Karte 20 | Fortgeschritten
|
||||
**Q:** Wie werden Custom Fields (Zusatzfelder) in Solution2 umgesetzt?
|
||||
**A:** Ueber die Tabellen `additionalfields` (Felddefinition: Typ, Zuordnung, Druck-Flags) und `additionalfieldsgroups` (Gruppierung). Koennen an verschiedene Entitaeten gehaengt werden (Auftraege, Teile, Fertigungsschritte...).
|
||||
|
||||
---
|
||||
|
||||
## Spaced Repetition Tracking
|
||||
|
||||
| Karte | Zuletzt | Naechste | Schwierigkeit |
|
||||
|-------|---------|----------|---------------|
|
||||
| (wird beim Ueben gefuellt) | | | |
|
||||
136
edu/content/flashcards/deck-sql.md
Normale Datei
136
edu/content/flashcards/deck-sql.md
Normale Datei
|
|
@ -0,0 +1,136 @@
|
|||
# Flashcard Deck: SQL & Datenbankzugriff in Omnis
|
||||
|
||||
**Thema**: SQL-Zugriff ueber DAMs (Database Access Modules)
|
||||
**Karten**: 15
|
||||
|
||||
---
|
||||
|
||||
## Karte 1 | Basis
|
||||
**Q:** Wie verbindet sich Omnis mit einer Datenbank?
|
||||
**A:** Ueber Session-Objekte und DAMs (Database Access Modules). Erst Session erstellen, dann `$logon()`:
|
||||
```omnis
|
||||
Do lSess.$logon('host', 'user', 'pass', 'sessName') Returns #F
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Karte 2 | Basis
|
||||
**Q:** Was ist der Unterschied zwischen `$prepare/$execute` und `$execdirect`?
|
||||
**A:** `$prepare`+`$execute` = vorbereitete Abfrage (parameterisiert, wiederverwendbar, sicher). `$execdirect` = direkte Ausfuehrung (einmalig). Fuer SELECT immer `$prepare/$execute` bevorzugen!
|
||||
|
||||
---
|
||||
|
||||
## Karte 3 | Basis
|
||||
**Q:** Wie holst du Daten aus einer SQL-Abfrage in eine Omnis-Liste?
|
||||
**A:**
|
||||
```omnis
|
||||
Do lStmt.$prepare('SELECT * FROM contact WHERE valid = :1') Returns #F
|
||||
Do lStmt.$execute(kTrue) Returns #F
|
||||
Do lStmt.$fetch(lResultList, kFetchAll) Returns #F
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Karte 4 | Basis
|
||||
**Q:** Was bedeutet `:1`, `:2` etc. in SQL-Statements?
|
||||
**A:** Bind-Variablen (Parameter). `:1` = erster Parameter, `:2` = zweiter etc. Werden bei `$execute` der Reihe nach uebergeben. **SICHER** gegen SQL-Injection!
|
||||
|
||||
---
|
||||
|
||||
## Karte 5 | Mittel
|
||||
**Q:** Was ist der Unterschied zwischen `@[lVar]` und `[lVar]` in Omnis-SQL?
|
||||
**A:** `@[lVar]` = Bind-Variable (sicher, parametrisiert). `[lVar]` = direkte Text-Substitution (UNSICHER, SQL-Injection moeglich!). **Immer `@[lVar]` verwenden!**
|
||||
|
||||
---
|
||||
|
||||
## Karte 6 | Mittel
|
||||
**Q:** Was macht `kFetchAll` vs `kFetchOne`?
|
||||
**A:** `kFetchAll` holt ALLE Ergebniszeilen in eine Liste. `kFetchOne` holt nur EINE Zeile (in eine Row oder die naechste Zeile einer Liste). Fuer grosse Ergebnismengen: `kFetchOne` in Schleife fuer bessere Speicher-Kontrolle.
|
||||
|
||||
---
|
||||
|
||||
## Karte 7 | Mittel
|
||||
**Q:** Wie fuehrst du ein INSERT aus?
|
||||
**A:**
|
||||
```omnis
|
||||
Do lStmt.$execdirect(con('INSERT INTO mytable (name, created) VALUES (@[lName], @[#D])')) Returns #F
|
||||
```
|
||||
`#D` = aktuelles Datum. Oder mit prepare: `$prepare('INSERT INTO mytable (name) VALUES (:1)')` -> `$execute(lName)`
|
||||
|
||||
---
|
||||
|
||||
## Karte 8 | Mittel
|
||||
**Q:** Wie machst du ein UPDATE?
|
||||
**A:**
|
||||
```omnis
|
||||
Do lStmt.$prepare('UPDATE orders SET status = :1, modtime = :2 WHERE orderid = :3') Returns #F
|
||||
Do lStmt.$execute('completed', #T, lOrderID) Returns #F
|
||||
```
|
||||
`#T` = aktueller Timestamp.
|
||||
|
||||
---
|
||||
|
||||
## Karte 9 | Mittel
|
||||
**Q:** Wie pruefst du ob eine SQL-Operation erfolgreich war?
|
||||
**A:** Jede SQL-Methode setzt `#F` (den Flag). `Returns #F` faengt den Wert auf:
|
||||
```omnis
|
||||
Do lStmt.$execute(lID) Returns #F
|
||||
If flag true
|
||||
# Erfolg
|
||||
Else
|
||||
# Fehler - lSess.$lasterror fuer Details
|
||||
End If
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Karte 10 | Fortgeschritten
|
||||
**Q:** Was ist `$lasterror` und `$lasterrortext`?
|
||||
**A:** Session-Properties die den letzten SQL-Fehler enthalten. `lSess.$lasterror` = Fehlercode, `lSess.$lasterrortext` = Fehlerbeschreibung. Immer bei `#F = false` pruefen!
|
||||
|
||||
---
|
||||
|
||||
## Karte 11 | Fortgeschritten
|
||||
**Q:** Wie machst du eine Transaktion in Omnis?
|
||||
**A:**
|
||||
```omnis
|
||||
Do lSess.$begin() Returns #F ;; BEGIN TRANSACTION
|
||||
# ... SQL Operationen ...
|
||||
If lAllesOK
|
||||
Do lSess.$commit() Returns #F ;; COMMIT
|
||||
Else
|
||||
Do lSess.$rollback() Returns #F ;; ROLLBACK
|
||||
End If
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Karte 12 | Fortgeschritten
|
||||
**Q:** Was ist ein "DAM" in Omnis?
|
||||
**A:** Database Access Module - ein Treiber fuer verschiedene DB-Systeme. Wichtige DAMs: `PGSQLDAM` (PostgreSQL), `OABORDAM` (Oracle), `MYSQLDAM` (MySQL), `ODBCDAM` (ODBC). Solution2 nutzt `PGSQLDAM`.
|
||||
|
||||
---
|
||||
|
||||
## Karte 13 | Fortgeschritten
|
||||
**Q:** Wie definierst du die Spalten einer Liste aus einem SQL-Ergebnis automatisch?
|
||||
**A:** Entweder `$getAllCols()` nach dem Fetch, oder `$definefromsqlclass('scMySchema')` vor dem Fetch. Automatisch: Omnis erkennt die Spalten beim Fetch von selbst, wenn die Liste leer ist.
|
||||
|
||||
---
|
||||
|
||||
## Karte 14 | Fortgeschritten
|
||||
**Q:** Was ist der Unterschied zwischen Server-Side SQL und Client-Side SQL in Remote Forms?
|
||||
**A:** Server-Side: SQL laeuft auf dem Omnis-Server (normal). Client-Side: Geht NICHT - der JS-Client im Browser hat keinen DB-Zugriff. Alle Daten muessen ueber Server-Methoden geladen werden.
|
||||
|
||||
---
|
||||
|
||||
## Karte 15 | Fortgeschritten
|
||||
**Q:** Wie wird in Solution2 die DB-Verbindung verwaltet?
|
||||
**A:** Ueber die `DBAccess`-Library. Sie verwaltet Sessions, Berechtigungen und Connection-Pooling. Die Session wird beim Login erstellt (`oLogin`/`oLogon`) und ueber `ioDBAccessStartup` im Navigator initialisiert.
|
||||
|
||||
---
|
||||
|
||||
## Spaced Repetition Tracking
|
||||
|
||||
| Karte | Zuletzt | Naechste | Schwierigkeit |
|
||||
|-------|---------|----------|---------------|
|
||||
| (wird beim Ueben gefuellt) | | | |
|
||||
170
edu/content/flashcards/deck-windows.md
Normale Datei
170
edu/content/flashcards/deck-windows.md
Normale Datei
|
|
@ -0,0 +1,170 @@
|
|||
# Flashcard Deck: Fensterprogrammierung & SubWindows
|
||||
|
||||
**Thema**: Window-Hierarchie, SubWindow-Muster, Command-Delegation in Solution2
|
||||
**Karten**: 25
|
||||
|
||||
---
|
||||
|
||||
## Karte 1 | Basis
|
||||
**Q:** Welche 3 Fenster-Superklassen hat Solution2?
|
||||
**A:** `wBaseWindow` (Wurzel), `wMainWindow` (Hauptfenster, erbt von wBaseWindow), `wSubWindow` (eingebettete Panels, erbt auch von wBaseWindow). Alle in `solution2/SuperClasses/`.
|
||||
|
||||
---
|
||||
|
||||
## Karte 2 | Basis
|
||||
**Q:** Was ist `wBaseWindow`?
|
||||
**A:** Die Wurzel-Superklasse ALLER Solution2-Fenster (hat KEINE eigene Superklasse). Definiert gemeinsame Infrastruktur: `ioCode`, `iiRef2SubWindow`, `ibControl2SubWindow`, `ilList`, `irRow`, `inEDMode`, `icCurrTabPane`.
|
||||
|
||||
---
|
||||
|
||||
## Karte 3 | Basis
|
||||
**Q:** Was ist `wMainWindow`?
|
||||
**A:** Superklasse fuer eigenstaendige Dateneingabe-Fenster (z.B. wOrders, wParts). Erbt von `wBaseWindow`. Fuegt hinzu: `irRowCount`, `irRowMax`, `irStatusBarPane`. Ruft bei Commands immer `$closeRelatedWindow()` auf.
|
||||
|
||||
---
|
||||
|
||||
## Karte 4 | Basis
|
||||
**Q:** Was ist `wSubWindow`?
|
||||
**A:** Superklasse fuer eingebettete Fenster-Panels (in Tabs/Paged Panes). Erbt von `wBaseWindow`. Fuegt hinzu: `iiRef2Parent` (Rueck-Referenz), `icFormWindow` (Rechte), `icSubWindow`, `iiRef2Window`. Ermoeglicht rekursive Verschachtelung.
|
||||
|
||||
---
|
||||
|
||||
## Karte 5 | Kritisch
|
||||
**Q:** Was macht `ibControl2SubWindow`?
|
||||
**A:** DER zentrale Schalter! Wenn `kTrue`: Commands gehen an `iiRef2SubWindow`. Wenn `kFalse`: Commands gehen an `ioCode` (Business-Logik). Wird von `$setControl2SubWindow()` gesetzt/zurueckgesetzt.
|
||||
|
||||
---
|
||||
|
||||
## Karte 6 | Kritisch
|
||||
**Q:** Was passiert in `wSubWindow.$construct`?
|
||||
**A:** 1) `Do inherited` (wBaseWindow-Init), 2) `Set reference iiRef2SubWindow` auf eigenes SubWindow-Feld, 3) `Set reference iiRef2Parent` auf pRef2Parent, 4) `$translateObjects`, 5) `icFormWindow` merken, 6) **`iiRef2Parent.$setControl2SubWindow(kTrue)`** = Kontrolle uebernehmen!, 7+8) Row/List-Namen setzen.
|
||||
|
||||
---
|
||||
|
||||
## Karte 7 | Kritisch
|
||||
**Q:** Was passiert in `wSubWindow.$destruct`?
|
||||
**A:** 1) `iiRef2Parent.$setControl2SubWindow(kFalse)` = Kontrolle ZURUECKGEBEN!, 2) `ilList.$define()` = Liste leeren, 3) `irRow.$define()` = Row leeren, 4) `irRowSearch.$define()` = Such-Row leeren. **Ohne diesen Code denkt der Parent das SubWindow existiert noch!**
|
||||
|
||||
---
|
||||
|
||||
## Karte 8 | Kritisch
|
||||
**Q:** Wie sieht das Command-Delegation-Pattern aus?
|
||||
**A:** Auf JEDEM Fenster identisch:
|
||||
```omnis
|
||||
If $cinst.ibControl2SubWindow
|
||||
Do iiRef2SubWindow.$cXxx() ## -> SubWindow
|
||||
Else
|
||||
Do $cinst.ioCode.$cXxx() ## -> Business-Logik
|
||||
End If
|
||||
```
|
||||
Gilt fuer: $cEdit, $cInsert, $cSave, $cCancel, $cDelete, $cPrint, $cAudit, $cNextVersion.
|
||||
|
||||
---
|
||||
|
||||
## Karte 9 | Wichtig
|
||||
**Q:** Was ist die bidirektionale Referenz-Kette?
|
||||
**A:** Jedes SubWindow hat `iiRef2Parent` (zeigt auf den Elter) UND der Elter hat `iiRef2SubWindow` (zeigt auf das Kind). So koennen Commands abwaerts und TabPane-Sperren aufwaerts fliessen.
|
||||
|
||||
---
|
||||
|
||||
## Karte 10 | Wichtig
|
||||
**Q:** Wie fliesst ein Edit-Command durch die Hierarchie?
|
||||
**A:** `wMainWindow.$cEdit` -> prueft `ibControl2SubWindow=kTrue` -> `wSubWindow.$cEdit` (Ebene 1) -> prueft `ibControl2SubWindow` -> entweder an Sub-SubWindow ODER an `ioCode.$cEdit()`. Der Command "sinkt" bis zur tiefsten aktiven Ebene.
|
||||
|
||||
---
|
||||
|
||||
## Karte 11 | Wichtig
|
||||
**Q:** Was macht `$closeRelatedWindow()` und wann wird es aufgerufen?
|
||||
**A:** Schliesst alle zugehoerigen Popup-Fenster. Wird auf `wMainWindow` IMMER VOR der Command-Delegation aufgerufen. Auf `wSubWindow` wird es NICHT aufgerufen - der Unterschied zwischen Main und Sub!
|
||||
|
||||
---
|
||||
|
||||
## Karte 12 | Wichtig
|
||||
**Q:** Wie funktioniert `$EnableTabPane`?
|
||||
**A:** SubWindow ruft `iiRef2Parent.$EnableTabPane($cinst.inEDMode)` auf -> Parent ruft `$cwind.$objs.TP.$enableTabPanes(pEDMode)` auf -> Tab-Reiter werden gesperrt/freigegeben. Die Sperre fliesst AUFWAERTS in der Hierarchie!
|
||||
|
||||
---
|
||||
|
||||
## Karte 13 | Wichtig
|
||||
**Q:** Wie heisst das TabPane-Objekt in Solution2 standardmaessig?
|
||||
**A:** `TP` - das ist Konvention! Zugriff ueber `$cwind.$objs.TP.$enableTabPanes(pEDMode)`.
|
||||
|
||||
---
|
||||
|
||||
## Karte 14 | Wichtig
|
||||
**Q:** Wie schliesst sich ein SubWindow?
|
||||
**A:** Es schliesst sich NICHT selbst! `wSubWindow.$closeWindow` delegiert an: `Do iiRef2Parent.$closeWindow()`. Der Parent entscheidet ueber das Schliessen des gesamten Fensters.
|
||||
|
||||
---
|
||||
|
||||
## Karte 15 | Mittel
|
||||
**Q:** Was ist `ioCode`?
|
||||
**A:** Das Business-Logik-Objekt (z.B. `oOrders`, `oOrderItems`). Es ist der "letzte Stopp" fuer Commands wenn kein aktives SubWindow existiert. Wird als Instanzvariable im Fenster definiert und enthaelt Methoden wie `$cEdit()`, `$cSave()`, `$cDelete()`.
|
||||
|
||||
---
|
||||
|
||||
## Karte 16 | Mittel
|
||||
**Q:** Was ist `icFormWindow`?
|
||||
**A:** Der Name des Formulars, der im `$construct` aus `pFormWiindow` (ja, mit Tippfehler im Original!) gesetzt wird. Wird fuer Pfad- und Rechtebestimmung (RBAC) verwendet.
|
||||
|
||||
---
|
||||
|
||||
## Karte 17 | Mittel
|
||||
**Q:** Wie weit kann die SubWindow-Verschachtelung gehen?
|
||||
**A:** Theoretisch unbegrenzt (rekursiv). Jedes SubWindow kann ein eigenes SubWindow-Feld haben. Praktisches Beispiel: `wOrders` (Main) -> `wOrder` (Sub, Details) -> `wOrderItems` (SubSub, Positionen). Typisch: 2-3 Ebenen.
|
||||
|
||||
---
|
||||
|
||||
## Karte 18 | Mittel
|
||||
**Q:** Was macht `$setControl2SubWindow(pBool)`?
|
||||
**A:** Setzt `ibControl2SubWindow` auf den uebergebenen Wert. Wird von SubWindows aufgerufen: `kTrue` in `$construct` (Kontrolle uebernehmen), `kFalse` in `$destruct` (Kontrolle zurueckgeben).
|
||||
|
||||
---
|
||||
|
||||
## Karte 19 | Mittel
|
||||
**Q:** Was macht `wOrder.$SubWindowSavesAttachments`?
|
||||
**A:** Prueft welches SubWindow aktiv ist (`iiRef2SubWindow.$classname`) und ruft je nach Typ verschiedene Save-Methoden auf. Zeigt: Man kann per `$classname` auf dem SubWindow verschiedene Aktionen ausloesen.
|
||||
|
||||
---
|
||||
|
||||
## Karte 20 | Mittel
|
||||
**Q:** Was ist der Unterschied bei Cross-Library-Vererbung?
|
||||
**A:** Innerhalb der `solution2`-Library: `wSubWindow` reicht. Aus anderen Libraries (Sales, Manufacturing, etc.): `solution2.wSubWindow` mit Library-Prefix noetig! Beispiel: `wOrder extends solution2.wSubWindow`.
|
||||
|
||||
---
|
||||
|
||||
## Karte 21 | Fortgeschritten
|
||||
**Q:** Was passiert wenn ein SubWindow die Kontrolle ABLEHNT?
|
||||
**A:** Es ruft sofort `$setControl2SubWindow(kFalse)` im `$construct` auf. Beispiel: `wWebPortal.$construct` macht `Do pRef2Parent.$setControl2SubWindow(kFalse)`. Das Fenster ist dann nur ein Anzeige-Panel ohne Command-Routing.
|
||||
|
||||
---
|
||||
|
||||
## Karte 22 | Fortgeschritten
|
||||
**Q:** Was macht `wOrderItems.$CallParentDoCommand`?
|
||||
**A:** Delegiert einen Command AUFWAERTS: `Do iiRef2Parent.$CallDoCommand`. Damit kann ein SubWindow seinen Parent bitten, einen bestimmten Command auszufuehren - die umgekehrte Richtung vom normalen Fluss!
|
||||
|
||||
---
|
||||
|
||||
## Karte 23 | Fortgeschritten
|
||||
**Q:** Was passiert wenn $destruct das `$setControl2SubWindow(kFalse)` vergisst?
|
||||
**A:** Das Elternfenster denkt, das SubWindow existiert noch (`ibControl2SubWindow = kTrue`). Alle Commands werden an eine tote Referenz geschickt -> "Method not found"-Fehler. Der haefigste SubWindow-Bug!
|
||||
|
||||
---
|
||||
|
||||
## Karte 24 | Fortgeschritten
|
||||
**Q:** Wie debuggt man Command-Routing-Probleme?
|
||||
**A:** 1) `Calculate lDebug as $cinst.ibControl2SubWindow` pruefen, 2) `iiRef2SubWindow` auf NULL pruefen, 3) Breakpoint in `$cEdit`/`$cCancel` des SubWindows setzen, 4) Pruefen ob `$construct` mit `Do inherited` aufgerufen wird, 5) Pruefen ob Superklasse korrekt ist (`wSubWindow` vs `wBaseWindow`).
|
||||
|
||||
---
|
||||
|
||||
## Karte 25 | Fortgeschritten
|
||||
**Q:** Was sind die 7 goldenen Regeln der Fensterprogrammierung?
|
||||
**A:** 1) `ibControl2SubWindow` bestimmt ALLES, 2) $construct baut die Kette auf (`inherited`!), 3) $destruct baut sie ab (Kontrolle zurueckgeben!), 4) Commands fliessen ABWAERTS, 5) TabPane-Sperren fliessen AUFWAERTS, 6) $closeWindow delegiert AUFWAERTS, 7) `ioCode` ist der letzte Stopp.
|
||||
|
||||
---
|
||||
|
||||
## Spaced Repetition Tracking
|
||||
|
||||
| Karte | Zuletzt | Naechste | Schwierigkeit |
|
||||
|-------|---------|----------|---------------|
|
||||
| (wird beim Ueben gefuellt) | | | |
|
||||
Laden …
Tabelle hinzufügen
Einen Link hinzufügen
In neuem Issue referenzieren