ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

Livro Caixa, tá quase

 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
renanbg
Colaborador
Colaborador


Registrado: Quinta-Feira, 12 de Abril de 2012
Mensagens: 1158

MensagemEnviada: Seg Set 18, 2017 3:19 pm    Assunto: Livro Caixa, tá quase Responder com Citação

Amigos, com base nessa procedure fiz umas modificações e consegui o resultado esperado, exceto por um detalhe.

Ela traz a data final, como a data atual, então se na data atual não houver movimento, traz uma linha em branco.

Alguém poderia me ajudar a editar ela, adicionando o parametro de datafinal?

Alem disse ela esta agrupando credito e debitos do mesmo dia numa unica linha. Gostaria de fosse numa nova linha.

Código:
create or alter procedure SALDO_CONTA (
    CONTA integer,
    DATAINICIAL date)
returns (
    DATA date,
    CONTAMOVIMENTADA integer,
    SALDOANTERIOR numeric(15,2),
    CREDITO numeric(15,2),
    DEBITO numeric(15,2),
    SALDOATUAL numeric(15,2))
as
declare variable VALORCREDITO numeric(15,2);
declare variable VALORDEBITO numeric(15,2);
declare variable DATAFINAL date;
begin
  data = datainicial;
  contamovimentada = conta;
  -- datafinal será sempre a data atual do sistema --
  datafinal = current_date;

  -- **************************************************************
  -- estas linhas estão fora do while para que sejam           -- *
  -- executadas apenas 1 vez, aumentando a performance.        -- *
  -- depois apenas faço a soma dos valores obtidos dia a dia   -- *
  -- para sempre obter o saldo anterior correto                -- *
  -- **************************************************************
  select coalesce(sum(valor),0)                                -- *
  from movimentacao                                                 -- *
  where tipo = 'C' and cod_banco = :conta and data < :data into :valorcredito;  -- *
                                                               -- *
  select coalesce(sum(valor),0)                                -- *
  from movimentacao                                                  -- *
  where tipo = 'D' and cod_banco = :conta and data < :data into :valordebito;   -- *
                                                               -- *
  -- obtenho o saldo anterior subtraindo o débito do crédito   -- *
  saldoanterior = valorcredito - valordebito;                  -- *
  -- **************************************************************

  -- verifico o movimento dia a dia, até o dia anterior à data atual
  while (data < datafinal) do
  begin
    -- somo os créditos do dia
    select coalesce(sum(valor),0)
    from movimentacao
    where tipo = 'C' and cod_banco = :conta and data = :data into :credito;

    -- somo os débitos do dia
    select coalesce(sum(valor),0)
    from movimentacao
    where tipo = 'D' and cod_banco = :conta and data = :data into :debito;

    saldoatual = saldoanterior + (credito - debito);

    -- se houve algum movimento no dia, exibo o registro
    if ((credito > 0) or (debito > 0))  then
      suspend;

    data = data + 1;
    saldoanterior = saldoanterior + (credito - debito);
  end

  -- somo os créditos da data atual
  select coalesce(sum(valor),0)
  from movimentacao
  where tipo = 'C' and cod_banco = :conta and data = :data into :credito;

  -- somo os débitos da data atual
  select coalesce(sum(valor),0)
  from movimentacao
  where tipo = 'D' and cod_banco = :conta and data = :data into :debito;

  saldoatual = saldoanterior + (credito - debito);

  -- exibe o registro com o saldo do dia atual
  suspend;
end
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
johnny-walker
Moderador
Moderador


Registrado: Sábado, 4 de Outubro de 2003
Mensagens: 10653
Localização: Contagem/MG - BRAZIL

MensagemEnviada: Seg Set 18, 2017 7:12 pm    Assunto: Responder com Citação

Teste este aqui, tavez lhe dê mais idéias:


Código:
/******************************************************************************/
/****          Generated by IBExpert 2.5.0.38 10/5/2003 22:29:43           ****/
/******************************************************************************/

SET SQL DIALECT 3;

SET NAMES WIN1252;

CREATE DATABASE 'c:\ClubeDelphi\caixa.gdb'
USER 'SYSDBA' PASSWORD 'masterkey'
PAGE_SIZE 4096
DEFAULT CHARACTER SET WIN1252;



