LoopsLoops execute a blocks of code a specified number of times, or while a specified condition is true. Miva Script provides three constructs for creating loops. Care must be taken to ensure an endless loop is not created. The Empresa engine will eventually time out, but the loop will consume server resources until that happens. The tag <MvWHILE> evaluates a condition at the beginning of the loop repeats the loop as long as the condition is true. It is the traditional loop construct and nearly all of the sample code you will find uses it. The <MvWHILESTOP> tag can be used to exit a loop at any time. New in 5.10: <MvFOR> allows you to loop through a block of code a specific number of times. Iif the number of loops is known in advance, this is often more to convenient to use than <MvWHILE> New in 5.10: <MvFOREACH> Is designed to make dealing with arrays of items more convenient. Each item in the array is represented in the loop as an iterator variable, simplifying the syntax. Optionally you can exit the loop using <MvFOREACHSTOP> NOTE: When combined with the -C (compatibility) compiler flag, MvFOREACH generates code that will run on any engine version 5.00 or newer, using runtime engine version checks to either call these functions or emulate their behavior. Syntax MvWHILEExample:<MvASSIGN name="g.counter" value="1">
<MvWHILE EXPR = "{ g.counter LE 10 }">
Execute the code here 10 times.
<MvASSIGN name="g.counter" value="{ g.counter + 1}">
</MvWHILE>
Breaking out of a loop. Loops can be ended manually using <MvWHILESTOP>, for example when an error is detected. Care must be taken to ensure an endless loop is not created. The Empresa engine will eventually time out, but the loop will consume server resources until that happens. In this example the code executes a fixed number of times. This also demonstrates a method of evaluating the condition at the end of the loop instead of the beginning. Example:<MvASSIGN name="g.counter" value="{ 1 }">
<MvWHILE EXPR = "{ 1 }">
Execute the code here.
<MvASSIGN name="g.counter" value="{ g.counter + 1}">
<MvIF EXPR="{ g.counter GT 100 }">
<MvWHILESTOP>
</MvIF>
</MvWHILE>
Often when processing data, the number of loops is often not know in advance so other conditions must be tested. In this example, l.fieldlist is a comma separated list of values and is output to the browser one line at a time. See MvWHILE for more information. Example:<MvASSIGN NAME="l.posn" VALUE="{ 1 }">
<MvASSIGN NAME="l.item" VALUE="{ gettoken(l.fieldlist,',',l.posn) }">
<MvWHILE EXPR="{ l.item }">
<MvEVAL EXPR="{ l.posn $ '. ' $ l.item }"><br>
<MvASSIGN NAME="l.posn" VALUE="{ l.posn + 1 }">
<MvASSIGN NAME="l.item" VALUE="{ gettoken(l.fieldlist,',',l.posn) }">
</MvWHILE>
Syntax MvFORWhen the number of loops is know in advance, <MvFOR> provides a much simpler syntax. The first example simply loops 100 times, the second outputs the numbers 1. through 100. Example:<MvFOR COUNT = "{ 100 }">
Execute the code here 100 times
</MvFOR>
<MvFOR INDEX = "l.pos" COUNT = "{ 100 }">
<MvEVAL EXPR = "{ l.pos }">. <br>
</MvFOR>
<MvFOR> also has more complex syntax available giving you enormous flexibility in controlling loops. You can skip numbers loop in reverse order (e.g. 100 to 1) and more. This example prints items 1, 3, 5, ... etc. in the first column and the items 2, 4, 6... etc in the second column. See MvFOR for more information. Example:<table><tr>
<td>
<MvFOR INDEX = "l.pos" FIRST = "{ 1 }" NEXT = "{ l.pos + 2 }" LAST = "{ 100 }">
<MvEVAL EXPR = "{ l.pos }">. <br>
</MvFOR>
</td>
<td>
<MvFOR INDEX = "l.pos" FIRST = "{ 2 }" NEXT = "{ l.pos + 2 }" LAST = "{ 100 }">
<MvEVAL EXPR = "{ l.pos }">. <br>
</MvFOR>
</td>
</tr></table>
Syntax MvFOREACHWhen looping through arrays of data <MvFOREACH> is the ideal tool. This example use <MvFOREACH> in it simplest form to output a number list of orders. The array l.orders is a structured copy of database records like this. l.orders[1]:Fname, l.orders[1]:Lname, During each loop the variable l.item is a reference to l.order[n] Example:<MvFOREACH ITERATOR = "l.item" ARRAY = "l.orders" INDEX = "l.pos">
<MvEVAL EXPR"{ l.pos }">. <MvEVAL EXPR"{ l.item:Fname }"> <MvEVAL EXPR"{ l.item:Lname }"><br>
</MvFOREACH>
<MvFOREACH> also has of the same attributes as MvFOR letting you loop forwards, backward, skip items, limit how many items to display and even set conditions which cause the loop to exit. See MvFOREACH for more information. |