Using the Continue Statement in AL Loops

If you’ve spent any time writing AL, you’ve probably written the same pattern dozens of times: loop through records, check a condition, and either skip the row or wrap the rest of the body inside a big if block. It works, but the indentation creeps up fast, and the intent gets buried.

The continue statement gives us a cleaner way to do that. It’s a small addition to the language, but it’s one of those quality-of-life improvements that make loops noticeably easier to read.

Diagram showing a loop where some iterations are skipped with the continue keyword

What Is the continue Statement?

continue skips the rest of the current iteration of a loop and jumps straight to the next one. The loop itself keeps running—only the remaining statements in the current pass are bypassed.

It works inside the usual AL loop constructs:

  • repeat ... until
  • while ... do
  • for ... do
  • foreach ... in ... do

Think of it as the counterpart to break. Where break exits the loop entirely, continue just says “I’m done with this one—move on.”

Why You Should Care

  • Flattens deeply nested if blocks inside loops
  • Makes filter/skip logic read top-to-bottom instead of inside-out
  • Reduces indentation, which tends to reduce bugs
  • Matches the pattern that developers coming from C#, JavaScript, and most other languages already expect

How It Works

A few things worth knowing before you sprinkle continue everywhere:

  • continue only affects the innermost loop it appears in. If you’re inside a nested loop, it won’t skip the outer loop’s iteration.
  • In a repeat ... until block over a record, you still need Next() to advance the cursor. continue does not call Next() for you—but because Next() is part of the loop condition pattern (e.g., until Customer.Next() = 0), the loop still moves forward correctly when you use it the typical way.
  • continue outside of a loop is a compile error.
  • It’s available in recent runtime versions of AL (rolled out as part of the 2025 release waves), so make sure your project’s runtime target supports it before using it.

Before: The Nested if Pattern

Here’s the kind of code we’ve all written. We want to process customer payments, but skip those that are blocked or have no balance.

if Customer.FindSet() then
    repeat
        if not Customer.Blocked then begin
            Customer.CalcFields("Balance (LCY)");
            if Customer."Balance (LCY)" <> 0 then begin
                // ... do the actual work here ...
                ProcessCustomer(Customer);
            end;
        end;
    until Customer.Next() = 0;

It works, but the meaningful line—ProcessCustomer(Customer)—is buried two levels deep. Add another condition, and you’re fighting the indentation.

What About break?

A quick reminder, since the two often get mentioned in the same breath: break is not a replacement for continue. break exits the loop entirely—the moment it runs, the loop is done and execution moves on to whatever comes after the until (or end). It’s the right tool when you’ve found what you were looking for and there’s no reason to keep iterating, but it’s the wrong tool when you just want to skip the current row.

// `break` stops the whole loop after the first match.
if Customer.FindSet() then
    repeat
        if Customer."No." = 'C00010' then begin
            ProcessCustomer(Customer);
            break; // we're done — don't look at any more customers
        end;
    until Customer.Next() = 0;

Before continue existed, there was no clean equivalent. If you wanted to skip a single iteration, you really had two choices:

  • Wrap the loop body in nested if blocks (the “Before” example above).
  • Extract the body into a procedure and exit early from that procedure when a guard condition is hit.

The procedure trick worked, but felt heavy for what should be a one-line “skip this row” decision. continue finally gives us that one-liner.

After: The continue Version

Same logic, rewritten with continue:

if Customer.FindSet() then
    repeat
        if Customer.Blocked.AsInteger() <> 0 then
            continue;

        Customer.CalcFields("Balance (LCY)");
        if Customer."Balance (LCY)" = 0 then
            continue;

        // The actual work is now at the top level of the loop body.
        ProcessCustomer(Customer);
    until Customer.Next() = 0;

The “skip” rules are listed up front, each one reads as a single sentence, and the real work lives at the natural indentation level. This is the pattern I reach for most often.

continue in Other Loop Types

It works the same way in foreach and for:

foreach Item in ItemList do begin
    if Item.Blocked then
        continue;

    if Item."Unit Price" = 0 then
        continue;

    UpdateItemPrice(Item);
end;
for i := 1 to 100 do begin
    if i mod 2 = 0 then
        continue;

    // Only odd numbers reach this line.
    ProcessOddNumber(i);
end;

Gotchas and Recommended Approach

  • Nested loops: continue skips only the innermost loop. If you need to skip an outer loop’s iteration, you’ll need a flag variable or to refactor the inner loop into its own procedure.
  • Don’t forget Next(): In a repeat ... until Rec.Next() = 0 block, the until clause still runs after continue, so the cursor advances normally. Just don’t accidentally write a loop that depends on a manual Next() call inside the body before the continue—the continue will skip past it.
  • Use it for guard clauses, not control flow gymnastics: continue shines when you’re filtering or short-circuiting at the top of the loop. If you’re using it deep in the middle of complex branching, the loop body is probably trying to do too much—consider extracting it into a procedure instead.
  • Runtime version: Confirm your app.json runtime target supports continue before using it in a project that needs to deploy to older environments.

Wrapping Up

continue is a small language feature, but it pays off every time you write a loop that has to skip some rows. The “guard clause” style—list the skip conditions at the top, then write the real work at one level of indentation—reads better, reviews better, and tends to be easier to extend.

If you’ve been waiting for AL to catch up to the loop patterns you use in other languages, this is one of those nice ones to finally have.

Learn more:

Note: The code and information discussed in this article are for informational and demonstration purposes only. Always test in a sandbox first. The continue statement is available starting with the AL runtime version introduced in the Microsoft Dynamics 365 Business Central 2025 release wave 1.

Permanent link to this article: https://www.dvlprlife.com/2026/05/using-the-continue-statement-in-al-loops/

Leave a Reply

Your email address will not be published.