Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 14-07-2003
judoboy judoboy is offline
Miembro
 
Registrado: may 2003
Ubicación: Valencia
Posts: 139
Poder: 21
judoboy Va por buen camino
¿Como actualizar totales?

Hola ya hice esta pregunta hace tiempo pero necesito soluciones.

El asunto es que yo actualizo los totales recorriendo todas las filas de mi DBGrid, pero esto a veces falla, no se porque.

Lo que hago es recorrer todo el DBgrid cada vez que inserto una nueva linea, y si me meto en el DBGrid y cambio alguna cantidad lo hago en el evento onexit del DBGrid. Pero como os cuento esto a veces falla.

El asunto es que como podría hacerlo con un procedimiento almacenado en mi base de datos, supongo que será mejor así, utilizo Interbase. O como mejoro la forma actual que tengo de hacerlo, para que se visualicen los cambios instantaneamente.
Responder Con Cita
  #2  
Antiguo 14-07-2003
Avatar de Investment
Investment Investment is offline
Miembro
 
Registrado: may 2003
Posts: 378
Poder: 21
Investment Va por buen camino
En vez de recorrerte el Grid, podias hacer una consulta a la base de datos que te de el total:

Select SUM(IMPORTE) from TABLA
__________________
Saludos,
Peter Investment
Responder Con Cita
  #3  
Antiguo 14-07-2003
judoboy judoboy is offline
Miembro
 
Registrado: may 2003
Ubicación: Valencia
Posts: 139
Poder: 21
judoboy Va por buen camino
Gracias, es una solución que no se me habia ocurrido, la estoy probando.
Mi pregunta es si actualizas desde el DBGrid una cantidad, o un precio, en el OnValidate hago que se actualice el total de dicho artículo. Pero si intento actualizar el total del pedido, me peta.

¿Cómo lo hago?
Responder Con Cita
  #4  
Antiguo 14-07-2003
Avatar de Investment
Investment Investment is offline
Miembro
 
Registrado: may 2003
Posts: 378
Poder: 21
Investment Va por buen camino
Y el total del pedido donde esta?

Es una columna más del grid?
Esta en un Edit?
En un dbEdit?
Un campo calculado?
__________________
Saludos,
Peter Investment
Responder Con Cita
  #5  
Antiguo 14-07-2003
judoboy judoboy is offline
Miembro
 
Registrado: may 2003
Ubicación: Valencia
Posts: 139
Poder: 21
judoboy Va por buen camino
En un DBEdit
Responder Con Cita
  #6  
Antiguo 14-07-2003
Avatar de Investment
Investment Investment is offline
Miembro
 
Registrado: may 2003
Posts: 378
Poder: 21
Investment Va por buen camino
Yo lo que haria es que una vez hagas el post de la nueva linea del grid, volver a calcular la query
Select SUM(IMPORTE) as TOTAL from TABLA

y el resultado lo meteria en ese DBEDIT

Eso no debe darte ningun problema. De todas formas, que error te da?
__________________
Saludos,
Peter Investment
Responder Con Cita
  #7  
Antiguo 14-07-2003
judoboy judoboy is offline
Miembro
 
Registrado: may 2003
Ubicación: Valencia
Posts: 139
Poder: 21
judoboy Va por buen camino
Te comento, si lo hago en el OnValidate de Cantidad, me dice que la Tabla Lineas_PEdido no esta en modo edición o inserción, y si pongo la tabla en modo inserción me da un desbordamiento de pila.

Mientras que si lo hago en el OnChange, me refresca los datos pero cada dos cambios es decir, si cambio una cantidad no me refresca nada, pero si vuelvo a cambiar otra cantidad, no hace falta que sea del mismo artículo que la primera. Me modifica los datos pero con los valores que debería tener en el primer cambio no en el segundo. Es como si fuese con un cambio atrasado.
Responder Con Cita
  #8  
Antiguo 14-07-2003
Avatar de Investment
Investment Investment is offline
Miembro
 
Registrado: may 2003
Posts: 378
Poder: 21
Investment Va por buen camino
Prueba a hacerlo en el evento BeforePost de la tabla Lineas_Pedido . En ese momento ya tienes el nuevo valor grabado y debería actualizar el total de la tabla cantidad con el valor que has metido.
__________________
Saludos,
Peter Investment
Responder Con Cita
  #9  
Antiguo 14-07-2003
judoboy judoboy is offline
Miembro
 
Registrado: may 2003
Ubicación: Valencia
Posts: 139
Poder: 21
judoboy Va por buen camino
Pues ya parece que esta, en el beforepost, parece que funciona bien. Muchas gracias por todo.
Responder Con Cita
  #10  
