For...End for

4D - Documentation   Français   English   German   Español   4D v11 SQL, Comandos por temas   4D v11 SQL, Lista alfabética de comandos   4D v11 SQL, Constantes por temas   Regresar   Anterior   Siguiente

versión 6.0


La sintaxis formal de la estructura de flujo de control For...End for es:

   For (Variable_Contador; Expresion_Inicio; Expresion_Fin {; Expresion_Incremento})
      instrucción(es)
   End for

El bucle For...End for es un bucle controlado por una variable contador:

La variable contador Variable_Contador es una variable numérica (Real, Entero, o Entero largo) que el bucle For...End for inicializa en el valor especificado por Expresion_Inicio.

Cada vez que el bucle se ejecuta, el valor del contador se incrementa en el valor especificado por el parámetro opcional Expresion_Incremento. Si no especifica Expresion_Incremento, la variable contador se incrementará por defecto en uno (1).

Cuando el contador alcanza el valor de Expresion_Fin , el bucle se detiene.

Importante: las expresiones numéricas

Expresion_Inicio
,
Expresion_Fin 
y
Expresion_Incremento 
son evaluadas una sola vez al comienzo del bucle. Si estas expresiones son variables, su modificación al interior del bucle no afectará el bucle.

Tip: sin embargo, con fines especiales, puede modificar el valor de la variable

Variable_Contador 
dentro del bucle; esto afectará el bucle.

Generalmente Expresion_Inicio es menor que Expresion_Fin .

Si Expresion_Inicio y Expresion_Fin son iguales, el bucle será ejecutado sólo una vez.

Si Expresion_Inicio es mayor que Expresion_Fin, el bucle no se ejecutará a menos de que Expresion_Incremento sea negativo. Ver ejemplos.

Ejemplos básicos

1. El siguiente ejemplo ejecuta 100 iteraciones:

   For (vContador;1;100)
      ` Hacer algo
   End for

2. El siguiente ejemplo va a través de todos los elementos del Array unArray:

   For ($vlElem;1;Size of array(unArray))
         ` Hacer algo con el elemento
      unArray{$vlElem}:=...
   End for

3. El siguiente ejemplo va a través de todos los caracteres del texto vtTexto:

   For ($vlCar;1;Length(
vtTexto
))
         ` Hacer algo con el carácter si es un TAB
      If (Character code(
vtTexto
[[$vlCar]])=Char(Tab))
         ` ...
      End if
   End for

4. El siguiente ejemplo va a través de los registros seleccionados para la tabla [unaTabla]:

   FIRST RECORD([
unaTabla
])
   For ($vlRegistro;1;Records in selection([
unaTabla
]))
         ` Hacer algo con el registro
      SEND RECORD([
unaTabla
])
         ` ...
         ` Ir al siguiente registro
      NEXT RECORD([
unaTabla
])
   End for

La mayoría de los bucles For...End for que usted escriba en sus bases se verán como los que presentamos en estos ejemplos.

Disminuir la variable contador

En algunos casos, podría querer tener un bucle cuyo contador disminuya en lugar de aumentar. Para hacer esto,

Expresion_Inicio 
debe ser mayor que Expresion_Fin y Expresion_Incremento debe ser negativo. Los siguientes ejemplos efectúan las mismas tareas que los ejemplos anteriores, pero en orden inverso:

5. El siguiente ejemplo ejecuta 100 iteraciones:

   For (vCounter;100;1;-1)
      ` Hacer algo
   End for

6. El siguiente ejemplo va a través de todos los elementos del Array unArray:

   For ($vlElem;Size of array(anArray);1;-1)
         `Hacer algo con el elemento
      unArray{$vlElem}:=...
   End for

7. El siguiente ejemplo va a través de todos los caracteres de texto vtTexto:

   For ($vlCar;Length(
vtTexto
);1;-1)
         ` Hacer algo con el carácter si es un TAB
      If (Ascii(
vtTexto
[[$vlCar]])=Char(Tab))
         ` ...
      End if
   End for

8. El siguiente ejemplo va a través de los registros seleccionados de la tabla [unaTabla]:

   LAST RECORD([
unaTabla
])
   For ($vlRecord;Records in selection([
unaTabla
]);1;-1)
         ` Hacer algo con el registro
      SEND RECORD([
unaTabla
])
         ` ...
         ` Ir al registro anterior
      PREVIOUS RECORD([
unaTabla
])
   End for

Incrementar la variable contador en más de uno

Si necesita esto, puede utilizar en Expresion_Incremento un valor (positivo o negativo) cuyo valor absoluto sera mayor que uno.