/******************************************************************************/
/****                              Generators                              ****/
/******************************************************************************/

CREATE GENERATOR GEN_APAGAR_ID;
CREATE GENERATOR GEN_ARECEBER_ID;


/******************************************************************************/
/****                              Exceptions                              ****/
/******************************************************************************/

CREATE EXCEPTION EXP_NEGATIVO 'O expoente não pode ser negativo !';



SET TERM ^ ;



/******************************************************************************/
/****                          Stored Procedures                           ****/
/******************************************************************************/

CREATE PROCEDURE CAIXA (
    INICIO DATE,
    FIM DATE)
RETURNS (
    DATA DATE,
    HISTORICO VARCHAR(30),
    VALOR NUMERIC(9,2),
    TIPO CHAR(1))
AS
BEGIN
  EXIT;
END^


CREATE PROCEDURE POWER (
    NUMERO NUMERIC(9,2),
    EXPOENTE INTEGER)
RETURNS (
    RESULTADO NUMERIC(15,2))
AS
BEGIN
  EXIT;
END^



SET TERM ; ^


/******************************************************************************/
/****                                Tables                                ****/
/******************************************************************************/

CREATE TABLE APAGAR (
    ID         INTEGER NOT NULL,
    DATA       DATE DEFAULT CURRENT_DATE NOT NULL,
    HISTORICO  VARCHAR(30),
    VALOR      NUMERIC(9,2) DEFAULT 0.00 NOT NULL
);


CREATE TABLE ARECEBER (
    ID         INTEGER NOT NULL,
    DATA       DATE DEFAULT CURRENT_DATE NOT NULL,
    HISTORICO  VARCHAR(30),
    VALOR      NUMERIC(9,2) DEFAULT 0.00 NOT NULL
);





/******************************************************************************/
/****                             Primary Keys                             ****/
/******************************************************************************/

ALTER TABLE APAGAR ADD CONSTRAINT FK_APAGAR PRIMARY KEY (ID);
ALTER TABLE ARECEBER ADD CONSTRAINT FK_ARECEBER PRIMARY KEY (ID);


/******************************************************************************/
/****                               Indices                                ****/
/******************************************************************************/

CREATE INDEX APAGAR_DATA ON APAGAR (DATA);
CREATE INDEX ARECEBER_DATA ON ARECEBER (DATA);


/******************************************************************************/
/****                               Triggers                               ****/
/******************************************************************************/


SET TERM ^ ;




/* Trigger: APAGAR_BI_BI */
CREATE TRIGGER APAGAR_BI_BI FOR APAGAR
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
  IF (NEW.ID IS NULL) THEN
    NEW.ID = GEN_ID(GEN_APAGAR_ID,1);
END
^

/* Trigger: ARECEBER_BI_BI */
CREATE TRIGGER ARECEBER_BI_BI FOR ARECEBER
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
  IF (NEW.ID IS NULL) THEN
    NEW.ID = GEN_ID(GEN_ARECEBER_ID,1);
END
^


SET TERM ; ^


/******************************************************************************/
/****                          Stored Procedures                           ****/
/******************************************************************************/


SET TERM ^ ;

ALTER PROCEDURE CAIXA (
    INICIO DATE,
    FIM DATE)
RETURNS (
    DATA DATE,
    HISTORICO VARCHAR(30),
    VALOR NUMERIC(9,2),
    TIPO CHAR(1))
AS
DECLARE VARIABLE SALDO_ANT_CREDITO NUMERIC(9,2);
DECLARE VARIABLE SALDO_ANT_DEBITO NUMERIC(9,2);
DECLARE VARIABLE SALDO_FINAL NUMERIC(9,2);
begin

  /* Primeiro recuperamos a soma dos valores dos debitos anteriores ao
     periodo informado para posteriormente calcularmos nosso saldo inicial */

  select sum(ap.valor)
  from apagar ap
  where (ap.data < :inicio)
  into :saldo_ant_debito;

  /* Agora recuperamos a soma dos valores dos creditos anteriores ao
     periodo informado  */

  select sum(ar.valor)
  from areceber ar
  where (ar.data < :inicio)
  into :saldo_ant_credito;

  /* Caso não haja lancamentos anteriores, a variavel ficara no estado NULL,
     como no SQL qualquer operação matemática feita com valores NULL sempre
     resulta em NULL, temos que verificar isso e atribuir 0.00 na variavel nula
     para que forneça o resultado esperado */

  if (:saldo_ant_credito is null) then saldo_ant_credito = 0.00;
  if (:saldo_ant_debito is null) then saldo_ant_debito = 0.00;

  data = :inicio - 1;
  historico = 'SALDO ANTERIOR';
  valor = (saldo_ant_credito - saldo_ant_debito);

  /* Inicializando a variavel que armazenara o saldo final
     com o valor do saldo anterior */
  saldo_final = valor;

  /* Por questões "estéticas" não queremos ter valores negativos no campo valor,
     sendo assim, se o saldo anterior é negativo, devemos informar que o lançamento é
     de débito e tornar o valor do saldo positivo, caso contratio informamos que o
     lançamento é de crédito.*/

  if (:valor < 0) then
  begin
    tipo = 'D';
    valor = valor * -1;
  end
  else
  begin
    tipo = 'C';
  end

  suspend; /* Retornando a primeira linha (registro) com o saldo anterior */

  /* o comando a seguir seleciona os registros dentro do periodo informado
     buscando na tabela de contas a pagar */

  tipo = 'D'; /* Estamos recuperando débitos */

  for select ap.data, ap.historico, ap.valor
      from apagar ap
      where (ap.data between :inicio and :fim)
      into :data, :historico, :valor
  do
  begin
    /* Subtraimos o valor do lançamento do saldo final */
    saldo_final = saldo_final - valor;
    /* O suspend a seguir retorna uma "linha" contendo os campos
       data, historico, tipo e valor que tem seus valores armazenados
       nas variáveis de mesmo nome */
    suspend;
  end

  tipo = 'C'; /* Estamos recuperando créditos */

  /* seleciona os registros dentro do periodo informado
     buscando na tabela de contas a receber */
  for select ar.data, ar.historico, ar.valor
      from areceber ar
      where (ar.data between :inicio and :fim)
      into :data, :historico, :valor
  do
  begin
    /* Adicionamos o valor do lançamento ao saldo final */
    saldo_final = saldo_final + valor;
    /* O suspend a seguir retorna uma "linha" contendo os campos
       data, historico, tipo e valor que tem seus valores armazenados
       nas variáveis de mesmo nome */
    suspend;
  end

  /* Montamos o ultimo "registro" que conterá os valores do saldo FINAL */
  data = :fim;
  historico = 'SALDO FINAL';
  tipo = 'C';
  valor = saldo_final;

  suspend;

end
^

ALTER PROCEDURE POWER (
    NUMERO NUMERIC(9,2),
    EXPOENTE INTEGER)
RETURNS (
    RESULTADO NUMERIC(15,2))
AS
DECLARE VARIABLE CONTADOR INTEGER;
begin
  resultado = -1; /* Em caso de erro, retorna -1 */

  if (:expoente < 0) then /* Está rotina só funciona para expoentes positivos */
    exception exp_negativo;

  contador = 0;
  resultado = 1;
  while (:contador < :expoente) do
  begin
    resultado = resultado * numero;
    contador = contador + 1;
    WHEN any do /* Caso ocorra algum erro, como por exemplo */
    begin       /* um overflow, então retorna -1 */
      resultado = -1;
      exit;
    end
  end
end
^


SET TERM ; ^



bye
_________________
P.O.W.E.R B.Y D.E.L.P.H.I
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular MSN Messenger
renanbg
Colaborador
Colaborador


Registrado: Quinta-Feira, 12 de Abril de 2012
Mensagens: 1158

MensagemEnviada: Ter Set 19, 2017 8:01 am    Assunto: Responder com Citação

Hum, estou tentando aqui, mas da esse erro:

Código:
arithmetic exception, numeric overflow, or string truncation.
string right truncation.
At procedure 'CAIXA' line: 80, col: 5.


Ajustei a procedure desta forma

