Recorrer fila a fila una tabla II: como hacerlo?

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 !

Acerca de pparnisari
Casi 44 vueltas al sol. Licenciado en sistemas. Curioso, investigador, excelente para resolver problemas prácticos. Casado, 2 hijos, cada vez con mas preguntas y respuestas mas en duda. Almost 44 laps to the sun. System engineer. Curious, researcher, great for solving practical problems. Married, 2 children, each time with more questions and more answers in doubt.

Deja un comentario