Antiguo 14-07-2003
judoboy judoboy is offline
Miembro
 
Registrado: may 2003
Ubicación: Valencia
Posts: 139
Poder: 21
judoboy Va por buen camino
Me he anticipado mucho a decir que funcionaba bien, me paso lo de antes que va una con una actualización de retraso
Responder Con Cita
  #11  
Antiguo 14-07-2003
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 23
guillotmarc Va por buen camino
Hola.

El problema de ese retraso, lo tienes porqué hasta que no haya finalizado el Post, los datos no van a la Base de Datos. Por lo que hasta ese momento, si haces un SELECT SUM(), aún no aparece ese valor.

Como el evento BeforePost se ejecuta antes de realizarse el Post, los datos aún no están en la base de Datos.

Si utilizas el evento AfterPost, entonces el resultado de la consulta con el SELECT SUM() será correcto, peró si intentas asignar el valor al TDbEdit, te saltará un error indicando que ya no estás en modo edición o inserción (puesto que el Post ya ha finalizado, finalizando por tanto el estado de edición del registro).

Una posible solución es poner el código en el AfterPost (imprescindible puesto que sinó no obtendrás correctamente el valor de la suma), y antes de asignar el valor al DbEdit, fuerza el registro a entrar de nuevo en Edición mediante un Edit.

Es feo, porqué siempre que hagas un Post, el registro acabará volviendo a estado de Edición, pero tiene que funcionarte para lo que quieres.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #12  
Antiguo 14-07-2003
andres1569 andres1569 is offline
Miembro
 
Registrado: may 2003
Posts: 908
Poder: 21
andres1569 Va por buen camino
Hola:

¿No valdría la opción de ejecutar la consulta SELECT SUM() * y sumar el valor obtenido al valor que ya tenemos, y asignárselo al campo SaldoAcumulado (o como se llame), todo ello en el BeforePost?

* La consulta, claro está, devolvería el sumatorio de todos los registros anteriores, sin incluir el que estamos editando.
__________________
Guía de Estilo

Última edición por andres1569 fecha: 14-07-2003 a las 19:11:01.
Responder Con Cita
  #13  
Antiguo 14-07-2003
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 23
guillotmarc Va por buen camino
Hola.

Esto valdría para las inserciones, pero con las modificaciones tendriamos un problema.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #14  
Antiguo 14-07-2003
andres1569 andres1569 is offline
Miembro
 
Registrado: may 2003
Posts: 908
Poder: 21
andres1569 Va por buen camino
Hola de nuevo:

Bueno, ese problema que comentas lo tendremos siempre que lancemos la consulta SELECT SUM(), independientemente que usemos BeforePost o AfterPost o de que incluyamos en la consulta el registro "actual" (el que estábamos insertando).

Si no hay ningún campo (FechaHora, NumInsercion ...) que nos permita saber qué registros son anteriores al actual (es decir que sumen el saldo anterior), sólo nos servirá la consulta para inserciones, y en el caso de modificaciones deberíamos implementar algo así:
Código:
procedure BeforeEdit;
begin
  AnteriorCantidad := Total;
end;

procedure BeforePost;
begin
  if DataSet.State = dsInsert then 
  begin
    ConsultaSuma.Open;  // previo paso de parámetros
    SaldoAcu := ConsultaSuma['SUMA'].AsCurrency + Table1Total.AsCurrency
  end
  else SaldoAcu := SaldoAcu + Total - AnteriorCantidad;
end;
Pero ya digo, habría que recurrir a esto si no hay ninguna forma, mediante una consulta SQL, de averiguar los registros "anteriores". Si hay algún criterio, no veo la razón para no hacerlo todo mediante SQL. La consulta sería algo parecido a esto:

SELECT SUM(TOTAL)
FROM INGRESOS
WHERE FECHAHORA <= :fecha

o bien, si los números de la primary key son correlativos por orden de inserción:

SELECT SUM(TOTAL)
FROM INGRESOS
WHERE id_ingreso < :id

donde los parámetros :fecha y :id son los valores que estamos editando.
__________________
Guía de Estilo
Responder Con Cita
  #15  
Antiguo 14-07-2003
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 23
guillotmarc Va por buen camino
Hola

