Problema con un Grid y una Tabla...

68 views
Skip to first unread message

Gabriel Palmieri

unread,
Aug 25, 2016, 11:40:53 AM8/25/16
to Comunidad de Visual Foxpro en Español
Hola a todos, nuevamente me encuentro aquí ya que tengo una cuestión que no logro resolver y siempre logran encaminarme.

Me pidieron un trabajo, un negocio quería empezar a digitalizar unas Fichas de Reparación de automóviles, tengo una tabla donde guardo datos personal, repuestos, observaciones, mano de obra, etc.

Para la mayoría de los datos me sirvió con un Text donde escriban la información y listo, el problema llega cuando me piden lo siguiente, que en la parte en que cargan los repuestos, tornería y lubricantes, "aparezca una tablita como un excel" palabras textuales del cliente, y así el poder cargar un repuesto abajo del otro, al lado el código, cantidad y precio, en tornería otra tablita con la descripción y el costo, y para los lubricantes la descripción, cantidad de litros, código y precio.


Lo primero que se me vino a la cabeza es hacerle una grilla a Repuestos una a Tornería y una a Lubricantes, de la siguiente forma:




Ahora el problema que tengo es que no se como podría pasar la información de las grillas a la tabla, quizás me convenga otra cosa, porque cada vez que se cargue una ficha van a cambiar estos datos, y si quiero luego darle le posibilidad de modificar, tengo que mostrarle los datos en las grillas y darle la opción de que modifique.

Desde ya muchas gracias.

Gabriel Palmieri

unread,
Aug 25, 2016, 11:48:47 AM8/25/16
to Comunidad de Visual Foxpro en Español
Estaba probando, ejecuté y traté de agregar datos a los grid, no me deja agregar más de una linea y no se porqué se copian los datos a las otras gillas ........  

Fidel Charny

unread,
Aug 25, 2016, 2:32:52 PM8/25/16
to Comunidad de Visual Foxpro en Español
Tratemos de emprolijar un poco esto.
Estamos hablando de Ordenes de Taller o de otra cosa?
Suponiendo que hablamos de Ordenes de Taller, me imagino un archivo de cabecera que tiene el ID de Ordenes de taller, y otras referencias útiles (titular, plazo de entrega, condiciones, etc). Y me imagino una tabla de detalle donde también tienes el ID de Ordenes de Taller, una codificación para  los respuestos, lubricantes, tornería, etc. Me imagino una sola tabla con todos los  items que pueden conformar una O.T., que a su vez, cada uno tiene una clasificación por el grupo al que pertenecen, digamos "R", "L", "T" por ponerlo muy simple.
Para rellenar los grids, puedes hacer tres cursores iguales que surgen del cursor de detalle, basándote en el ID de la orden y la clasificación de grupo. Si la orden es nueva o no hay nada de un grupo determinado, el cursor respectivo estará vacío.
Si no existe una tabla con los respuestos, lubricantes y tonería (ponen todo a mano), cada agregado a cada uno de los controles grids debe acarrear automáticamente el ID y el grupo al que pertenencen.
A la hora de grabar, tendrás que juntar la información de los tres cursores para agregar, modificar o quitar de la tabla de detalle.

Gabriel Palmieri

unread,
Aug 25, 2016, 6:23:29 PM8/25/16
to Comunidad de Visual Foxpro en Español
Es una sola tabla, como me dijeron que ponían todo a mano (no hay tabla de lubricantes, tabla de tipos de trabajo de tornería, nada de eso) lo primero que hice fue darles un text de un tamaño considerable, igual que como lo tenían ellos en su ficha, como comenté antes me pidió si podía hacerse de esa forma como una "tablita" ya que a veces usaban más de un repuesto o más de un lubricante y así le resultaría mejor.

El tema es que, supongamos que va a cargar una ficha, la ficha 25, donde usó 2 repuestos diferentes, tenes 2 cantidades, 2 códigos, 2 descripciones y 2 precios, como podría guardar eso que va a estar en el Grid, en mi tabla, y después si ellos buscan la Ficha 25 y abren para verla, tendría que darle esa información, se entiente?

Gabriel Palmieri

unread,
Aug 25, 2016, 6:29:09 PM8/25/16
to Comunidad de Visual Foxpro en Español

Es una simple hojita donde ellos ponen los datos personales de la persona que deja su automóvil y algo más de información sobre los trabajos que se efectúan en ese vehículo y los repuestos que utiliza.

Fidel Charny

