Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Conexión con bases de datos
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Conexión con bases de datos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 07-02-2011
delphijm delphijm is offline
Miembro
 
Registrado: abr 2008
Posts: 47
Poder: 0
delphijm Va por buen camino
DataSets Maestro - Detalle acceso al detalle

Hola a todos,

Tengo dos TClientDataSet relacionados como maestro - detalle...

En el evento BeforeOpen del dataset maestro, añado unos nuevos campos fkCalculated... Hasta aqui no hay problema...

En el evento AfterOpen tambien del dataset maestro, quiero dar valor a estas columnas en funcion del valor de los registros de la tabla de detalle, claro de los registros correspondientes al registro de la tabla maestra.

Aqui tengo el problema... En el evento AfterOpen, programo un bucle por cada registro de la tabla maestra y, dentro de el, otro bucle anidado recorriendo la tabla de detalle para sumar unos valores...

Cuando acabo el bucle de la tabla detalle, actualizo el campo que me interesa de la tabla maestra y continua con el siguiente registro de la tabla maestra...

El DataSet de la tabla maestra lo tengo conectado a un TDBGRID y, cuando acaba el proceso, si la tabla maestra tiene inicialmente 3 registros, me acaba mostrando al menos 30 o 40...

No entiendo que pasa.... Intuyo que el problema esta en como recorro la tabla de detalle que esta relacionada con un DataSetField con la tabla maestra y quizas no deba hacerlo asi pero no se como hacerlo sino???

Alguien puede ayudarme porfa???

Saludos
Responder Con Cita
  #2  
Antiguo 07-02-2011
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.732
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Cita:
BeforeOpen del dataset maestro, añado unos nuevos campos fkCalculated
¿¿¿Y si la abres dos veces, tienes los campos repetidos??? No creo que esto esté bien...

Creo que sería conveniente que nos contaras que es lo que calculas y qué informacion tienen las tablas maestra y detalle.

SUPONIENDO que las tablas sean la cabecera de una factura y sus lineas, te sugiero que crees una tercera tabla que sea para los TOTALES.
  • ¿Agregas campos al detalle?
  • Abres la cabecera
  • Miras si ya tienes los totales calculados
  • Abres el detalle
  • Recorres el detalle de principio a fin
  • Guardas el total en la tabla de totales.

Pregunta importante: ¿Qué base de datos utilizas? Estos problemas se solucionas con sentencias SQL muchas veces.
Responder Con Cita
  #3  
Antiguo 09-02-2011
delphijm delphijm is offline
Miembro
 
Registrado: abr 2008
Posts: 47
Poder: 0
delphijm Va por buen camino
Hola,

No son exactamente tablas de facturas - lineas pero parecido... Te comento lo que hago como si fueran facturas - lineas...

Para cada registro de una factura tengo en el dataset de detalle sus lineas...
Cada registro de lineas tiene como datos el codigo del articulo y la cantidad...
El dataset maestro lo tengo vinculado a un TDBGrid...
En este TDBGrid quiero mostrar, ademas de la informacion de la cabecera, el total de cantidad de cada codigo de articulo, de esta forma:

Factura + Cliente + FechaFact + cantidArticulo_A + cantidArticulo_B

Los campos cantidArticulo_A y cantidArticulo_B no estan en la tabla maestra, pero los añado en tiempo de ejecucion como campos fkCalculated porque si los añado como campos fkData, al hacer un post intentaria actualizar la BBDD y no son campos de ella.

Hasta aqui aparentemente bien...

El tema esta en que en el evento AfterOpen de la tabla maestra programo lo necesario para llenar estos nuevos campos en funcion de los registros de la tabla detalle de lineas de factura.

Lo que hago es un bucle while de la tabla maestra y para cada registro hago un bucle anidado while de los registros de la tabla de detalle...
De la tabla de detalle voy acumulando las cantidades por codigo de articulo y cuando acabo este bucle detalle asigno los valores a los nuevos campos de totales de la tabla maestra...

En el entorno de desarrollo tengo dos registros de factura cada uno de ellos con 2 o 3 lineas de detalle...

El tema esta en que me acumula los campos de totales bien para cada factura pero cuando se visualiza el dataset maestro en el TDBGrid en lugar de ver los dos registros de las 2 facturas lo que veo son 20 o 30 facturas que son las dos que deberia haber pero repetidas constantemente.

He observado que el problema esta en el bucle anidado que uso para recorrer el dataset de las lineas...

Se trata de un bucle asi:
cdsLin.first
while not cdsLin.eof do
begin
.... sentencias....
next;
end;

Si elimino las sentencias continua el problema...
Pero si elimino la linea de cdsLin.first me funciona bien para la primera factura pero no para la/las siguentes porque supongo que el puntero de la tabla de detalle se ha posicionado al final en la primera pasada...

No se si el problema puede estar en que los campos que he añadido son de tipo fkCalculated i estos solo estan pensados para asignarles valor en el evento OnCalcFields o deberia replantearme otro evento diferente de AfterOpen de la tabla maestra para hacer estos calculos?

La base de datos que uso es MySQL pero en principio no me interesa que estos totales me vengan ya desde la base de datos porque las cantidades de las lineas van a poder modificarlas el usuario y entonces debere de recalcularlos en local.

No se si esto da alguna pista adicional???