Cita:
Posteado originalmente por andres1569
Bueno, ese problema que comentas lo tendremos siempre que lancemos la consulta SELECT SUM(), independientemente que usemos BeforePost o AfterPost o de que incluyamos en la consulta el registro "actual" (el que estábamos insertando).
¿ Porqué ?. En el evento AfterPost, el resultado de la consulta SELECT SUM siempre será correcto, puesto que la Base de Datos contiene todos los registros con sus ultimos valores.

Cita:
Posteado originalmente por andres1569
SELECT SUM(TOTAL)
FROM INGRESOS
WHERE id_ingreso < :id
¿ Que ocurre si en lugar de insertar / modificar el ultimo registro, estamos modificando uno de los intermedios en la grid ?. Entonces sería mejor hacer algo como :

SELECT SUM(TOTAL)
FROM INGRESOS
WHERE id_ingreso <> :id

Pero realmente no es necesario, si ejecuta la consulta en el AfterPost el valor devuelto tiene que ser correcto.

Otra cosa es que después diga que le salta un error de : Tabla Lineas_PEdido no esta en modo edición o inserción. Esto es un error de diseño de las tablas, por poner el total en el DataSet detalles en lugar de en el DataSet maestro.

Lo mejor que puede hacer es poner el total donde corresponde, en la cabecera del pedido, y no complicarse la vida volviendo a poner en modo edición el registro en Detalles, o hacer una consulta parametrizada en el BeforePost, sin tener en cuenta el registro actual para después sumarle el valor de este registro.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #16  
Antiguo 15-07-2003
andres1569 andres1569 is offline
Miembro
 
Registrado: may 2003
Posts: 908
Poder: 21
andres1569 Va por buen camino
Hola de nuevo:

Para estos casos reclamo uno de esos smilies sonrojados que había en lo foros antiguos.

He tenido una cruzada de cables impresionante (y preocupante), he mezclado este hilo con otro que se ha posteado recientemente sobre campos calculados y donde se trataba de hallar un saldo calculando los registros anteriores al actual, de ahí que hablara de saldos y de hallar los registros anteriores cuando no era ese el tema.

Marc, de ahí lo de id_ingreso < :id.

Había leído el hilo por encima pero lo confundí y entré directamente pensando que iba de aquello. Disculpen todos los foreros.

Me voy a dormir, lo necesito ¡¡buenas noches!!
__________________
Guía de Estilo
Responder Con Cita
  #17  
Antiguo 15-07-2003
judoboy judoboy is offline
Miembro
 
Registrado: may 2003
Ubicación: Valencia
Posts: 139
Poder: 21
judoboy Va por buen camino
Bueno pues simplemente era para daros las gracias a todos por vuestras respuestas y aclaraciones.

Un saludo
Responder Con Cita
  #18  
Antiguo 15-07-2003
emili emili is offline
Miembro
 
Registrado: jun 2003
Ubicación: Ontinyent (Valencia)
Posts: 14
Poder: 0
emili Va por buen camino
Hola a todos.

Otra solución es que trabaje la BD (¿has dicho que tenias interbase, verdad?). Creo que es una buena alternativa y te garantizaria el cálculo del total del pedido.

Puedes crear un trigger. Quedaria mas o menos asi:

Create trigger ACTUALIZA_TOTAL for LINEAS_PEDIDO active AFTER UPDATE POSITION 0
as
declare variable total double precision;
begin
// hacemos un sum() de todas las lineas del pedido
SELECT SUM(INGRESOS) FROM LINEAS_PEDIDO WHERE new.<campos primarios de lineas relacionados con la cabecera>
into :total;

// Hacemos la modificación pertinente en la cabecera del pedido.
UPDATE CABECERA_PEDIDO SET TOTAL_PEDIDO=:total WHERE
<clave primaria cabecera>
end;


Tendremos que crear otros dos triggers que se activen en el AFTER INTERT y el AFTER DELETE, para cubrir todas las posibilidades.

Ahora, con un simple refresh de la cabecera, tendremos el total actualizado, pase lo que pase.

Además si tenemos la aplicación en red, minimizamos el tráfico, y ganamos en rapidez, porque la modificación la realizará el server y no el cliente, evitando el envio de paquetes entre la BD y el cliente.

Bueno, espero que te sea de ayuda.

Saludos.
Responder Con Cita
  #19  
Antiguo 15-07-2003
IVAND IVAND is offline
Miembro
 
Registrado: may 2003
Ubicación: ECUADOR
Posts: 523
Poder: 21
IVAND Va por buen camino
Y porque no usan midas, es mas facil que estar lanzando consultas al servidor

__________________
IVAND
Responder Con Cita
Respuesta



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


La franja horaria es GMT +2. Ahora son las 12:57:30.


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