Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 24-01-2011
WALTERMAN90 WALTERMAN90 is offline
Miembro
 
Registrado: mar 2008
Posts: 12
Poder: 0
WALTERMAN90 Va por buen camino
Libro diario y mayor

Hola amigos, les pido por favor me ayuden con este tema ya que no se como ni por donde empezar...

Necesito hacer un libro mayor parecido a esto...
paso a "dibujar la pantalla"

Seleciconar Cuenta: "compra de inmuebles" <-- elijo yo
Fecha desde: 21/10/2010 <-- elijo yo
Fecha hasta: 26/10/2010 <-- elijo yo
Saldo inicial: ??? <-- lo calcula (no se como)

nº asiento | cliente | debe | haber | saldo

los valores de "debe y haber" los tengo, ahora el saldo se calcula solo, pero ¿como? lo mismo pasa con el saldo inicial ¿como?

mis tablas principales son
conta_asientos: id_asiento , fecha , total_debe , total_haber
conta_asientos_deta: id_asiento , id_detalle , debe , haber

Espero puedan ayudarme. muchas gracias.
Responder Con Cita
  #2  
Antiguo 25-01-2011
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Antes que nada, creo que en la tabla conta_asientos_deta te falta la cuenta. Sponiendo que la tienes en esta tabla:

Si solo trabajás con estas dos tablas te propongo una solución simple:
Creá una tabla temporal con los campos que necesitas mostrar
libro_mayor(n_asiento, cliente, debe, haber, saldo)
Luego calculas el saldo inicial. Esto es lo que suma la columna debe y lo que suma la columna haber hasta la Fecha_Desde.
Recorres el detalle hasta que llegas a la fecha_desde
Código Delphi [-]
{PSEUDOCODIGO}
while (Fecha_asiento < Fecha_Desde) do
begin
   if (conta_asientos_deta.cuenta = Cuenta_Seleccionada) then
   begin
      Debe := Debe + conta_asientos_deta.debe;
      Haber := Haber + conta_asientos_derta.haber;
   end;
   Next
end;
with libro_mayor do
begin
   Insert (0{asiento_ficticio_inicial}, debe, haber, debe-haber {saldo});
   Acumulador_de_Saldo := debe-haber;
end;

Luego vas recorriendo las tablas e insertando los registros hasta la Fecha_Hasta y calculando el saldo:
Código Delphi [-]
{PSEUDOCODIGO}
while (Fecha_asiento < Fecha_Hasta) do
begin
   if (conta_asientos_deta.cuenta = Cuenta_Seleccionada) then
   begin
      with libro_mayor do
      begin
         Acumulador_de_Saldo := Acumulador_de_Saldo + (debe-haber);
         Insert (asiento, debe, haber, Acumulador_de_Saldo);
      end;
   end;
   Next;
end;

Nota para todo esto, los datos tienen que estar ordenados por fecha!
Además de esto, deberás hacer bucles anidados para tomar los datos de la cabecera del asiento y del detalle. La fecha está en la cabecera y si cumple con esta deberás tomar la cuenta del detalle. Si la cuenta es la que buscamos, utilizamos debe y haber para contar el saldo inicial o para rellenar el resto de registros.

Última edición por duilioisola fecha: 25-01-2011 a las 01:01:06.
Responder Con Cita
  #3  
Antiguo 25-01-2011
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Otra opción es utilizar una vista o unir las tablas con JOINs y hacer los bucles directamente con ella. Pero esto depende del motor de base de datos que utilices.

En Firebird (o cualquier otro motor SQL):
Código SQL [-]
select c.asiento,c.fecha,d.linea,d.debe,d.haber 
from conta_asientos c
join conta_asientos_deta d
on c.asiento=d.asiento

Y finalmente (también dependiendo del motor de base de datos) es generar un procedimiento almacenado al cual le pasas los datos (fecha_desde, fecha_hasta y cuenta) y te devuelve los datos que necesitas ordenados y calculados.
Responder Con Cita
  #4  
Antiguo 25-01-2011
WALTERMAN90 WALTERMAN90 is offline
Miembro
 
Registrado: mar 2008
Posts: 12
Poder: 0
WALTERMAN90 Va por buen camino
Cita:
Empezado por duilioisola Ver Mensaje
Otra opción es utilizar una vista o unir las tablas con JOINs y hacer los bucles directamente con ella. Pero esto depende del motor de base de datos que utilices.

En Firebird (o cualquier otro motor SQL):
Código SQL [-]
select c.asiento,c.fecha,d.linea,d.debe,d.haber 
from conta_asientos c
join conta_asientos_deta d
on c.asiento=d.asiento

Y finalmente (también dependiendo del motor de base de datos) es generar un procedimiento almacenado al cual le pasas los datos (fecha_desde, fecha_hasta y cuenta) y te devuelve los datos que necesitas ordenados y calculados.
Esta me gusta más, uso MySQL, si podrías darme alguna ayudita más de cómo hacerlo sería fantastico ya que vengo mal con esto...
Hasta el join voy bien, lo que no se es como ir calculando los saldos en base al saldo inicial, ya que supongo y como en tu primer ejemplo debo calcular primero este saldo inicial (hasta la fecha desde) y luego ir calculando los saldos para cada registro... eso se me hace bastante raro de hacer, te agradecería mucho si me ayudas un poco...

...y de nuevo muchas gracias por responder!!!...
Responder Con Cita
  #5  
Antiguo 25-01-2011
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
El saldo a la fecha incial lo puedes calcular con un SUM

Código SQL [-]
select SUM(d.debe),SUM(d.haber)
from conta_asientos c
join conta_asientos_deta d
on c.asiento=d.asiento
where
c.fecha < :fecha_desde and
d.cuenta = :cuenta_pedida