unread,
Aug 25, 2016, 7:35:29 PM8/25/16
to Comunidad de Visual Foxpro en Español
Lo fundamental para resolver eso es tratar de sistematizar lo mínimo. Y lo mínimo, es tener un ID de Orden de trabajo y una codificación automática. Pero necesitas dos tablas:
1) Cabecera: ID,Fecha, Datos Vehículo, Datos del Titular, Condiciones, Facturado
2) Detalle: ID,Grupo,FEcha,Concepto,Cantidad,Precio,Importe, etc
El ID es un consecutivo, numérico o alfanumérico.
El grupo, apunta al punto de entrada de datos (control grid respectivo)
De esa forma, puedes buscar en la tabla de cabecera por los datos esenciales (fecha, patente, titular, etc) y relacionar con la tabla de detalle por el ID.
Conocido el ID, tendrás 3 búsquedas:
SELECT * FROM DETALLE WHERE ID=lnId AND GRUPO = "R" into cursor Repuestos readwirte
SELECT * FROM DETALLE WHERE ID=lnId AND GRUPO = "L" into cursor Lubricantes readwrite
SELECT * FROM DETALLE WHERE ID=lnId AND GRUPO = "T" into cursor Torneria readwrite
Luego va la asociación a los controles grid (recomiendo una rutina específica para ello), pero enunciado genéricamente:
Thisform.grdRepuestos.RecordSource = "Repuestos"
Thisform.grdLubricantes.RecordSource = "Lubricantes"
thisform.grdTorneria.REcordSource = "Torneria"

Para guardar los datos, tendrás que guardar los datos de los tres cursores en la tabla Detalle.
Tratándose de tablas dbf, te puedes basar en el número de registro (RECNO()) de la tabla principal. Por ejemplo;:
SELECT *,recno() as tb_record, .F. as tb_delete FROM DETALLE WHERE ID=lnId AND GRUPO = lcGrupo into Cursor &lcCursor READWRITE
Luego, tienes que tener en cuenta:
1) Si el registro es nuevo (se agregó en el control grid), tb_record tendrá el valor Cero.
2) Si el registro existía cuando se creó el cursor, tb_record tendrá el número de registro de la tabla.
3) Para borrar un registro, antes de DELETE, tiene que ir REPLACE tb_delete with .T.

A la hora de guardar en la tabla detalle, tienes que ver las siguientes situaciones:
1) Si tb_record = 0, indica que se intentó un alta. Pero si tb_delete = .T., el alta se ignora porque significa que la anuló el usuario.
2) Si tb_Record > 0, indica que se pudo haber modificado el registro. Si tb_delete = .T., significa que el usuario quiere eliminar ese registro

Te quedaría más o menos así:
*<Guardando la información>
lcSetDeleted
= SET("Deleted")
SET DELETED OFF
lcCursor_list
= "Repuestos,Lubricantes,Torneria"
lcGrupo_List
= "R,L,T"
lnIdTrabajo
= Cabecera.Id_Orden
FOR i
= 1 TO GETWORDCOUNT(m.lcCursor_List,",")
    lcCursor
= GETWORDNUM(m.lcCursor_List,i,",")
    lcGrupo
= GETWORDNUM(m.lcGrupo_List,i,",")
   
    SELECT
(m.lcCursor)
   
*<Incluye el ID del trabajo y el grupo de pertenencia>
    replace ALL ID WITH m
.lnIdTrabajo,;
        grupo WITH m
.lcGrupo
       
    SCAN
        SCATTER TO laDatos
        DO CASE
            CASE EMPTY
(tb_record)    && si no está borrado, es un alta
                IF
!tb_Delete
                    INSERT INTO detalle FROM ARRAY laDatos
                ENDIF
            CASE tb_record
> 0        && es una modificación.
                                   
                lnGo
= tb_record
                lDelete
= tb_delete
                SELECT detalle
                GO m
.lnGo
                IF RLOCK
()
                    IF m
.lDelete  && si está borrado hay que borrarlo en la tabla
                        DELETE
                    ELSE
                        GATHER FROM laDatos
                    ENDIF
                ENDIF
        ENDCASE
        UNLOCK IN detalle
    ENDSCAN
NEXT
SET DELETED
&lcSetDeleted        && reestablece la configuración        
*<Limpia los 3 cursores>
FOR i
= 1 TO GETWORDCOUNT(m.lcCursor_List,",")
    lcCursor
= GETWORDNUM(m.lcCursor_List,i,",")
    SELECT
(m.lcCursor)
    ZAP
NEXT                        
WITH thisform
   
.grdRepuestos.refresh
   
.grdLubricantes.refresh
   
.grdTorneria.refresh
ENDWITH

Antes de guardar, debes hacer el proceso de validación. Eliminar los registros con campos para los que no se admite un valor vacío, etc.
Esto es fundamental para no guardar registros inútiles en la tabla, ya que si se opera directamente en el control grid, el usuario puede crear una multitud de registros vacíos con solo intentar desplazarse hacia abajo.

Si sigues este método, recuerda que, para borrar un registro en el cursor:
SELECT (lcCursor)
REPLACE tb_delete with .T.
DELETE                                   && esto es necesario para que el usuario deje de ver el registro borrado
Thisform.grdElqueSea.refresh

Viendo tu pantalla, te aconsejo que los Grid tengan la propiedad DeleteMark = .F. Y agrega un botón para borrar, con consulta previa.
Reply all
Reply to author
Forward
0 new messages