Un saludo y gracias
Responder Con Cita
  #4  
Antiguo 09-02-2011
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.732
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Pues yo haría campos calculados...
Agregas los campos calculados a la tabla cabecera
En el evento OnGetText de cada campo abres el detalle, lo recorres y el resultado se lo asignas a Text.

Código Delphi [-]
procedure TDataModule.TablaCabeceraTOTALGetText(Sender: TField; var Text: string; DisplayText: boolean);
var 
   Q : TQuery; {El componente que utilices para hacer Querys a MySQL}
   Total : Real;
begin
  Q := TQuery.Create(nil) ;
  try
    try
       {Seleccionas la suma del detalle que corresponda a la cabecera actual}
       SQL.Text := 'SELECT SUM(IMPORTE) FROM TABLA_DETALLE WHERE CABECERA=?CABECERA';
       Params.ByName['CABECERA'].AsInteger := TablaCabeceraCABECERA.AsInteger;
       ExecSQL;
       Total := FieldByName['SUM'].AsFloat;
    except
      Total := 0;
    end 
  finally
    Q:Free;
  end;
  Text := FormatFloat(Total);
end;
Responder Con Cita
  #5  
Antiguo 09-02-2011
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Hola.

Es extraño que aparezcan filas de más (habría que ver el código y la forma en que están asociados ambos conjuntos de datos para entender la razón de ello). Pero, de cualquier manera, convendría usar campos fkInternalCalc para guardar esos totales, ya que este tipo de campos, a diferencia de los fkCalculated, retienen la asignación que se les hace aunque haya navegación; es decir, se comportan como si fueran de tipo fkData, pero sin enviarse a la base de datos.

Por otro lado, puede que te facilite las cosas usar Aggregates en el conjunto de datos detalle.

Saludos.

Al González.
Responder Con Cita
  #6  
Antiguo 09-02-2011
delphijm delphijm is offline
Miembro
 
Registrado: abr 2008
Posts: 47
Poder: 0
delphijm Va por buen camino
Hola Al,

De hecho el funcionamiento de estos campos que añado me gustaria que fueran como los fkData pero sin que esten ligados a la BBDD... Si los fkInternalCalc son asi, lo probare con ellos...

Creo que los Aggregates no me servirian porque en la tabla de detalle existiran varias linieas con articulos diferentes... Necesito una total para cada articulo, no un solo total de todas las lineas... Espera...

Mientras escribo estoy pensando que si me pueden servir los aggregates... Tambien los probare...

Ya te dire como me va...

Gracias
Responder Con Cita
  #7  
Antiguo 09-02-2011
delphijm delphijm is offline
Miembro
 
Registrado: abr 2008
Posts: 47
Poder: 0
delphijm Va por buen camino
Hola duilioisola,

Lo que me propones no creo que me sirva... Veras, necesito tener en el lado del cliente, las tablas de maestro-detalle completas, con los campos calculados que comento, pero necesito tener la relacion maestro - detalle en el cliente para que pueda modificarse cualquier dato (bueno algunos) tanto de la tabla maestra como la de detalle...

Probare con la solucion propuesta por Al...

De todas formas te digo que no conocia la forma de usar el evento OnGetText de los campos del DataSet... Me interesa para otro tema que forma parte de una batalla venidera...

Gracias
Responder Con Cita
  #8  
Antiguo 10-02-2011
delphijm delphijm is offline
Miembro
 
Registrado: abr 2008
Posts: 47
Poder: 0
delphijm Va por buen camino
Cita:
Empezado por Al González Ver Mensaje
Hola.

Es extraño que aparezcan filas de más (habría que ver el código y la forma en que están asociados ambos conjuntos de datos para entender la razón de ello). Pero, de cualquier manera, convendría usar campos fkInternalCalc para guardar esos totales, ya que este tipo de campos, a diferencia de los fkCalculated, retienen la asignación que se les hace aunque haya navegación; es decir, se comportan como si fueran de tipo fkData, pero sin enviarse a la base de datos.

Por otro lado, puede que te facilite las cosas usar Aggregates en el conjunto de datos detalle.

Saludos.

Al González.
Hola Al,

Al final me funciono perfectamente solo con añadir los campos como fkInternalCalc en lugar de fkCalculated... Seguramente los Aggregates tambien me servirian pero lo prefiero asi...

Deduzco que los campos fkCalculated solo deben de usarse para ser usados en el evento OnCalcFields del TClientDataSet y los fkInternalCalc pueden usarse libremente donde sea...

Muchas gracias por tu ayuda...

Un saludo
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Saber si el DBGrid (Detalle) esta Vacio en Relacion Maestro/Detalle Adrian Murua Conexión con bases de datos 2 03-01-2009 14:48:46
Problema tabla Maestro-detalle en la q la pk de t.detalle formad por 2cods de la maes akinom38 Varios 1 09-11-2007 20:27:44
Respecto a la relacion maestro detalle detalle ilichhernandez Conexión con bases de datos 0 15-05-2007 19:13:54
Reporte Maestro/Detalle/Detalle de 4 Tablas jovehe Impresión 2 23-03-2005 02:25:02
Maestro-Detalle ;Actualizar detalle a partir de un DBgrid norberto_larios Conexión con bases de datos 1 11-09-2004 19:17:34


La franja horaria es GMT +2. Ahora son las 20:12:50.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi