Recorrer fila a fila una tabla II: como hacerlo?
10/02/2011 Deja un comentario
Siguiendo con el ejemplo del flujo de caja de tesorería ahora que la tabla ya está ordenada por la fecha vamos a concentrarnos en recorrer iteratívamente la tabla sumando los ingresos y egresos de cada día y guardándolos en una tabla auxiliar.
Para esto vamos a usar dos instrucciones claves de script: PEEK y LOAD AUTOGENERATE. Va el código y luego la explicación (en gris código de la primera parte tratado en el anterior post):
Tesoreria: LOAD Fecha, Cuenta, Tipo, Monto FROM Tesoreria.xls (biff, embedded labels, table is Hoja1$); Tesoreria_Ordenada: NOCONCATENATE LOAD * RESIDENT Tesoreria ORDER By Fecha; Drop Table Tesoreria; LET vFechaAnterior = PEEK('Fecha', 0, 'Tesoreria_Ordenada'); // Obtiene la Fecha de la primera fila de la tabla LET vMontoAcumulado = 0; // Suponemos que el primer día de actividad comienza con $0 TotalesDia: LOAD 1 as Fecha AUTOGENERATE 1 WHERE 1=0; // Genero una tabla vacía con solo una columna Fecha LET vCantFilas = noofrows('Tesoreria_Ordenada'); FOR i = 0 TO vCantFilas - 1 // Repite el bucle tantas veces como filas tiene la tabla LET vFecha = PEEK('Fecha', $(i), 'Tesoreria_Ordenada'); //Obtiene la Fecha de la fila actual LET vMonto = PEEK('Monto', $(i), 'Tesoreria_Ordenada'); //Obtiene el Monto de la fila actual LET vTipo = PEEK('Tipo', $(i), 'Tesoreria_Ordenada'); //Obtiene el Tipo de la fila actual IF vFecha<>vFechaAnterior then // Cambió el día ! CONCATENATE (TotalesDia) // Graba un total para el dia anterior al actual LOAD '$(vFechaAnterior)' as Fecha, '$(vMontoAcumulado)' as TotalDia AUTOGENERATE 1; END IF LET vFechaAnterior = vFecha; LET vMontoAcumulado = vMontoAcumulado + ( vMonto * if (vTipo='Ingreso',1,-1) ); NEXT CONCATENATE (TotalesDia) // Guarda el último día LOAD '$(vFechaAnterior)' as Fecha, '$(vMontoAcumulado)' as TotalDia AUTOGENERATE 1;
Explicación:
El modificador «AUTOGENERATE 1» se emplea para generar una fila con los valores que se desee y almacenarla en una tabla.
Nosotros lo usamos al comienzo para generar una tabla vacía (where 1=0) que llamamos TotalesDia donde iremos concatenando las filas con los totales de cada día. También dentro del bucle FOR lo usamos cada vez que se detecta un cambio de día y debemos almacenar dicho total en la tabla creada, para lo cual en el post anterior nos ocupamos de ordenar la tabla por fecha ascendente.
Para recorrer fila a fila la tabla con los movimientos de Tesorería usamos NOOFROWS para dimensionar el bucle FOR, y PEEK que empleamos para obtener el valor de un campo determinado de una fila determinada, identificando a las filas por su posición dentro de la tabla: de 0 (cero) a «noofrows ()-1».
Finalmente usamos un IF(cond,x,y) ternario para que si el movimiento es un ingreso sume al total acumulado y si es un egreso reste al mismo, ya que los datos originales están todos expresados en valores absolutos.
Como resultado de su ejecución obtenemos:
Saludos y espero les sirva !