Loops

Karl Falconer ·

A for loop runs a block of code once for each item in a collection. It’s how you do something to every line item, every shipment line, every comment, etc.

for order_lines in order
  set order_line.custom.note to "Processed"
end

For each line item on the order, this sets that line’s note field. The loop variable inside the block is the singular form (order_line) of the collection name (order_lines).

If you’ve used a spreadsheet: A for loop is like applying a formula to every row in a column. The collection is the column; the body is the formula.

The shape

for collection in model
  body
end
Part Example Meaning
collection order_lines The name of the collection on the model.
model order The model that owns the collection.
body set order_line.custom.note to "..." What to do with each item. Inside, refer to the current item by its singular name (order_line).

Conditional actions in a loop

Combine with when to act only on some items:

for order_lines in order
  when order_line.sku starts_with "HAZMAT-" then
    set order_line.custom.requires_signature to true
  end
end

For every line item, if its SKU starts with “HAZMAT-“, flag it.

Nested loops

Loops nest naturally. A common pattern: iterate line items, then iterate something inside each line.

for order_lines in order
  for inventories in order_line
    when inventory.available > 0 then
      route order_line to warehouse inventory.warehouse_id
    end
  end
end

The inner loop iterates each order_line’s inventories collection. Variables inside refer to whatever loop they’re in — order_line for the outer, inventory for the inner.

Iterating regex matches in text

There’s a second form of for that iterates over the parts of a string that match a regex:

for /(?<num>\d+)/ in order.notes
  print "Found number: " & num
end

For every group of digits found in order.notes, the named capture (num) is bound, and the body runs once with that capture available.

This is the only way to “split” a string in BGL — there’s no split function.

What’s available inside a loop

  • The loop variableorder_line, inventory, etc.
  • The outer modelorder is still accessible inside for order_lines in order.
  • Session variables — see Variables.

What’s not available

BGL doesn’t support:

  • break or continue — you can’t exit a loop early or skip iterations. To approximate “stop after first match”, use a session variable as a flag:
    set $found to false
    for order_lines in order
      when not $found and order_line.sku is "TARGET" then
        set $found to true
        # do the work
      end
    end
    
  • An index variable — there’s no built-in way to know “I’m on the third item”. Use indexed access (order_lines[2].sku) when you need a specific position. See Collections and Source Data.
  • take(n) — you can’t limit a loop to the first N items. The full collection always iterates.

Common collections you can loop over

Model Collections
order order_lines
order_line inventories, options, comments
shipment shipment_lines
purchase_order purchase_order_items
sales_order_return sales_order_return_items

Loop vs quantifier vs accumulate

Three different things you might want to do with a collection:

  • Run an action on each item — use for ... end.
  • Ask a yes/no question about the collection — use a quantifier (order has any|all|none ...).
  • Compute a sum/count/joined string across items — use accumulate.
Was this article helpful?
0 out of 0 found this helpful

Comments

0 comments

Please sign in to leave a comment.