9. El siguiente bucle se dirigue sólo a los elementos pares del Array unArray:

   For ($vlElem;2;((Size of array(unArray)+1)\2)*2;2)
         ` Hacer algo con los elementos #2,#4...#2n
      unArray{$vlElem}:=...
   End for

Observe que la expresión ((Size of Array(unArray)+1)\2)*2 trata los arrays pares e impares.

Salir de un bucle cambiando la variable contador

En algunos casos, usted podría querer ejecutar un bucle un cierto número de veces, pero luego salir del bucle cuando otra condición sea TRUE. Para hacer esto, puede probar esta condición dentro del bucle y si es TRUE, explicitamente definir la variable contador en un valor superior al valor de la expresión final.

10. En el siguiente ejemplo, se efectúa un bucle entre los registros de una selección hasta llegar al final de la selección o hasta que la variable interproceso <>vbWeStop, inicialmente definida como FALSE, se vuelva TRUE. Esta variable se maneja por un método de proyecto ON EVENT CALL que le permite interrumpir la operación:

   <>vbWeStop:=False
   ON EVENT CALL ("GESTION STOP")
      ` GESTION STOP define <>vbStop como True si las teclas Ctrl-punto (Windows) o Cmd-Punto (Macintosh) son presionadas
   $vlNumRegistros:=Records in selection([unaTabla])
   FIRST RECORD([unaTabla])
   For ($vlRegistro;1;$vlNumRegistros)
         ` Hacer algo con el registro
      SEND RECORD([unaTabla])
         ` ...
         ` Ir al siguiente registro
      If (<>vbWeStop)
         $vlRecord:=$vlNbRecords+1 ` Forzar a la variable contador a salir del bucle
      Else
         NEXT RECORD([unaTabla])
      End if
   End for
   ON EVENT CALL("")
   If (<>vbStop)
      ALERT("La operación ha sido interrumpida.")
   Else
      ALERT("La operación ha terminado con éxito.")
   End if

Comparación de estructuras de bucle

Regresemos al primer ejemplo For...End for:

El siguiente ejemplo ejecuta 100 iteraciones:

   For (vCounter;1;100)
      ` Hacer algo
   End for

Es interesante ver cómo los bucles While...End while y Repeat...Until realizan la misma acción.

Este es el bucle While...End while equivalente :

   $i := 1 ` Inicialización del contador
   While ($i<=100) ` Bucle 100 veces
      ` Hacer algo
      $i := $i + 1 ` Hay que incrementar el contador
   End while

Este es el bucle Repeat...Until equivalente:

   $i := 1 ` Inicialización del contador
   Repeat
      ` Hacer algo
      $i := $i + 1 ` Hay que incrementar el contador
   Until ($i=100) ` Bucle 100 veces

Consejo: el bucle For...End for es generalmente más rápido que los bucles While...End while y Repeat...Until , porque 4D prueba la condición internamente para cada ciclo del bucle e incrementa el contador. Por lo tanto, utilice la estructura For...End for cada vez que sea posible.

Optimizar la ejecución de For...End for

Puede utilizar como contador una variable interproceso, proceso o local de tipo Real, Entero, y Entero largo. Para bucles largos, especialmente en modo compilado, utilice variables locales de tipo entero largo.

11. Este es un ejemplo:

   C_LONGINT($vlContador)   ` uso de una variable local de tipo entero largo
   For ($vlContador;1;10000)
      ` Hacer algo
   End for

Estructuras For...End for de bucles anidados

Usted puede anidar tantas estructuras de control como necesite. Esto incluye anidamiento de bucles For...End for. Para evitar errores, asegúrese de utilizar una variable contador diferente para cada estructura de bucle

Estos son dos ejemplos:

12. El siguiente ejemplo va a través de todos los elementos de un Array de dos dimensiones:

   For ($vlElem;1;Size of array(unArray))
         ` ...
         ` Hacer algo con la fila
         ` ...
      For ($vlSubElem;1;Size of array(unArray{$vlElem}))
         ` Hacer algo con el elemento
         unArray{$vlElem}{$vlSubElem}:=...
      End for
   End for

13. El siguiente ejemplo construye un Array de punteros para todos los campos de tipo Fecha presentes en la base:

   ARRAY POINTER($apCamposFecha;0)
   $vlElem:=0
   For ($vlTabla;1;Count table)
      For($vlCampo;1;Count fields($vlTabla))
         $vpCampo:=Field($vlTabla;$vlCampo)
         If (Type($vpCampo->)=Is Date)
            $vlElem:=$vlElem+1
            INSERT IN ARRAY($apCamposFecha;$vlElem)
            $apCamposFecha{$vlElem}:=$vpCampo
         End if
      End for
   End for

Ver también

Case of...Else...End case, Condiciones y bucles, If...Else...End if, Repeat...Until, While...End while.


4D - Documentation   Français   English   German   Español   4D v11 SQL, Comandos por temas   4D v11 SQL, Lista alfabética de comandos   4D v11 SQL, Constantes por temas   Regresar   Anterior   Siguiente