Agrupación y bucles
Los comandos GROUP y LOOP ofrecen dos maneras de ejecutar una serie de comandos de manera reiterada. GROUP realiza una sola repetición de uno o más comandos con cada registro. LOOP realiza varias repeticiones de una serie de comandos con un solo registro y solo se puede usar dentro de un bloque GROUP.
Un ejemplo sencillo de GROUP
Usted tiene una tabla de datos de facturas denominada Trans_Cp. Con esta información, necesita calcular un total acumulado de importes de facturas:
| Número_proveedor | Nombre_proveedor | Número_factura | Fecha | Cantidad |
|---|---|---|---|---|
| 11663 | More Power Industries | 5981807 | 2000-11-17 | 618.30 |
| 13808 | NOVATECH Wholesale | 2275301 | 2000-11-17 | 6705.12 |
| 12433 | Koro International | 6585673 | 2000-11-17 | 7955.46 |
Para calcular este importe, utiliza el comando GROUP. Dentro de cada repetición de GROUP, usted:
- Calcula el total acumulado del registro actual.
- Extrae el número, el importe, la fecha y el total acumulado de las facturas a la tabla de resultados.
OPEN Ap_Trans
COMMENT set the initial value of running total to zero END
ASSIGN v_running_total = 0.00
COMMENT iterate over each record in the table and then calculate and extract the running total END
GROUP
ASSIGN v_running_total = v_running_total + Amount
EXTRACT Invoice_Number, Amount, Date, v_running_total AS "Running total" TO results1
END
Cuando se ejecuta el script, los comandos dentro del bloque GROUP se procesan en cada registro de la tabla, de arriba hacia abajo, y se calcula y extrae el total acumulado. Si pudiéramos observar el comando GROUP a medida que se ejecuta, se vería de este modo:
La primera iteración de GROUP: total acumulado = 0,00 + 618,30
El comando GROUP agrega el importe de la factura del primer registro al total acumulado inicial de 0,00 y extrae los campos a la tabla de resultados:
| Número_proveedor | Nombre_proveedor | Número_factura | Fecha | Cantidad |
|---|---|---|---|---|
| 11663 | More Power Industries | 5981807 | 2000-11-17 | 618.30 |
| 13808 | NOVATECH Wholesale | 2275301 | 2000-11-17 | 6705.12 |
| 12433 | Koro International | 6585673 | 2000-11-17 | 7955.46 |
La segunda iteración de GROUP: total acumulado = 618,30 + 6705,12
El comando GROUP agrega el importe de la factura del segundo registro al nuevo total acumulado de 618,30 y extrae los campos a la tabla de resultados:
| Número_proveedor | Nombre_proveedor | Número_factura | Fecha | Cantidad |
|---|---|---|---|---|
| 11663 | More Power Industries | 5981807 | 2000-11-17 | 618.30 |
| 13808 | NOVATECH Wholesale | 2275301 | 2000-11-17 | 6705.12 |
| 12433 | Koro International | 6585673 | 2000-11-17 | 7955.46 |
Tercera iteración de GROUP: total acumulado = 7323,42 + 7955,46
El comando GROUP agrega el importe de la factura del tercer registro al nuevo total acumulado de 7323,42 y extrae los campos a la tabla de resultados:
| Número_proveedor | Nombre_proveedor | Número_factura | Fecha | Cantidad |
|---|---|---|---|---|
| 11663 | More Power Industries | 5981807 | 2000-11-17 | 618.30 |
| 13808 | NOVATECH Wholesale | 2275301 | 2000-11-17 | 6705.12 |
| 12433 | Koro International | 6585673 | 2000-11-17 | 7955.46 |
Tabla de resultados final
Una vez que el comando GROUP haya procesado el registro final de la tabla, usted tendrá la siguiente tabla de resultados:
| Número_factura | Cantidad | Fecha | Total_acumulado |
|---|---|---|---|
| 5981807 | 618.30 | 2000-11-17 | 618.30 |
| 2275301 | 6705.12 | 2000-11-17 | 7323.42 |
| 6585673 | 7955.46 | 2000-11-17 | 15278.88 |
Manejo de diferentes casos con GROUP IF
Con la misma tabla Ap_Trans que antes, usted necesita calcular los totales acumulados de tres tipos de facturas:
- Valor elevado (mayor que o igual a 1000,00)
- Valor medio (entre 100,00 y 1000,00)
- Valor bajo (menos que 100,00)
El comando GROUP proporciona una estructura IF/ELSE para manejar los diferentes casos. Usted proporciona las expresiones condicionales para la prueba y, si un registro se evalúa como verdadero, se ejecutan los comandos dentro del bloque.
Cómo se prueban los casos
Los casos se prueban de arriba hacia abajo y un registro solo puede ser procesado por un bloque IF/ELSE. El primer caso que se evalúa como verdadero para el registro es el que lo procesa:
- Cuando GROUP procesa el primer registro, vuelve a probarlo con la primera condición IF (Amount >= 1000). Si esta condición se evalúa como verdadera, se ejecuta el código de este caso y no se prueba ningún otro.
- Si el primer caso se evalúa como falso, se prueba la siguiente condición ELSE IF (Amount >= 100). Del mismo modo, si esta condición se evalúa como verdadera, se ejecuta el código de este caso y no se prueba ningún otro.
- Por último, si ninguno de los caos IF o ELSE IF se evalúa como verdadero, el registro se procesa con el caso predeterminado del bloque ELSE.
Nota
Si un registro se evalúa como verdadero para más de un caso, el registro solo es procesado por el primer bloque IF/ELSE que lo prueba. Los registros nunca son procesados por más de un bloque IF/ELSE en un comando GROUP.
OPEN Ap_Trans
COMMENT set initial values for running totals END
ASSIGN v_running_total_hi = 0.00
ASSIGN v_running_total_med = 0.00
ASSIGN v_running_total_low = 0.00
COMMENT use GROUP IF to run different ASSIGN and EXTRACT commands depending on invoice amount END
GROUP IF Amount >= 1000
ASSIGN v_running_total_hi = v_running_total_hi + Amount
EXTRACT Invoice_Number, Amount, Date, v_running_total_hi AS "Running total" TO results_hi
ELSE IF Amount >= 100
ASSIGN v_running_total_med = v_running_total_med + Amount
EXTRACT Invoice_Number, Amount, Date, v_running_total_med AS "Running total" TO results_med
ELSE
ASSIGN v_running_total_low = v_running_total_low + Amount
EXTRACT Invoice_Number, Amount, Date, v_running_total_low AS "Running total" TO results_low
END
Al ejecutar el script, el comando GROUP prueba el importe de la factura de cada registro. Según el importe, el registro se utiliza para actualizar uno de los tres totales acumulados (bajo, medio o alto) y se generan tres tablas de resultados.
LOOP dentro de un comando GROUP
Al usar GROUP para procesar los registros de una tabla, puede usar un comando LOOP para ejecutar una serie de comandos varias veces en un único registro. LOOP es una segunda repetición que ocurre dentro de la repetición de GROUP y se ejecuta hasta que una condición de prueba que usted especifica se evalúa como falsa.
Uso de LOOP para dividir un campo
Usted tiene la siguiente tabla que contiene datos de facturas y necesita aislar información específica para los importes de facturas por departamento. Una factura puede estar relacionada con más de un departamento, y los códigos de los departamentos se almacenan en un formato delimitado por comas en la tabla:
| Número_proveedor | Número_factura | Fecha | Cantidad | Código_depto |
|---|---|---|---|---|
| 11663 | 5981807 | 2000-11-17 | 618.30 | CCD,RDR |
| 13808 | 2275301 | 2000-11-17 | 6705.12 | CCD |
| 12433 | 6585673 | 2000-11-17 | 7955.46 | CCD,LMO,RDR |
Para extraer los importes de las facturas por departamento, usted:
- Utiliza un comando GROUP para procesar la tabla registro por registro.
- Calcula la cantidad de departamentos (n) asociados con cada registro.
- Utilice el comando LOOP para repetir n veces en el registro a fin de extraer los datos de cada departamento asociado con el registro.
Nota
Debe incrementar la variable v_recuento dentro de LOOP. Si no lo hace, la prueba WHILE siempre se evalúa como verdadera y el script entra en un bucle infinito. Puede incluir el comando SET LOOP en sus scripts para evitar estos bucles infinitos. Si desea obtener más información, consulte Comando SET LOOP.
COMMENT
Use GROUP to count commas in each department code field as a way of identifying how many departments are associated with the record
"LOOP" over each record for each code in the field, with each iteration of the loop extracting the record with a single code to the result1 table
END
GROUP
v_department_count = OCCURS(Dept_Code,',')
v_counter = 0
LOOP WHILE v_counter <= v_department_count
v_dept = SPLIT(Dept_Code, ',', (v_counter + 1))
EXTRACT FIELDS Invoice_Number, Amount, v_dept AS "Department" TO result1
v_counter = v_counter + 1
END
END
Cuando se ejecuta el script, los comandos dentro del bloque GROUP se procesan en cada registro de la tabla, de arriba hacia abajo. Para cada registro, el comando LOOP se repite en el registro una vez por código de departamento en la lista delimitada por comas y, a continuación, extrae un registro. Si pudiéramos observar los comandos GROUP y LOOP a medida que se ejecutan, se verían de este modo:
Primera iteración de GROUP: 2 iteraciones de LOOP
| Número_proveedor | Número_factura | Fecha | Cantidad | Código_depto |
|---|---|---|---|---|
| 11663 | 5981807 | 2000-11-17 | 618.30 | CCD,RDR |
| 13808 | 2275301 | 2000-11-17 | 6705.12 | CCD |
| 12433 | 6585673 | 2000-11-17 | 7955.46 | CCD,LMO,RDR |
Para el primer registro de la tabla, el valor de v_recuento_departamentos es 1; por lo tanto, LOOP se repite dos veces:
- Para la primera repetición del LOOP:
- v_recuento = 0
- v_dept = CCD
Se extrae el siguiente registro y el valor de v_recuento se incrementa a 1; por lo tanto, se vuelve a repetir LOOP:
5981807 618.30 CCD - Para la segunda repetición de LOOP:
- v_recuento = 1
- v_dept = RDR
Se extrae el siguiente registro y el valor de v_recuento se incrementa a 2; por lo tanto, no se vuelve a repetir LOOP y el comando GROUP pasa al siguiente registro:
5981807 618.30 RDR
Segunda iteración de GROUP: 1 iteración de LOOP
| Número_proveedor | Número_factura | Fecha | Cantidad | Código_depto |
|---|---|---|---|---|
| 11663 | 5981807 | 2000-11-17 | 618.30 | CCD,RDR |
| 13808 | 2275301 | 2000-11-17 | 6705.12 | CCD |
| 12433 | 6585673 | 2000-11-17 | 7955.46 | CCD,LMO,RDR |
Para el segundo registro de la tabla, el valor de v_recuento_departamentos es 0; por lo tanto, LOOP se repite una vez:
- v_recuento = 0
- v_dept = CCD
Se extrae el siguiente registro y el valor de v_recuento se incrementa a 1; por lo tanto, no se vuelve a repetir LOOP y el comando GROUP pasa al siguiente registro:
| 2275301 | 6705.12 | CCD |
Tercera iteración de GROUP: 3 iteraciones de LOOP
| Número_proveedor | Número_factura | Fecha | Cantidad | Código_depto |
|---|---|---|---|---|
| 11663 | 5981807 | 2000-11-17 | 618.30 | CCD,RDR |
| 13808 | 2275301 | 2000-11-17 | 6705.12 | CCD |
| 12433 | 6585673 | 2000-11-17 | 7955.46 | CCD,LMO,RDR |
Para el tercer registro de la tabla, el valor de v_recuento_departamentos es 2; por lo tanto, LOOP se repite tres veces:
- Para la primera repetición de LOOP:
- v_recuento = 0
- v_dept = CCD
Se extrae el siguiente registro y el valor de v_recuento se incrementa a 1; por lo tanto, se vuelve a repetir LOOP:
6585673 7955.46 CCD - Para la segunda repetición de LOOP:
- v_recuento = 1
- v_dept = LMO
Se extrae el siguiente registro y el valor de v_recuento se incrementa a 2; por lo tanto, se vuelve a repetir LOOP:
6585673 7955.46 LMO - Para la tercera repetición de LOOP:
- v_recuento = 2
- v_dept = RDR
Se extrae el siguiente registro y el valor de v_recuento se incrementa a 3; por lo tanto, no se vuelve a repetir LOOP y el comando GROUP llega al final de la tabla:
6585673 7955.46 RDR
Tabla de resultados final
Una vez que el comando GROUP procesó cada registro de la tabla y que el comando LOOP se haya repetido para todos los códigos de departamentos, usted tendrá la siguiente tabla de resultados:
| Número_factura | Cantidad | Departamento |
|---|---|---|
| 5981807 | 618.30 | CCD |
| 5981807 | 618.30 | RDR |
| 2275301 | 6705.12 | CCD |
| 6585673 | 7955.46 | CCD |
| 6585673 | 7955.46 | LMO |
| 6585673 | 7955.46 | RDR |