Dynamics NAV – Programmierung: Die Schleifentypen REPEAT-UNTIL, WHILE-DO, FOR-TO
Wie in jeder anderen Programmiersprache gibt es natürlich auch in C/AL, der Programmiersprache von Microsoft Dynamics NAV (Navision), verschiedene Arten der Schleifenanweisungen.
Diesen will ich mich in diesem Artikel widmen und aufzeigen, wie sie funktionieren und wo die Grenzen sind.
Zuerst einmal eine kleine Übersicht. In C/AL unterscheidet man zwischen 3 Schleifenarten:
- FOR-TO bzw. FOR-DOWNTO – Schleife
- WHILE-DO – Schleife
- REPEAT-UNTIL – Schleife
FOR-TO und FOR-DOWNTO – Schleife
Dies ist wohl der Klassiker unter den Schleifentypen. Trotzdem ist es aber auch gleich der Typ, der am seltensten Einsatz in Navision findet.
FOR I := 1 TO 1000 DO BEGIN
Anweisung;
Anweisung;
END;
Es ist auch möglich die Schleife von einem hohen Wert zu einem kleineren Wert herunter zu zählen. Hierfür wird in der FOR-Schleife das TO durch DOWNTO ersetzt.
FOR I := 1000 DOWNTO 1 DO BEGIN
Anweisung;
Anweisung;
END;
Im Gegensatz zu anderen Programmiersprachen wie C# oder VB.NET ist es aber nicht möglich, die Schrittweite zu beeinflussen. Diese verbleibt stets bei 1 bzw. -1.
WHILE-DO – Schleife
Dieser Schleifentyp beinhaltet die Abbruch-Bedingung am Anfang der Schleife.
WHILE I < 1000 DO BEGIN
Anweisung;
I := I + 1;
END;
Natürlich können mehrere Abbrechbedingungen miteinander mit logischen Operatoren wie AND und OR verknüpft werden. Dabei muss zudem auf eine korrekte Klammersetzung bei der Programmierung geachtet werden.
ExitLoop := FALSE;
WHILE ((I < 1000) OR (ExitLoop = TRUE)) DO BEGIN
Anweisung;
IF A = B THEN
ExitLoop := TRUE;
I := I + 1;
END;
REPEAT-UNTIL – Schleife
Die REPEAT-Until Schleife ist wohl der meist verwendete Schleifentyp in Navision/Microsoft Dynamcis NAV. Bei dieser Schleife steht die Abbruch-Bedingung am Ende.
IF x < y THEN BEGIN
REPEAT
x := x + 1;
a := a - 1;
UNTIL x = y;
b := x;
END;
Vor allem beim Durchlaufen von Datensätzen (Records) wird sie gerne eingesetzt. Hierbei ist die Abbruchbedingung das Ergebnis der NEXT-Funktion. Wenn der letzte Datensatz durchlaufen wurde, gibt diese eine 0 zurück.
IF Customer.FIND('-') THEN
REPEAT
Anweisung;
UNTIL Customer.NEXT = 0;
Auch hier ist eine Verkettung von Abbruch-Bedingungen durch logische Operatoren wie bei der WHILE-Schleife möglich.
Zusammenfassung
Im Gegensatz zu anderen Programmiersprachen sind die Schleifen in C/AL, allen voran die FOR-Schleife, nicht so mächtig. So gibt es keine Ausstiegsmöglichkeit aus den Schleifen (wie ein „Break“ in C# bzw. „Exit For“ in VB.NET) und auch keine flexible Schrittweite für die FOR-Schleife – Es gibt zwar ähnliche Ausdrücke, sie haben aber andere Auswirkungen. Aber das alles ist kein Beinbruch, da man diese Funktionalitäten auch anders, zum Beispiel über eine WHILE-Schleife, abbilden kann.
IF Customer.FIND(‚-‚) THEN
REPEAT
Anweisung;
UNTIL Customer.NEXT = 0;
Also das IF Customer.FIND(‚-‚) ist böse!
Das sollte nicht verwendet werden. Wenn man wissen will, ob Datensätze enthalten sind, empfiehlt sich:
IF NOT Customer.ISEMPTY THEN..
Danach sollte man, sofern man nicht mehr als 500 Datensätze erwartet:
Customer.FINDSET; // Parameter in der Hilfe nachschaun
Sollten es mehr sein, sollte man
Customer.FINDFIRST; verwenden.
Und statt Customer.FIND(‚+‘ / ‚-‚); sollte man immer Customer.FINDFIRST; bzw FINDLAST; verwenden.
Diese Befehle sind um einiges performanter.
Gruß
Björn
Hallo Björn,
naja, das ist so nicht ganz richtig 😉
FINDFIRST wird nur eingesetzt wenn man NUR den ersten Datensatz abfragen will. Es ist kein Ersatz für FIND(‚-‚). Ich will ja alle Datensätze (unabhängig von der Menge) durchlaufen, von daher entfällt FINDFIRST, über FINDSET kann man streiten 🙂
Gruß Carsten