Código:
SET TERM ^ ;

create or alter procedure CAIXA (
    INICIO date,
    FIM date)
returns (
    DATA date,
    LANCAMENTO varchar(30),
    VALOR numeric(9,2),
    TIPO char(1))
as
declare variable SALDO_ANT_CREDITO numeric(9,2);
declare variable SALDO_ANT_DEBITO numeric(9,2);
declare variable SALDO_FINAL numeric(9,2);
begin

  /* Primeiro recuperamos a soma dos valores dos debitos anteriores ao
     periodo informado para posteriormente calcularmos nosso saldo inicial */

  select sum(valor)
  from MOVIMENTACAO
  where (data < :inicio) AND TIPO = 'D'
  into :saldo_ant_debito;

  /* Agora recuperamos a soma dos valores dos creditos anteriores ao
     periodo informado  */

  select sum(valor)
  from MOVIMENTACAO
  where (data < :inicio) AND TIPO = 'C'
  into :saldo_ant_credito;

  /* Caso não haja lancamentos anteriores, a variavel ficara no estado NULL,
     como no SQL qualquer operação matemática feita com valores NULL sempre
     resulta em NULL, temos que verificar isso e atribuir 0.00 na variavel nula
     para que forneça o resultado esperado */

  if (:saldo_ant_credito is null) then saldo_ant_credito = 0.00;
  if (:saldo_ant_debito is null) then saldo_ant_debito = 0.00;

  data = :inicio - 1;
  lancamento = 'SALDO ANTERIOR';
  valor = (saldo_ant_credito - saldo_ant_debito);

  /* Inicializando a variavel que armazenara o saldo final
     com o valor do saldo anterior */
  saldo_final = valor;

  /* Por questões "estéticas" não queremos ter valores negativos no campo valor,
     sendo assim, se o saldo anterior é negativo, devemos informar que o lançamento é
     de débito e tornar o valor do saldo positivo, caso contratio informamos que o
     lançamento é de crédito.*/

  if (:valor < 0) then
  begin
    tipo = 'D';
    valor = valor * -1;
  end
  else
  begin
    tipo = 'C';
  end

  suspend; /* Retornando a primeira linha (registro) com o saldo anterior */

  /* o comando a seguir seleciona os registros dentro do periodo informado
     buscando na tabela de contas a pagar */

  tipo = 'D'; /* Estamos recuperando débitos */

  for select data, lancamento, valor
      from movimentacao
      where (data between :inicio and :fim) AND TIPO = 'D'
      into :data, :lancamento, :valor
  do
  begin
    /* Subtraimos o valor do lançamento do saldo final */
    saldo_final = saldo_final - valor;
    /* O suspend a seguir retorna uma "linha" contendo os campos
       data, historico, tipo e valor que tem seus valores armazenados
       nas variáveis de mesmo nome */
    suspend;
  end

  tipo = 'C'; /* Estamos recuperando créditos */

  /* seleciona os registros dentro do periodo informado
     buscando na tabela de contas a receber */
  for select data, lancamento, valor
      from movimentacao
      where (data between :inicio and :fim) AND TIPO = 'C'
      into :data, :lancamento, :valor
  do
  begin
    /* Adicionamos o valor do lançamento ao saldo final */
    saldo_final = saldo_final + valor;
    /* O suspend a seguir retorna uma "linha" contendo os campos
       data, historico, tipo e valor que tem seus valores armazenados
       nas variáveis de mesmo nome */
    suspend;
  end

  /* Montamos o ultimo "registro" que conterá os valores do saldo FINAL */
  data = :fim;
  lancamento = 'SALDO FINAL';
  tipo = 'C';
  valor = saldo_final;

  suspend;

end^

SET TERM ; ^
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
renanbg
Colaborador
Colaborador


Registrado: Quinta-Feira, 12 de Abril de 2012
Mensagens: 1158

MensagemEnviada: Ter Set 19, 2017 4:56 pm    Assunto: Responder com Citação

Consegui executar, mas ela traz apenas saldo inicial e final. Eu desejo o saldo dia a dia.

Achei uma outra, que faz o que eu quero, mas não to conseguindo adiconar 2 parametros

