📚 Qlik Sense Kurs – Artikel 16 von 28
← Vorheriger Artikel: Master Calendar erstellen
→ Nächster Artikel: Expressions Optimization
Was ist IterNo()? Eine Counter-Funktion die in WHILE-Schleifen die aktuelle Iterations-Nummer zurückgibt (1, 2, 3…) – perfekt für Datum-Ranges, Sequenzen und Record-Expansion!
Was kannst du über IterNo() & AUTOGENERATE lernen?
Nach diesem Guide kannst Du:
- IterNo() + AUTOGENERATE + WHILE für Sequenzen nutzen
- Records expandieren (1 Projekt → N Monate)
- Komplexe kumulative Berechnungen durchführen
Zeitinvestment: 20 Min Lesen + 3 Std Hands-on
Voraussetzung: Grundlegende Qlik-Kenntnisse
Quick Win: In 10 Minuten verstehst Du das Power-Trio und kannst es einsetzen
Was ist das Power-Trio: IterNo() + AUTOGENERATE + WHILE?
Das Problem: Du brauchst eine Sequenz von 1 bis 1000, oder alle Tage zwischen zwei Daten, oder Du möchtest 1 Projekt-Record in 12 Monats-Records expandieren. Wie machst Du das in Qlik?
Die Lösung: Das Power-Trio IterNo() + AUTOGENERATE + WHILE!
Wie generiere ich eine Sequenz mit IterNo() und AUTOGENERATE?
// Sequenz 1-10
Simple_Sequence:
LOAD
IterNo() as Counter,
IterNo() * 10 as Value
AUTOGENERATE 1
WHILE IterNo() <= 10;
Erklärung Schritt für Schritt:
- AUTOGENERATE 1: Startet mit einem leeren Record (wie ein Startpunkt)
- IterNo(): Zählt automatisch: 1. Iteration = 1, 2. Iteration = 2, 3. Iteration = 3, …
- WHILE IterNo() <= 10: Wiederholt solange IterNo() kleiner-gleich 10 ist
- IterNo() * 10: Jede Iteration kann Berechnungen mit IterNo() machen
Ergebnis:
Counter | Value
1 | 10
2 | 20
3 | 30
...
10 | 100
Wie generiert man eine ID-Sequenz mit IterNo() und AUTOGENERATE?
// ID-Sequenz mit formatiertem Code
ID_Sequence:
LOAD
IterNo() as SequenceID,
'ITEM-' & Num(IterNo(), '00000') as ItemCode,
IterNo() * 10 as Value
AUTOGENERATE 1
WHILE IterNo() <= 1000;
Erklärung:
- Num(IterNo(), ‚00000‘): Formatiert IterNo() mit führenden Nullen (1 → «00001», 25 → «00025»)
- ‚ITEM-‚ & …: Fügt Präfix hinzu
Ergebnis:
SequenceID | ItemCode | Value
1 | ITEM-00001 | 10
2 | ITEM-00002 | 20
...
1000 | ITEM-01000 | 10000
Performance: 10,000 Iterationen = <1 Sekunde! Sehr effizient bis ~100k Records.
Wie funktioniert die Record Expansion: 1 Record → N Records?
Ein super-mächtiges Pattern: 1 Projekt mit 5 Monaten Laufzeit → 5 Records (1 pro Monat)!
// Source: Projekte mit Start/Ende
Projects:
LOAD
ProjectID,
ProjectName,
Date(StartDate) as StartDate,
Date(EndDate) as EndDate,
(Year(EndDate) - Year(StartDate)) * 12 +
(Month(EndDate) - Month(StartDate)) + 1 as DurationMonths,
MonthlyBudget
FROM [DataProjects.xlsx]
(ooxml, embedded labels);
Erklärung der DurationMonths Berechnung:
- Start: Jan 2023, Ende: Mai 2023
- (2023 – 2023) * 12 = 0
- (5 – 1) = 4
- 0 + 4 + 1 = 5 Monate
// Expansion: Ein Record pro Monat
Projects_Expanded:
LOAD
ProjectID,
ProjectName,
Date(AddMonths(StartDate, IterNo() - 1), 'MMM-YYYY') as MonthDate,
IterNo() as MonthNumber,
MonthlyBudget,
MonthlyBudget * IterNo() as CumulativeBudget
RESIDENT Projects
WHILE IterNo() <= DurationMonths;
DROP TABLE Projects;
Erklärung der Expansion:
- RESIDENT Projects: Für JEDEN Record in Projects…
- WHILE IterNo() <= DurationMonths: …erstelle DurationMonths Records
- AddMonths(StartDate, IterNo() – 1): 1. Iteration = StartDate + 0 Monate, 2. Iteration = StartDate + 1 Monat, usw.
- MonthlyBudget * IterNo(): Kumulatives Budget (Monat 1 = 10k, Monat 2 = 20k, …)
Vorher:
ProjectID | ProjectName | StartDate | DurationMonths | MonthlyBudget
P001 | Website | 2023-01-01 | 5 | 10000
Nachher:
ProjectID | ProjectName | MonthDate | MonthNumber | MonthlyBudget | CumulativeBudget
P001 | Website | Jan-2023 | 1 | 10000 | 10000
P001 | Website | Feb-2023 | 2 | 10000 | 20000
P001 | Website | Mär-2023 | 3 | 10000 | 30000
P001 | Website | Apr-2023 | 4 | 10000 | 40000
P001 | Website | Mai-2023 | 5 | 10000 | 50000
Use Case: Budget-Verteilung, Projekt-Planung, Ressourcen-Allocation über Zeit!
Wie funktionieren kumulative Berechnungen bei Loan Amortization?
Ein komplexeres Beispiel: Tilgungsplan für Kredite berechnen.
// Loan Parameters
Loans:
LOAD
LoanID,
CustomerID,
Principal, // Kreditsumme
AnnualInterestRate, // Jahreszins (z.B. 0.05 = 5%)
LoanTermMonths, // Laufzeit in Monaten
Principal * (AnnualInterestRate / 12) /
(1 - Power(1 + AnnualInterestRate / 12, -LoanTermMonths)) as MonthlyPayment
FROM [DataLoans.xlsx]
(ooxml, embedded labels);
Erklärung MonthlyPayment: Standard-Annuitätenformel für gleiche monatliche Raten.
// Amortization Schedule
Amortization:
LOAD
LoanID,
CustomerID,
IterNo() as PaymentNumber,
AddMonths(Date(Today()), IterNo() - 1) as PaymentDate,
// Restschuld
If(IterNo() = 1,
Principal,
RangeSum(Peek('RemainingBalance'), -Peek('PrincipalPayment'))) as RemainingBalance,
// Zinszahlung für diesen Monat
If(IterNo() = 1,
Principal * (AnnualInterestRate / 12),
Peek('RemainingBalance') * (AnnualInterestRate / 12)) as InterestPayment,
// Tilgung für diesen Monat
MonthlyPayment - If(IterNo() = 1,
Principal * (AnnualInterestRate / 12),
Peek('RemainingBalance') * (AnnualInterestRate / 12)) as PrincipalPayment,
MonthlyPayment
RESIDENT Loans
WHILE IterNo() <= LoanTermMonths
ORDER BY LoanID, IterNo();
DROP TABLE Loans;
Erklärung der Logik:
- Peek(‚RemainingBalance‘): Holt den Wert aus der vorherigen Zeile
- RemainingBalance: Vorherige Restschuld – Tilgung = neue Restschuld
- InterestPayment: Restschuld * Monatszins
- PrincipalPayment: Monatliche Rate – Zinsen = Tilgung
Ergebnis für einen 100.000€ Kredit über 24 Monate bei 5% Zins:
PaymentNumber | PaymentDate | InterestPayment | PrincipalPayment | RemainingBalance | MonthlyPayment
1 | 2024-10-01 | 416.67 | 3,971.50 | 96,028.50 | 4,388.17
2 | 2024-11-01 | 400.12 | 3,988.05 | 92,040.45 | 4,388.17
3 | 2024-12-01 | 383.50 | 4,004.67 | 88,035.78 | 4,388.17
...
24 | 2026-09-01 | 18.12 | 4,370.05 | 0.00 | 4,388.17
Power-Tipp: Peek() greift auf vorherige Records zu – perfekt für kumulative Berechnungen!
Was ist der Unterschied zwischen IterNo(), RecNo() und RowNo()?
Drei ähnliche Funktionen – aber unterschiedliche Zwecke!
| Funktion | Wo verwendet | Wert |
|---|---|---|
| IterNo() | In WHILE-Loops | Iterations-Nummer (1, 2, 3…) |
| RecNo() | Beim Laden aus Source | Zeilen-Nummer in Quelle (1, 2, 3…) |
| RowNo() | Im Ergebnis | Zeilen-Nummer nach Filtern (1, 2, 3…) |
// Beispiel: Unterschied RecNo() vs RowNo()
Data:
LOAD
RecNo() as SourceRow, // Zeile im File
RowNo() as ResultRow, // Zeile im Ergebnis
Field1,
Field2
FROM Data.txt
WHERE Field1 > 100; // Filter!
// Wenn File 10 Zeilen hat, aber nur 3 erfüllen den Filter:
// SourceRow (RecNo): 2, 5, 8 <- Original-Positionen
// ResultRow (RowNo): 1, 2, 3 <- Positions im Ergebnis
Was sind die Best Practices und häufige Fehler bei IterNo() & AUTOGENERATE?
⚠️ Fehler 1: Endlosschleifen
Symptom: Qlik lädt endlos, App friert ein.
Falsch:
// GEFÄHRLICH: Keine Obergrenze!
LOAD
IterNo() as ID,
Peek('Value') + 1 as Value
AUTOGENERATE 1
WHILE Peek('Value') < 1000000; // Was wenn nie erreicht?
Richtig:
// SICHER: Max-Iterations-Limit
LOAD
IterNo() as ID,
Peek('Value') + 1 as Value
AUTOGENERATE 1
WHILE IterNo() <= 10000 AND Peek('Value') < 1000000; // Stoppt spätestens bei 10k
⚠️ Fehler 2: ORDER BY vergessen bei Peek()
Symptom: Kumulative Berechnungen sind falsch.
Problem: Peek() greift auf vorherige Zeile zu – aber in welcher Reihenfolge?
Falsch:
// Unsortiert!
LOAD
Date,
Amount,
RangeSum(Peek('Total'), Amount) as Total
RESIDENT Sales
WHILE IterNo() <= NoOfRows('Sales');
Richtig:
// Mit ORDER BY!
LOAD
Date,
Amount,
RangeSum(Peek('Total'), Amount) as Total
RESIDENT Sales
WHILE IterNo() <= NoOfRows('Sales')
ORDER BY Date ASC; // Wichtig für korrekte Reihenfolge!
Was sind die nächsten Schritte für IterNo() & AUTOGENERATE?
Du kannst jetzt Sequenzen generieren und Records expandieren! Als nächstes:
1. Master Calendar: Praktische Anwendung von IterNo(). Master Calendar erstellen zeigt’s im Detail.
2. Expressions: Jetzt wo Du Daten generieren kannst, optimiere die Analysen. Expressions Optimization ist der nächste Schritt.
Welche verwandten Themen gibt es im Kurs zu IterNo() & AUTOGENERATE?
- Master Calendar erstellen – Praktische Anwendung von IterNo()
- Zeitbasierte Daten – IntervalMatch – Kombiniert mit Calendar