 |
ActiveDelphi .: O site do programador Delphi! :.
|
Exibir mensagem anterior :: Exibir próxima mensagem |
Autor |
Mensagem |
renanbg Colaborador


Registrado: Quinta-Feira, 12 de Abril de 2012 Mensagens: 1158
|
Enviada: Seg Set 18, 2017 3:19 pm Assunto: Livro Caixa, tá quase |
|
|
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 |
|
 |
johnny-walker Moderador


Registrado: Sábado, 4 de Outubro de 2003 Mensagens: 10653 Localização: Contagem/MG - BRAZIL
|
Enviada: Seg Set 18, 2017 7:12 pm Assunto: |
|
|
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 |
|
 |
renanbg Colaborador


Registrado: Quinta-Feira, 12 de Abril de 2012 Mensagens: 1158
|
Enviada: Ter Set 19, 2017 8:01 am Assunto: |
|
|
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 |
|
 |
renanbg Colaborador


Registrado: Quinta-Feira, 12 de Abril de 2012 Mensagens: 1158
|
Enviada: Ter Set 19, 2017 4:56 pm Assunto: |
|
|
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 |
|
 |
renanbg Colaborador


Registrado: Quinta-Feira, 12 de Abril de 2012 Mensagens: 1158
|
Enviada: Ter Set 19, 2017 5:14 pm Assunto: |
|
|
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 |
|
 |
|
|
Enviar Mensagens Novas: Proibido. Responder Tópicos Proibido Editar Mensagens: Proibido. Excluir Mensagens: Proibido. Votar em Enquetes: Proibido.
|
|