Dentro de una rutina, frecuentemente existe la necesidad de repetir una secuencia o bloque de instrucciones por una cantidad de veces, en general desconocida. Esta necesidad requiere un comando que ejecute las instrucciones hasta que ocurra una condición que la interrumpa en el procesamiento. Este comando es WHILE ... ENDDO, que significa "ejecute siempre que". Este ejecuta repetidamente un bloque de instrucciones que esté contenido entre su inicio (WHILE) y su final (ENDDO) siempre que una determinada condición permanezca verdadera. Por ejemplo:
// Llamada a la función de cálculo FUNCTION Main() LOCAL aEstoque := { { 300, "S" }, { 900, "S" }, { 400, "N" }, { 150, "N" }, { 540, "N" } } LOCAL nReserva := 0 IF !EMPTY(aEstoque) ENDIF nReserva := CalcGrao(1900, aEstoque) RETURN NIL // Función de cálculo FUNCTION CalcGrao(nSacas, aAlmox) LOCAL nPos := 1 LOCAL nReserva := 0 LOCAL nSoma := 0 WHILE nPos <= LEN(aAlmox) .AND. nReserva < nSacas nSoma := nReserva + aAlmox[nPos, 1] IF nSoma <= nSacas nReserva := nSoma ELSE nReserva := nSacas ENDIF nPos++ ENDDO RETURN nReserva
A veces, es necesario interrumpir la ejecución de las instrucciones contenidas dentro del WHILE antes que se llegue al final. Para ello se utiliza el comando LOOP. Este comando permite la interrupción lógica del comando WHILE, volviendo el flujo de ejecución al inicio del mismo. Observe el siguiente ejemplo:
// Función de cálculo FUNCTION CalcGrao(nSacas, aAlmox) LOCAL nPos := 0 LOCAL nReserva := 0 LOCAL nSoma := 0 WHILE nPos < LEN(aAlmox) .AND. nReserva < nSacas nPos++ IF aAlmox[nPos, 2] == "N" LOOP ENDIF nSoma := nReserva + aAlmox[nPos] IF nSoma <= nSacas nReserva := nSoma ELSE nReserva := nSacas ENDIF ENDDO RETURN nReserva
Es decir, si el contenido de la 2ª información del array es "N", el programa regresará al inicio del WHILE y procesará el próximo elemento.Por lo tanto, los elementos con "N" no se considerarán en el procesamiento.
Otra manera de interrumpir la repetición del comando WHILE es por medio del comando EXIT (Salida). Este comando es semejante al LOOP. Sin embargo, en lugar de regresar al inicio del WHILE, se finaliza la ejecución de las instrucciones, saliendo del círculo de repetición del WHILE. De esta forma, la ejecución de las instrucciones continuará después del ENDDO. Por ejemplo:
// Función de cálculo FUNCTION CalcGrao(nSacas, aAlmox) LOCAL nPos := 0 LOCAL nReserva := 0 LOCAL nSoma := 0 WHILE nPos < LEN(aAlmox) .AND. nReserva < nSacas nPos++ IF aAlmox[nPos, 2] == "N" EXIT ENDIF nSoma := nReserva + aAlmox[nPos] IF nSoma <= nSacas nReserva := nSoma ELSE nReserva := nSacas ENDIF ENDDO RETURN nReserva
Muchas veces, también es necesario repetir un bloque de instrucciones por una determinada cantidad de veces. Para atender esta necesidad, se requiere de un comando que ejecute un bloque de instrucciones de acuerdo con un contador que controle el número de veces en el cual éste se ejecutó y finalice la ejecución cuando se alcance este límite previsto. Este comando es FOR ... NEXT. Éste repite la ejecución del bloque de instrucciones que esté entre su inicio y su final hasta que un contador alcance su límite especificado, de acuerdo con determinado incremento. Por ejemplo:
FUNCTION CalcGrao(nSacas, aAlmox) LOCAL nPos := 0 LOCAL nReserva := 0 LOCAL nSoma := 0 FOR nPos := 1 TO LEN(aAlmox) nSoma := nReserva + aAlmox[nPos, 1] IF nSoma <= nSacas nReserva := nSoma ELSE nReserva := nSacas ENDIF NEXT nPos RETURN nReserva
Así como el comando WHILE, el comando FOR ... NEXT también acepta el comando EXIT, que interrumpe las repeticiones aunque el contador aún no haya llegado al límite especificado. Observe el siguiente ejemplo:
// Función de cálculo FUNCTION CalcGrao(nSacas, aAlmox) LOCAL nPos := 0 LOCAL nReserva := 0 LOCAL nSoma := 0 FOR nPos := 1 TO LEN(aAlmox) IF nReserva == nSacas .OR. aAlmox[nPos, 2] == "N" EXIT ENDIF nSoma := nReserva + aAlmox[nPos, 1] IF nSoma <= nSacas nReserva := nSoma ELSE nReserva := nSacas ENDIF NEXT nPos RETURN nReserva