Esto te dará los saldos de debe y haber hasta la fecha y el saldo total, que será DEBE-HABER.

Luego de eso, con un bucle puedes ir rellenando el resto.

Código SQL [-]
select c.asiento,c.fecha,d.debe,d.haber
from conta_asientos c
join conta_asientos_deta d
on c.asiento=d.asiento
where
c.fecha >= :fecha_desde and
c.fecha <= :fecha_hasta and
d.cuenta = :cuenta_pedida
order by c.fecha,c.asiento

No conozco MySQL, pero no creo que haya una forma de calcular el saldo acumulado con un select... quizás algún gurú de los SQL pueda ayudarte un poco más.
De todos modos, puedes ir caclculándolo con Delphi a medida que vas recibiendo los datos, con un campo calculado.
Responder Con Cita
  #6  
Antiguo 25-01-2011
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Bueno, se puede, pero es complicado...

Primero calculas el saldo inicial con el SQL que te he enviado anteriormente.
Luego ejecutas esto pasándole los parámetros (los que tienen ":" delante)
Código SQL [-]
select c.asiento,d.linea,c.fecha,d.debe,d.haber,
(   /* Calculo del saldo */
    select :saldo_inicial + sum(dd.debe)-sum(dd.haber)
    from conta_asientos cc
    join conta_asientos_deta dd
    on cc.asiento=dd.asiento
    where
    dd.cuenta = :cuenta_pedida and
    cc.fecha >= :fecha_desde and
    /* Que sea menor que la fecha o
          Que sea igual a la fecha pero menor el asiento o
              Que sea igual el asiento paro menor la linea */
    (
     (cc.fecha < c.fecha) or
     (cc.fecha = c.fecha) and ( (cc.asiento < c.asiento) or
                               ( (cc.asiento = c.asiento) and (dd.linea < d.linea ) ) )
    )
)
from conta_asientos c
join conta_asientos_deta d
on c.asiento=d.asiento
where
d.cuenta = :cuenta_pedida and
c.fecha >= :fecha_desde and
c.fecha <= :fecha_hasta
order by c.fecha,c.asiento,d.linea

Ten en cuenta que es un select dentro de un select, por lo que según la cantidad de registros y los índices que tengas, puede tardar bastante.
Deberás tener (creo que obligatoriamente) un índice en la cabecera (conta_asientos) por [fecha, asiento] y en el detalle conta_asientos_deta por [cuenta,asiento, linea]

Última edición por duilioisola fecha: 25-01-2011 a las 09:53:32.
Responder Con Cita
  #7  
Antiguo 25-01-2011
WALTERMAN90 WALTERMAN90 is offline
Miembro
 
Registrado: mar 2008
Posts: 12
Poder: 0
WALTERMAN90 Va por buen camino
Cita:
Empezado por duilioisola Ver Mensaje
Antes que nada, creo que en la tabla conta_asientos_deta te falta la cuenta. Sponiendo que la tienes en esta tabla:

Si solo trabajás con estas dos tablas te propongo una solución simple:
Creá una tabla temporal con los campos que necesitas mostrar
libro_mayor(n_asiento, cliente, debe, haber, saldo)
Luego calculas el saldo inicial. Esto es lo que suma la columna debe y lo que suma la columna haber hasta la Fecha_Desde.
Recorres el detalle hasta que llegas a la fecha_desde
Código Delphi [-]
{PSEUDOCODIGO}
while (Fecha_asiento < Fecha_Desde) do
begin
   if (conta_asientos_deta.cuenta = Cuenta_Seleccionada) then
   begin
      Debe := Debe + conta_asientos_deta.debe;
      Haber := Haber + conta_asientos_derta.haber;
   end;
   Next
end;
with libro_mayor do
begin
   Insert (0{asiento_ficticio_inicial}, debe, haber, debe-haber {saldo});
   Acumulador_de_Saldo := debe-haber;
end;

Luego vas recorriendo las tablas e insertando los registros hasta la Fecha_Hasta y calculando el saldo:
Código Delphi [-]
{PSEUDOCODIGO}
while (Fecha_asiento < Fecha_Hasta) do
begin
   if (conta_asientos_deta.cuenta = Cuenta_Seleccionada) then
   begin
      with libro_mayor do
      begin
         Acumulador_de_Saldo := Acumulador_de_Saldo + (debe-haber);
         Insert (asiento, debe, haber, Acumulador_de_Saldo);
      end;
   end;
   Next;
end;

Nota para todo esto, los datos tienen que estar ordenados por fecha!
Además de esto, deberás hacer bucles anidados para tomar los datos de la cabecera del asiento y del detalle. La fecha está en la cabecera y si cumple con esta deberás tomar la cuenta del detalle. Si la cuenta es la que buscamos, utilizamos debe y haber para contar el saldo inicial o para rellenar el resto de registros.
muy interesante! muchas gracias, no tenia nada en mente asi que voy a probar, en realidad lo quería hacer solo con sql pero me parece una buena opción...
Muchas gracias por responder.
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

Temas Similares
Tema Autor Foro Respuestas Último mensaje
El diario de un perro Lord Delfos La Taberna 0 17-05-2010 06:54:36
Diario de una mujer madura jcarteagaf Humor 6 30-07-2008 18:30:20
Diario de un cincuentón egostar Humor 5 06-11-2007 05:34:43
Diario de un Cincuenton FGarcia Humor 0 25-09-2007 19:32:54
Diario de un lammer JaMFrY Humor 3 28-06-2003 14:21:10


La franja horaria es GMT +2. Ahora son las 18:55:47.


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