FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
¿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. |
#2
|
||||
|
||||
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 |
#3
|
|||
|
|||
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? |
#4
|
||||
|
||||
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 |
#5
|
|||
|
|||
En un DBEdit
|
#6
|
||||
|
||||
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 |
#7
|
|||
|
|||
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. |
#8
|
||||
|
||||
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 |
#9
|
|||
|
|||
Pues ya parece que esta, en el beforepost, parece que funciona bien. Muchas gracias por todo.
|
#10
|
|||
|
|||
Me he anticipado mucho a decir que funcionaba bien, me paso lo de antes que va una con una actualización de retraso
|
#11
|
||||
|
||||
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). |
#12
|
|||
|
|||
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. |
#13
|
||||
|
||||
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). |
#14
|
|||
|
|||
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; 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 |
#15
|
||||
|
||||
Hola
Cita:
Cita:
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). |
#16
|
|||
|
|||
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 |
#17
|
|||
|
|||
Bueno pues simplemente era para daros las gracias a todos por vuestras respuestas y aclaraciones.
Un saludo |
#18
|
|||
|
|||
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. |
#19
|
|||
|
|||
Y porque no usan midas, es mas facil que estar lanzando consultas al servidor
__________________
IVAND |
|
|
|