Ajuda com campo calculado

Delphi

03/08/2009

Pessoal,

Montei uma query que monta um fluxo de contas. Algo mais ou menos assim

SELECT * FROM (
SELECT DATA,
       0 AS ENTRADA,
       VALOR AS SAIDA,
       ´PAGAR´ AS TIPO
  FROM CONTAS_PAGAR

UNION

SELECT DATA,
       VALOR AS ENTRADA,
       0 AS SAIDA,
       ´RECEBER´ AS TIPO
  FROM CONTAS_RECEBER
) CONTAS
 ORDER BY 1, 2


Essa select une as duas tabelas de contas (pagar e receber) e me monta um resultado como um livro caixa.

Aí, no objeto Query do Delphi criei um [b:1f30dfdc71]campo calculado [/b:1f30dfdc71]chamado [b:1f30dfdc71]SALDO[/b:1f30dfdc71]. No [b:1f30dfdc71]OnCalcField [/b:1f30dfdc71]da tabela eu uso o seguinte código:

Saldo := Saldo + qContasENTRADA.Value - qContasSAIDA.Value;
   qContasSALDO.Value := Saldo;


Detalhe: no [b:1f30dfdc71]BeforeOpen [/b:1f30dfdc71]da tabela [b:1f30dfdc71]eu zero a variável saldo[/b:1f30dfdc71].

Após o open a tabela abre certinha, com todos saldos OK. [u:1f30dfdc71][i:1f30dfdc71][b:1f30dfdc71]O problema é que ao rolar a tela do DBGrid ele sai recalculando tudo e com valores errados.[/b:1f30dfdc71][/i:1f30dfdc71][/u:1f30dfdc71]

Já fui até no BeforeScroll e coloquei Saldo := 0 mas não resolveu.

O OnCalcField deveria recalcular o valor conforme eu rolo a tela? Alguma sugestão de correção para esse problema?


Willian

Willian

Curtidas 0

Respostas

Emerson Nascimento

Emerson Nascimento

03/08/2009

qual o resultado que você espera? apresente um exemplo.


GOSTEI 0
Willian

Willian

03/08/2009

Vamos lá!!! :D

Estou usando a seguinte select:

SELECT * FROM ( 
SELECT DATA, 
       0 AS ENTRADA, 
       VALOR AS SAIDA, 
       ´PAGAR´ AS TIPO 
  FROM CONTAS_PAGAR 

UNION 

SELECT DATA, 
       VALOR AS ENTRADA, 
       0 AS SAIDA, 
       ´RECEBER´ AS TIPO 
  FROM CONTAS_RECEBER 
) CONTAS 
 ORDER BY 1, 2


Essa SELECT me retorna algo assim:

DATA        ENTRADA    SAIDA    TIPO
--------------------------------------------
01/07/09   50,00          0,00            E
02/07/09   15,00          0,00            E
02/07/09    0,00        35,00            S


No objeto Query que tem a select eu incluí um campo calculado chamado SALDO. Nele eu quero manter o subtotal das operações. O código é assim:

SALDO := SALDO + (ENTRADA - SAIDA);
qTabelaCampoCalculado.Value := SALDO;


Fazendo isso, eu tenho um retorno aparecido com esse:

DATA        ENTRADA    SAIDA    TIPO       SALDO
-------------------------------------------------------------
01/07/09   50,00          0,00            E       50,00 //SALDO 0 + 50
02/07/09   15,00          0,00            E       65,00 //SALDO 50 + 15
02/07/09     0,00        35,00            S       30,00 //SALDO 65 - 35


Isso aparece legal na primeira carga da Query, faz uma montagem muito legal de um ´livro caixa´... o problema é que quando eu rolo a dbgrid que apresenta o resultado ele simplesmente sai recalculando tudo de novo e os valores do campo SALDO simplesmente ficam errados.

No help não cita que o OnCalcField chamado no Scroll. Tô perdido pq é só rolar a barra da dbgrid que ele vem recalculando tudo... :cry: Nem consigo achar algum evento para tentar zerar o saldo antes desse recálculo.

Alguma idéia?


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

03/08/2009

talvez o uso de um ClientDataset com um campo do tipo InternalCalc te ajude melhor nessa empreitada. outro recurso seria trazer o cálculo pronto na intrução SQL (para isso é preciso que você informe qual banco está usando).


GOSTEI 0
Willian

Willian

03/08/2009

Eu tentei fazer isso no banco direto... estou usando SQL Server 2008 Express. Nunca fiz procedure/cursor em banco, então na minha primeira tentativa sai ´isso´:

CREATE PROC [dbo].[FluxoContas]
   @DT_INI  AS DATE,
   @DT_FIM  AS DATE,
   @DT_INI2 AS DATE,
   @DT_FIM2 AS DATE
AS
   
DECLARE @CODIGO AS INTEGER
DECLARE @DATA AS DATE
DECLARE @ENTRADA AS FLOAT
DECLARE @SAIDA AS FLOAT
DECLARE @PESSOA AS NVARCHAR(40)
DECLARE @TIPO AS CHAR(1)
DECLARE @SALDO AS FLOAT

DECLARE MeuCursor SCROLL CURSOR
    FOR 
SELECT CODIGO, DATA, ENTRADA, SAIDA, PESSOA, TIPO FROM (
SELECT C.CODIGO,
       C.DATA_VENCTO AS DATA,
       0 AS ENTRADA,
       C.VALOR_NOMINAL AS SAIDA,
       F.FORNECEDOR AS PESSOA,
       ´P´ AS TIPO
  FROM CONTAS_PAGAR C, FORNECEDORES F
 WHERE C.FORNECEDOR = F.CODIGO
   AND C.DATA_VENCTO >= @DT_INI AND C.DATA_VENCTO <= @DT_FIM
 
 UNION

SELECT C.CODIGO,
       C.DATA_VENCTO AS DATA,
       C.VALOR_NOMINAL AS ENTRADA,
       0 AS SAIDA,
       ´MENSALIDADE´ AS PESSOA,
       ´R´ AS TIPO        
  FROM CONTAS_RECEBER C
 WHERE C.DATA_VENCTO >= @DT_INI2 AND C.DATA_VENCTO <= @DT_FIM2

) 
 CONTAS_TEMP 
 ORDER BY 2, 1
 
 CREATE TABLE #TEMPORARIA (CODIGO BIGINT, DATA DATE, ENTRADA FLOAT, 
                            SAIDA FLOAT, PESSOA NVARCHAR(40), TIPO CHAR(1), SALDO FLOAT) 
 
 OPEN MeuCursor   
FETCH NEXT FROM MeuCursor INTO @CODIGO, @DATA, @ENTRADA, @SAIDA, @PESSOA, @TIPO  

WHILE @@FETCH_STATUS = 0   
BEGIN   
   @SALDO = @SALDO + @ENTRADA - @SAIDA
   INSERT INTO TEMPORARIA VALUES (@CODIGO, @DATA, @ENTRADA, @SAIDA, @PESSOA, @TIPO, @SALDO)
   FETCH NEXT FROM MeuCursor INTO @CODIGO, @DATA, @ENTRADA, @SAIDA, @PESSOA, @TIPO   
END   

CLOSE MeuCursor   
DEALLOCATE MeuCursor

SELECT * FROM #TEMPORARIA


Mas na linha:

@SALDO = @SALDO + @ENTRADA - @SAIDA


Dá erro! A mensagem de erro:

Msg 102, Level 15, State 1, Procedure FluxoContas, Line 52
Incorrect syntax near ´@SALDO´.
Msg 156, Level 15, State 1, Procedure FluxoContas, Line 57
Incorrect syntax near the keyword ´CLOSE´.


Se eu tirar essa linha ele compila e executa... mas não tras absolutamente nada na execução!

Eu aceito qualquer solução: como corrigir isso na Query ou no Banco.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

03/08/2009

tente:
SET @SALDO = @SALDO + @ENTRADA - @SAIDA


GOSTEI 0
Willian

Willian

03/08/2009

:D
Então, ontem à noite... depois de tanto brigar eu tinha descoberto que faltava o SET antes da instrução... agora vi sua resposta... pelo menos confirmou que era esse o problema!!!!!

Valeu pela ajuda, muito obrigado.


GOSTEI 0
POSTAR