none
BALANCE CONTABLE SQL SERVER RRS feed

  • Pregunta

  • uen día por favor alguna idea del por que me da error esta consulta estoy manejando sql 2014 y necesito sacar un balance contable, donde por ejemplo:

    1 ACTIVO 350.00

    11 ACTIVO CIRCULANTE 350.00

    1110 CAJA       350.00

    1110001 CAJA CHICA  300.00

    1110001 CAJA TRASPASOS 50.00

    Cabe mencionar que tengo tres tablas uno con el catalogo de cuentas que va por niveles, la otra con el movimiento diario y la tercera que guarda fechas de los registros y una sumatoria total del debe y haber de cada movimiento diario.

    Intente con este código pero me da error, al inicio en el apartado de:

    SELECT CUENTA, SUM(SaldoAnterior) SaldoAnterior, SUM(DEBE) DEBE, SUM(HABER) HABER
    FROM (
     
    SELECT CUENTA, SUM(DEBE - HABER) as SaldoAnterior, 0 Cargos, 0 Abonos
    FROM CATALOGOCTAS INNER JOIN
                             MOVIMIENTODIARIO ON CATALOGOCTAS.ID_CUENTAS = MOVIMIENTODIARIO.ID_CUENTAS INNER JOIN
                             SUMASDEAPUNTES ON MOVIMIENTODIARIO.ID_APUNTE = SUMASDEAPUNTES.ID_APUNTE
    WHERE FECHA < 31/12/2017
    GROUP BY CUENTA 
     
    UNION ALL
     
    SELECT CUENTA, 0 as SaldoAnterior, SUM(DEBE) DEBE, SUM(HABER) HABER
    FROM CATALOGOCTAS INNER JOIN
                             MOVIMIENTODIARIO ON CATALOGOCTAS.ID_CUENTAS = MOVIMIENTODIARIO.ID_CUENTAS INNER JOIN
                             SUMASDEAPUNTES ON MOVIMIENTODIARIO.ID_APUNTE = SUMASDEAPUNTES.ID_APUNTE
    WHERE FECHA BETWEEN 01/01/2018 AND 31/01/2018
    GROUP BY CUENTA
     
    ) AS Balanza
    GROUP BY CUENTA

    Ya que al final esta consulta sql la pienso mandar a un gridview de asp.net

    O alguna otra idea de sacar algo parecido.

    Gracias por su ayuda, un saludo



    Hugo Damian

    sábado, 7 de abril de 2018 4:00

Respuestas

  • Hola Hugo Damian:

    Ese código al menos tiene errores de sintaxis en las fechas, pues estas deben estar entrecomilladas por apóstrofes.

    Además como no pones alias a las tablas, no se sabe de cual es cada columna, y el motor solo puede predecirlo si la columna es única. Y por ejemplo la columna Fecha, parece tener bastante setnido en MOVIMIENTODIARIO y también lo podría tener en SUMADEAPUNTES.Tu sintaxis corregida puede quedar así:

    SELECT CUENTA, SUM(B.SaldoAnterior) SaldoAnterior, SUM(B.DEBE) DEBE, SUM(B.HABER) HABER
    FROM (
     
    SELECT CUENTA, SUM(M.DEBE - M.HABER) as SaldoAnterior, 0 DEBE, 0 HABER
    FROM CATALOGOCTAS C INNER JOIN
                             MOVIMIENTODIARIO M ON C.ID_CUENTAS = M.ID_CUENTAS INNER JOIN
                             SUMASDEAPUNTES S ON M.ID_APUNTE = S.ID_APUNTE
    WHERE FECHA < '31/12/2017'
    GROUP BY CUENTA 
     
    UNION ALL
     
    SELECT C.CUENTA, 0 as SaldoAnterior, SUM(S.DEBE) DEBE, SUM(S.HABER) HABER
    FROM CATALOGOCTAS C INNER JOIN
                             MOVIMIENTODIARIO M ON C.ID_CUENTAS = M.ID_CUENTAS INNER JOIN
                             SUMASDEAPUNTES S ON M.ID_APUNTE = S.ID_APUNTE
    WHERE M.FECHA BETWEEN '01/01/2018' AND '31/01/2018'
    GROUP BY CUENTA
     
    ) AS B
    GROUP BY CUENTA

    Observa que la segunda consulta filtra por fecha de movimientos, cuando a lo mejor debe de ser por fecha de suma de apuntes....

    Saludos

    • Marcado como respuesta Hugo Damian sábado, 7 de abril de 2018 14:48
    sábado, 7 de abril de 2018 4:54
  • Hola Damian:

    No problema

    CREATE PROCEDURE MIPROC (@FECHA1 DATE, @FECHAINICIAL DATE, @FECHAFINAL DATE)
    AS
    
    SELECT CUENTA, SUM(B.SaldoAnterior) SaldoAnterior, SUM(B.DEBE) DEBE, SUM(B.HABER) HABER
    FROM (
     
    SELECT CUENTA, SUM(M.DEBE - M.HABER) as SaldoAnterior, 0 DEBE, 0 HABER
    FROM CATALOGOCTAS C INNER JOIN
                             MOVIMIENTODIARIO M ON C.ID_CUENTAS = M.ID_CUENTAS INNER JOIN
                             SUMASDEAPUNTES S ON M.ID_APUNTE = S.ID_APUNTE
    WHERE FECHA < @FECHA1
    GROUP BY CUENTA 
     
    UNION ALL
     
    SELECT C.CUENTA, 0 as SaldoAnterior, SUM(S.DEBE) DEBE, SUM(S.HABER) HABER
    FROM CATALOGOCTAS C INNER JOIN
                             MOVIMIENTODIARIO M ON C.ID_CUENTAS = M.ID_CUENTAS INNER JOIN
                             SUMASDEAPUNTES S ON M.ID_APUNTE = S.ID_APUNTE
    WHERE M.FECHA BETWEEN @FECHAINICIAL AND @FECHAFINAL
    GROUP BY CUENTA
     
    ) AS B
    GROUP BY CUENTA
    RETURN

    Algo así.

    Saludos

    • Marcado como respuesta Hugo Damian sábado, 7 de abril de 2018 14:48
    sábado, 7 de abril de 2018 7:26

