Algo eficiente para o controle de saldo?

Delphi

08/05/2010

Pessoal, seguinte:

Estou tentando fazer um controle de banco com saldo, mais da forma que fiz não esta sendo eficiente, pois na hora de alterar o valor o saldo se perde, e fica a maior bagunça

O codigo é este
var
  dblsaldoantes, dblvalor, dblsaldoatual : Double;
begin

  try
    dslocal.DataSet.edit;
    dslocal.DataSet.FieldByName('idempresas').asinteger := strtoint(frmprincipal.lblidempr.caption);
    dslocal.dataset.fieldbyname('cdbanco').AsString     := codbanco.Text;
    if Deb_Cred.ItemIndex = 0 then
       dslocal.dataset.fieldbyname('operacao').AsString := 'D'
    else
       dslocal.dataset.fieldbyname('operacao').AsString := 'C';

    dblsaldoantes := dm.controlebancosSALDOATUAL.AsCurrency;
    dblvalor      := dm.controlebancosVALORMOVIMENTO.AsCurrency;
    if dslocal.dataset.fieldbyname('operacao').AsString = 'C' then
       dblsaldoatual := dblsaldoantes + dblvalor
    else
       dblsaldoatual := dblsaldoantes - dblvalor;
    dslocal.DataSet.FieldByName('saldoatual').AsCurrency := dblsaldoatual;
    //Gravar no banco
    dslocal.DataSet.Post;
    saldoatual.Caption  := Format('%12.2n',[dblsaldoatual]);   //mascarando o label
    //comitando as transações
    dm.connection.Commit;              // referente ao ZConnetcion
    ShowMessage('Dados gravados com sucesso!');
    dslocal.DataSet.Refresh;
  except
    on E: Exception do
    begin
      pt_messagedlg('Atenção! Não foi possível gravar os dados!'+#13+#10+
                    e.message, mtError, [mbOK], 0);
      dm.connection.Rollback;  //referente ao ZConnetcion
      exit;
    end;
  end;


Uso firebird 2.0 e delphi 7

algo assim

saldo inicial-------------------c------------8.000,00-----------8.000,00
deposito--------------------c-------------1.000,00-----------9.000,00
cheque emitido---------------d------------6.000,00-----------3.000,00


etc
Então, se eu gravar pela primeira vez com o codigo que eu fiz, funciona beleza, mais o problema esta se eu for alterar um destes valores ai, neste caso o saldo se perde e vira uma bagunça como ja citei acima.

Na SP eu consigo assim
CREATE PROCEDURE SALDO_BANCO 
RETURNS (
    R_IDBANCOS INTEGER,
    R_DATAMOV DATE,
    R_CODBANCO VARCHAR(3),
    R_TIPOOPERACAO CHAR(1),
    R_HISTORICO VARCHAR(50),
    R_VALORMOVIMENTO NUMERIC(15,2),
    R_SALDOATUAL NUMERIC(15,2))
AS
begin
  r_saldoatual = 0.00;
  for select idbancos, dtmovimento, cdbanco, operacao, historico, valormovimento
             from controlebancos order by idbancos, dtmovimento
             into :r_idbancos, :r_datamov, :r_codbanco,
                  :r_tipooperacao, :r_historico, :r_valormovimento
             do
             begin
               select :r_saldoatual +
                       (case when operacao = 'D' then
                             valormovimento * -1
                        else
                             valormovimento
                        end )
               from controlebancos where idbancos = :r_idbancos
               into :r_saldoatual;
               suspend;
             end
end


Mais queria mesmo fazer isso no aplicativo, e não sei a maneira de fazer.



Adriano Dolce

Adriano Dolce

Curtidas 0

Respostas

Adriano Dolce

Adriano Dolce

08/05/2010

Eu mudei, assim
procedure 
TfrmCad_ControleBancos.btnpostClick(Sender: TObject);


begin





  try


    dslocal.DataSet.edit;


    dslocal.DataSet.FieldByName('idempresas').asinteger := 
strtoint(frmprincipal.lblidempr.caption);


    dslocal.dataset.fieldbyname('cdbanco').AsString     := 
codbanco.Text;


    if Deb_Cred.ItemIndex = 0 then


       dslocal.dataset.fieldbyname('operacao').AsString := 'D'


    else


       dslocal.dataset.fieldbyname('operacao').AsString := 'C';





    {Gravar no banco os dados }


    dslocal.DataSet.Post;


    saldoatual.Caption  := Format('%12.2n',[_retornaSaldo]);  
 //mascarando o label





   {Atualiza o banco com o saldo cfe aplicado na Stored Procedure }


    with qrylocal do


    begin


      close;


      sql.Clear;


      sql.Add (' update controlebancos rec set rec.saldoatual =        
');


      sql.Add ('   (select r_saldoatual spb from                      
 ');


      sql.Add (' saldo_banco spb where spb.r_idbancos = rec.idbancos)  
');


      ExecSQL;


    end;





    { comitando as transações }


    dm.connection.Commit;              // referente ao ZConnetcion


    ShowMessage('Dados gravados com sucesso!');


    dslocal.DataSet.Refresh;


    dsMostraGrade.DataSet.Refresh;


  except


    on E: Exception do


    begin


      pt_messagedlg('Atenção! Não foi possível gravar os 
dados!'+#13+#10+


                    e.message, mtError, [mbOK], 0);


      dm.connection.Rollback;  //referente ao ZConnetcion


      exit;


    end;


  end;





end;


 Usando a stored procedure que eu criei e chamando esta função para visualizar no form


function 
TfrmCad_ControleBancos._retornaSaldo: Currency;


begin


  with qrylocal do


  begin


    close;


    sql.Clear;


    sql.Add(' select * from saldo_banco ');


    open;


    Last;


    Result := fieldbyname('r_saldoatual').AsCurrency;


    Close;


  end;





end;


Minha duvida é, se eu usar este update
{Atualiza o banco com o saldo cfe aplicado na Stored Procedure }



    with qrylocal do



    begin



      close;



      sql.Clear;



      sql.Add (' update controlebancos rec set rec.saldoatual =        
');



      sql.Add ('   (select r_saldoatual spb from                      
 ');



      sql.Add (' saldo_banco spb where spb.r_idbancos = rec.idbancos)  
');



      ExecSQL;



    end;

Para atualizar minha tabela, será que vai ficar lento o sistema?



GOSTEI 0
POSTAR