Recorrido de filas de una tabla
Con lo que dices me da la impresión de que no está claro el diagrama de flujo.
En un sistema de datos relacionales (como FoxPro), en los archivos de transacciones no estás repitiendo características que están en las tablas relacionadas. Por ejemplo, en la tabla de cabecera de facturas, no pones el nombre del cliente, porque ese dato se busca, cuando se necesita, en la tabla de clientes. Por lo tanto irá el identificador solamente. En la tabla de detalle de productos vendidos, se coloca el identificador de cliente para poder obtener información de qué clientes compraron qué cosa. En ambas tablas va la fecha de operación porque te permite determinar rápidamente facturas entre fechas (cabecera) o productos vendidos entre fechas (detalle). Si te interesa saber qué empleado vendió qué cosa, también irá el identificador de empleado en la tabla de detalle. En la tabla de cabecera te será útil incluir el identificador de empleado si tienes que liquidar comisiones por totales de factura. En ninguna de las dos va el nombre del empleado.
Independientemente de la finalidad de la aplicación, cualquier módulo que pretenda registrar ventas, tendrá dos tablas de corrida: cabecera de facturas y detalle de productos vendidos. Y las tablas de base (clientes, empleados, rubros, productos, marcas, etc) que sirven de apoyo.
Si utilizas una sola tabla en la que tienes todos los datos, te resultará un pandemonio sacar un libro de ventas o cualquier tipo de información que no se refiera a productos vendidos.
El planteo es más o menos así:
Supongamos que
la tabla de cabecera se llama "Facturas"
la tabla de detalle de productos vendidos se llama "Produven".
la tabla de productos se llama PRODUCTOS y tiene un índice sobre el campo "Codigo" llamado "CODPROD" (INDEX ON CODIGO TAG CODPROD)
Un método que puede utilizarse, es crear dos cursores basados en estas tablas y luego actualizar las tablas. Esto para no complicarte con Buffering.
IF !USED("CABECERA")
SELECT * FROM FACTURAS WHERE .F. INTO CURSOR CABECERA
ENDIF
IF !USED("DETALLE")
SELECT * FROM PRODUVEN WHERE .F. INTO CURSOR DETALLE
ENDIF
Con esto generaste dos cursores con la estructura de las tablas y sin registros.
Ahora bien, la interfase tiene que rellenar los cursores. El cursor DETALLE va asociado al control grid y en él ingresas los productos vendidos (codigo, descripción, cantidad, precio, importe, etc)
En la interfase tienes que estar tomando: Fecha de operación, comprador, condición de venta, número de comprobante, ETC.
Cuando terminas de rellenar el formulario con los datos de productos vendidos (o sea, agregas datos al cursor DETALLE), comprador, empleado vendedor, condición de venta, etc, , se puede Grabar o Cancelar.
Si cancelas la operación, saltas al punto 7 y limpias la interfase.
Si grabas la operación, seguirás la secuencia :
Antes de grabar, tendrás que tener algún elemento de validación:
* Que no falte el código de cliente, la fecha, número de comprobante, código de empleado vendedor, si la factura suma más que cero (o si es nota de crédito), etc.
* EJEMPLO
SELECT DETALLE
GO TOP
IF EOF()
MESSAGEBOX("No ha vendido nada")
RETURN
ENDIF
select CABECERA
if Empty(CODIGO_CLIENTE)
Messagebox("No indicó el comprador")
Thisfrom.Command1.setfocus
RETURN
ENDIF
1) Obtienes el número de comprobante (siempre justo antes de grabar).
2) Rellenas el cursor DETALLE con fecha, número de comprobante, código de cliente, Código Empleado, etc.
3) Sumas los campos de importe (pueden ser gravado, no gravado, exento, iva, etc.)
4) rellenas el cusor CABECERA (1 solo registro) con código de cliente, fecha, número de comprobante, condición de venta, etc, y los totales obtenidos del cursor DETALLE.
5) grabar en FACTURAS (CABECERA)
SELECT CABECERA
SCATTER MEMVAR
INSERT INTO FACTURAS FROM MEMVAR
6) grabar en PRODUVEN (DETALLE) [detalle de productos vendidos] y actualizar inventario
SELECT DETALLE
SCAN
SCATTER MEMVAR
if indexseek(detalle.codigo,.f.,"PRODUCTOS","CODPROD")
SELECT PRODUCTOS
INDEXSEEK(detalle.codigo,.T.,"PRODUCTOS","CODPROD")
IF RLOCK()
REPLACE CANTIDAD WITH CANTIDAD - DETALLE.CANTIDAD
UNLOCK
ENDIF
ENDIF
INSERT INTO PRODUVEN FROM MEMVAR
ENDSCAN
UNLOCK IN FACTURAS
UNLOCK IN PRODUVEN
FLUSH
7) LIMPIO CURSORES
SELECT DETALLE
ZAP
SELECT CABECERA
ZAP
Tómate un tiempo para hacer un buen diseño de datos y luego un diagrama de flujo. Te simplificará mucho el desarrollo. Lo esencial es plantear adecuadamente el problema. Para ello debes tener en cuenta, como mínimo, lo siguiente:
a) datos que deben conservarse obligatoriamente (motivos legales, reglamentarios, etc.)
b) información requerida por los usuarios (estadísticas de ventas de diversos tipos)
Teniendo un detalle completo de estos aspectos, podrás diseñar las tablas como para poder recuperar la información que se necesita suministrar.
Resuelto el diseño y el flujo de datos, será la hora de diseñar la interfase para que responda a todas las necesidades planteadas.