Todas las respuestas

  • Cuando haces una union deben de tener la misma cantidad de columnas y todas con los mismos nombres en tu caso no es asi, tienes en el primer select cuenta, saldoanterior, cargos y abonos y en el 2do tienes cuenta, saldoanterior, debe y haber entonces no coinsiden los campos de las uniones


    Marvin E. Pineda

      ComboBoxMultiColumns

     NetBarControl

      TextEditor

    sábado, 7 de abril de 2018 4:51
    Moderador
  • Hola Hugo Damian:

    Ese código al menos tiene errores de sintaxis en las fechas, pues estas deben estar entrecomilladas por apóstrofes.

    Además como no pones alias a las tablas, no se sabe de cual es cada columna, y el motor solo puede predecirlo si la columna es única. Y por ejemplo la columna Fecha, parece tener bastante setnido en MOVIMIENTODIARIO y también lo podría tener en SUMADEAPUNTES.Tu sintaxis corregida puede quedar así:

    SELECT CUENTA, SUM(B.SaldoAnterior) SaldoAnterior, SUM(B.DEBE) DEBE, SUM(B.HABER) HABER
    FROM (
     
    SELECT CUENTA, SUM(M.DEBE - M.HABER) as SaldoAnterior, 0 DEBE, 0 HABER
    FROM CATALOGOCTAS C INNER JOIN
                             MOVIMIENTODIARIO M ON C.ID_CUENTAS = M.ID_CUENTAS INNER JOIN
                             SUMASDEAPUNTES S ON M.ID_APUNTE = S.ID_APUNTE
    WHERE FECHA < '31/12/2017'
    GROUP BY CUENTA 
     
    UNION ALL
     
    SELECT C.CUENTA, 0 as SaldoAnterior, SUM(S.DEBE) DEBE, SUM(S.HABER) HABER
    FROM CATALOGOCTAS C INNER JOIN
                             MOVIMIENTODIARIO M ON C.ID_CUENTAS = M.ID_CUENTAS INNER JOIN
                             SUMASDEAPUNTES S ON M.ID_APUNTE = S.ID_APUNTE
    WHERE M.FECHA BETWEEN '01/01/2018' AND '31/01/2018'
    GROUP BY CUENTA
     
    ) AS B
    GROUP BY CUENTA

    Observa que la segunda consulta filtra por fecha de movimientos, cuando a lo mejor debe de ser por fecha de suma de apuntes....

    Saludos

    • Marcado como respuesta Hugo Damian sábado, 7 de abril de 2018 14:48
    sábado, 7 de abril de 2018 4:54
  • Las sumatorias por niveles se resuelve de manera simple con CTE recursivas, busca en la web al respecto, si tienes dudas las consultas por este medio.

    Por ejemplo un enlace para que revises: Totales en un plan de cuentas

    sábado, 7 de abril de 2018 6:21
  • Gracias por tu tiempo me sirvió de maravilla, abusando de ti. ¿crees que se pueda poner variable las fechas de ambas consultas para poder meter esto en un procedimiento almacenado y dejarlo como parámetro?

    WHERE FECHA < '31/12/2017'
    WHERE M.FECHA BETWEEN '01/01/2018' AND '31/01/2018'

    Gracias nuevamente por tu tiempo.


    Hugo Damian

    sábado, 7 de abril de 2018 6:27
  • Hola Damian:

    No problema

    CREATE PROCEDURE MIPROC (@FECHA1 DATE, @FECHAINICIAL DATE, @FECHAFINAL DATE)
    AS
    
    SELECT CUENTA, SUM(B.SaldoAnterior) SaldoAnterior, SUM(B.DEBE) DEBE, SUM(B.HABER) HABER
    FROM (
     
    SELECT CUENTA, SUM(M.DEBE - M.HABER) as SaldoAnterior, 0 DEBE, 0 HABER
    FROM CATALOGOCTAS C INNER JOIN
                             MOVIMIENTODIARIO M ON C.ID_CUENTAS = M.ID_CUENTAS INNER JOIN
                             SUMASDEAPUNTES S ON M.ID_APUNTE = S.ID_APUNTE
    WHERE FECHA < @FECHA1
    GROUP BY CUENTA 
     
    UNION ALL
     
    SELECT C.CUENTA, 0 as SaldoAnterior, SUM(S.DEBE) DEBE, SUM(S.HABER) HABER
    FROM CATALOGOCTAS C INNER JOIN
                             MOVIMIENTODIARIO M ON C.ID_CUENTAS = M.ID_CUENTAS INNER JOIN
                             SUMASDEAPUNTES S ON M.ID_APUNTE = S.ID_APUNTE
    WHERE M.FECHA BETWEEN @FECHAINICIAL AND @FECHAFINAL
    GROUP BY CUENTA
     
    ) AS B
    GROUP BY CUENTA
    RETURN

    Algo así.

    Saludos

    • Marcado como respuesta Hugo Damian sábado, 7 de abril de 2018 14:48
    sábado, 7 de abril de 2018 7:26
  • Muchísimas gracias por tu tiempo y dedicación un saludo cordial.

    Hugo Damian

    sábado, 7 de abril de 2018 14:48
  • Eso va a ser difícil que logres sacarlo con simple select, creo que debes armar una rutina en un lenguaje de programación como .Net Visual Studio o VFP, porque para armar los saldos iniciales para un rango de fechas necesitas funciones separadas. A ese saldo inicial le debes sumar y restar las operaciones del periodo en cuestión y eso te da saldo final. Eso es para las cuentas de aplicación, es decir las que tienes transacciones, pero la cosa se complica para las cuentas de agrupación, porque no tienen transacciones propias sino que acumulan lo que les reportan sus subcuentas.
    • Editado JoséMiel sábado, 7 de abril de 2018 20:05
    sábado, 7 de abril de 2018 20:05
  • Gracias pensaba meter esa información a un gridview de asp.net y mediante otro query sacar saldos iniciales, lo que se me complica es lo que dices como sumar y restar las operaciones del periodo ya que entiendo que se debe de restar o sumar según la naturaleza de la cuenta y se empieza.

    Sumando el saldo inicial mas el primer movimiento de la cuenta de debe menos el haber, las siguientes restas o sumas se van haciendo dependiendo del resultado anterior, por ejemplo:

    Gracias saludos.


    Hugo Damian

    domingo, 8 de abril de 2018 21:13
  • Hola:

    Se puede hacerlo en T-Sql.

    Evidentemente, la construcción de las sentencias no son de esta complejidad, hay que subirla un par de peldaños.

    Una posibilidad, para la parte que comentas, es utilizar algo así como SUM(ROUND(M.DEBE,2)) OVER BY(LEFT(CUENTA,X)) as debegrupo,

    O dicho de otro modo, dado que las funciones de ventana, permiten extraer la agrupación de los datos por los criterios definidos en el over, y esta puede ser una función, de manera que extraes, la parte izquierda de la cuenta, que es el grupo de cuentas.

    Cuidado porque depende de como este montada la estructura de cuentas, y el tipo de balance que estes armando, a veces tienes que sacar las cuentas de nivel 3, a veces de nivel 4 y hasta nivel 5.

    Y los saldos iniciales, no dejan de ser apuntes de cuentas al debe o al haber, por tanto ni siquiera saldos, dado que los anotas en el asiento de apertura, que no deja de ser otro asiento... :)

    Pero creo que eso será otro capítulo.

    Un saludo

    lunes, 9 de abril de 2018 5:32
  • En efecto, tengo un ejemplo operativo en VFP que te puedo pasar, es de adaptarlo porque está hecho para tablas DBF donde los asientos tienen un campo Monto y otro que marca D debe ó H Haber, pero he visto otros sistemas donde hay dos campos: Cargos y Abonos. Y hay otros más chapuzos donde todo va en un solo campo y da por hecho que cargos son positivos y abonos son negativos. Por ahora no estoy donde tengo ese ejemplo pero estoy en  svdocus arroba yahoo com Tambien puedes revisar otros reportes del sistema que gestiona esa base, si acaso estuvieran los fuentes disponibles, para partir de algo parecido que ya esté hecho,
    lunes, 9 de abril de 2018 13:43
  • En efecto, tengo un ejemplo operativo en VFP que te puedo pasar, es de adaptarlo porque está hecho para tablas DBF donde los asientos tienen un campo Monto y otro que marca D debe ó H Haber, pero he visto otros sistemas donde hay dos campos: Cargos y Abonos. Y hay otros más chapuzos donde todo va en un solo campo y da por hecho que cargos son positivos y abonos son negativos. Por ahora no estoy donde tengo ese ejemplo pero estoy en  svdocus arroba yahoo com Tambien puedes revisar otros reportes del sistema que gestiona esa base, si acaso estuvieran los fuentes disponibles, para partir de algo parecido que ya esté hecho,
    hola, me gustaría recibir tú ejemplo, de ser posible esté es mi correo "hols75@hotmail.com"
    viernes, 8 de marzo de 2019 21:33