data final e cod_banco(pra puxar o extrato da conta que eu quiser)

Código:
SET TERM ^ ;

create or alter procedure PROC_MOVI (
    DATAINICIAL date)
returns (
    COD_BANCO integer,
    DATA date,
    TIPO char(1),
    LANCAMENTO varchar(40),
    VALOR numeric(12,2),
    SALDO numeric(12,2))
as
declare variable DEBITO double precision;
declare variable CREDITO double precision;
declare variable SALDOATUAL double precision;
begin
  select sum(movi.VALOR) from MOVIMENTACAO movi where movi.TIPO = 'D' and
movi.DATA < :DATAINICIAL into :DEBITO;
  select sum(movi.VALOR) from MOVIMENTACAO movi where movi.TIPO = 'C' and
movi.DATA <DATAINICIAL>= :DATAINICIAL order by DATA,CODIGO into
:COD_BANCO,:DATA,:TIPO,:LANCAMENTO,:VALOR,:SALDO do
  begin
      if (TIPO = 'C') then SALDO = SALDOATUAL + :VALOR;
      if (TIPO = 'D') then SALDO = SALDOATUAL - :VALOR;
      SALDOATUAL = :SALDO;
      suspend;
  end
end^

SET TERM ; ^

/* Following GRANT statements are generated automatically */

GRANT SELECT ON MOVIMENTACAO TO PROCEDURE PROC_MOVI;

/* Existing privileges on this procedure */

GRANT EXECUTE ON PROCEDURE PROC_MOVI TO SYSDBA;
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
renanbg
Colaborador
Colaborador


Registrado: Quinta-Feira, 12 de Abril de 2012
Mensagens: 1158

MensagemEnviada: Ter Set 19, 2017 5:14 pm    Assunto: Responder com Citação

Consegui executar, mas ela traz apenas saldo inicial e final. Eu desejo o saldo dia a dia.

Achei uma outra, que faz o que eu quero, mas não to conseguindo adiconar 2 parametros

data final e cod_banco(pra puxar o extrato da conta que eu quiser)

Código:
SET TERM ^ ;

create or alter procedure PROC_MOVI (
    DATAINICIAL date)
returns (
    COD_BANCO integer,
    DATA date,
    TIPO char(1),
    LANCAMENTO varchar(40),
    VALOR numeric(12,2),
    SALDO numeric(12,2))
as
declare variable DEBITO double precision;
declare variable CREDITO double precision;
declare variable SALDOATUAL double precision;
begin
  select sum(movi.VALOR) from MOVIMENTACAO movi where movi.TIPO = 'D' and
movi.DATA < :DATAINICIAL into :DEBITO;
  select sum(movi.VALOR) from MOVIMENTACAO movi where movi.TIPO = 'C' and
movi.DATA < :DATAINICIAL into :CREDITO;
  SALDOATUAL =coalesce(CREDITO,0) - coalesce(DEBITO,0) ;
  COD_BANCO = 0;
  DATA = DATAINICIAL - 1;
  TIPO = '';
  LANCAMENTO = 'SALDO ANTERIOR';
  VALOR = SALDOATUAL;
  SALDO = SALDOATUAL;
  suspend;
  for select
COD_BANCO,DATA,TIPO,LANCAMENTO,COALESCE(VALOR,0),COALESCE(VALOR,0) from MOVIMENTACAO
where DATA >= :DATAINICIAL order by DATA,CODIGO into
:COD_BANCO,:DATA,:TIPO,:LANCAMENTO,:VALOR,:SALDO do
  begin
      if (TIPO = 'C') then SALDO = SALDOATUAL + :VALOR;
      if (TIPO = 'D') then SALDO = SALDOATUAL - :VALOR;
      SALDOATUAL = :SALDO;
      suspend;
  end
end^

SET TERM ; ^

/* Following GRANT statements are generated automatically */

GRANT SELECT ON MOVIMENTACAO TO PROCEDURE PROC_MOVI;

/* Existing privileges on this procedure */

GRANT EXECUTE ON PROCEDURE PROC_MOVI TO SYSDBA;
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi Todos os horários são GMT - 3 Horas
Página 1 de 1

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB