Fórum Somando por Mês #198308
02/12/2003
0
Tenho um código simples para somar valores de um determinado campo em uma tabela. Tentei fazer com que somasse somente o mês corrente, mas isso não está acontecendo. Já rodei o forum todo, usei exemplos, mas ainda não sei o que estou errando.
Além disso, ao entrar no form ele realiza o cálculo numa boa. Ao sair do form e clicar em um dbGrid com os dados da tabela de origem do cálculo, quando volto ao form onde se realiza o cálculo, volta só no dia atual, e não o mês, e se eu saio e volto novamente, fica zerado!!!
Deu barato aki, acho que é o sono... já li e reli o código, e realmente não sei quem fiz!!
segue o código (que está no evento on show do form):
(* TSHISTÓRICO - SALDOS DE EXPEDIENTE *) procedure TfrmExpediente.tsHistShow(Sender: TObject); var Ent, Sai, TME, TMS, Hoje, SomaE, SomaS : Currency; begin Hoje := 0; Ent := 0; TME := 0; SomaE := 0; Sai := 0; TMS := 0; SomaS := 0; DMExp.tblLancEntrada.DisableControls; DMExp.tblLancSaida.DisableControls; try (* SOMA AS ENTRADAS DO DIA *) DMExp.tblLancEntrada.First; if DMExp.tblLancEntrada.FieldByName(´DATA´).AsDateTime = Date then begin while not DMExp.tblLancEntrada.EOF do begin Ent := Ent + DMExp.tblLancEntrada.FieldByName(´VALOR´).AsCurrency; DMExp.tblLancEntrada.Next; end; end; (* SOMA AS SAÍDAS DO DIA *) DMExp.tblLancSaida.First; while not DMExp.tblLancSaida.EOF do begin if DMExp.tblLancSaidaDATA.Value = Date then Sai := Sai + DMExp.tblLancSaida.FieldByName(´VALOR´).AsCurrency; DMExp.tblLancSaida.Next; end; (* SOMA AS ENTRADAS DO MES *) DMExp.tblLancEntrada.First; repeat begin while not DMExp.tblLancEntrada.EOF do begin TME := TME + DMExp.tblLancEntrada.FieldByName(´VALOR´).AsCurrency; DMExp.tblLancEntrada.Next; end; end; until DMExp.tblLancEntrada.Eof; (* SOMA AS SAÍDAS DO MES *) DMExp.tblLancSaida.First; repeat begin while not DMExp.tblLancSaida.EOF do begin TMS := TMS + DMExp.tblLancSaida.FieldByName(´VALOR´).AsCurrency; DMExp.tblLancSaida.Next; end; end; until DMExp.tblLancSaida.Eof; finally DMExp.tblLancEntrada.EnableControls; DMExp.tblLancSaida.EnableControls; DMExp.tblLancEntrada.First; DMExp.tblLancSaida.First; DMExp.tblSaldos.Edit; DMExp.tblSaldosENTRADA.Value := TME; DMExp.tblSaldosSAIDA.Value := TMS; editTotDiaE.Text := FormatFloat(´R$ #,0.00´, Ent); editTotDiaS.Text := FormatFloat(´R$ ,0.00´, Sai); editSaldoAnterior.Text := FormatFloat(´R$ ,0.00´, (TME - Ent)-(TMS - Sai)); editSaldoAtual.Text := FormatFloat(´R$ #,0.00´, TME - TMS); editSomasE.Text := FormatFloat(´R$ ,0.00´,TME-(TMS-SAI)); editSomasS.Text := FormatFloat(´R$ ,0.00´,TME-TMS+Sai); end; end;
Toda ajuda é bem vinda...
[]s
Douglas.
Douglas Bitencourt
Curtir tópico
+ 0Posts
02/12/2003
Yankleber
Não deu para sacar qual o problema que está ocorrendo, mas vou te dar umas dicas...
1) não é preciso usar begin-end dentro do repeat-until:
2) por que você está usando um while-do dentro de um repeat-until? Você está fazendo o mesmo teste duas vezes, e isso é uma carga desnecessária de processamento além de um erro feio de programação.
Ao invés de:
repeat begin while not DMExp.tblLancEntrada.EOF do begin TME := TME + DMExp.tblLancEntrada.FieldByName(´VALOR´).AsCurrency; DMExp.tblLancEntrada.Next; end; end; until DMExp.tblLancEntrada.Eof;
você deveria usar:
while not DMExp.tblLancEntrada.EOF do begin TME := TME + DMExp.tblLancEntrada.FieldByName(´VALOR´).AsCurrency; DMExp.tblLancEntrada.Next; end;
Também não entendi porque motivo você usou o [b:2c48ba8324]try[/b:2c48ba8324]. Normalmente ele só é usado quando você vai realizar alguma operação que possa causar um runtime error (erro em tempo de execução) e nunca em uma operação normal. Se você está com medo de causar um erro por tentar fazer um loop do tipo ´while not eof´ em uma tabela vazia, pode testar primeiro se existe algum registro nela assim:
if not DMExp.tblLancEntrada.EOF then begin while not DMExp.tblLancEntrada.EOF do begin TME := TME + DMExp.tblLancEntrada.FieldByName(´VALOR´).AsCurrency; DMExp.tblLancEntrada.Next; end; end;
Finalmente, seria uma boa idéia antes de rodar qualquer loop deste, mover o ponteiro para o início da tabela (primeiro registro) através do método [b:2c48ba8324]First[/b:2c48ba8324], assim:
DMExp.tblLancEntrada.First; if not DMExp.tblLancEntrada.EOF then begin while not DMExp.tblLancEntrada.EOF do begin TME := TME + DMExp.tblLancEntrada.FieldByName(´VALOR´).AsCurrency; DMExp.tblLancEntrada.Next; end; end;
Ah, finalmente: cuidado com a sua indentação, para tornar seu código mais legível!!!
Espero ter ajudado...
Gostei + 0
02/12/2003
Douglas Bitencourt
Obrigado pela pronta resposta. Já ajudou bastante sim. Arrumei um pouco o código.
O que pretendo com esse código é somar as entradas e saídas do [b:aa83e208bd]dia[/b:aa83e208bd] e o total de entradas e saídas do [b:aa83e208bd]mês[/b:aa83e208bd]. E colocar estes valores em edits.
Obrigado pelos toques, realmente ta ruim o código, eu to programando desde o começo deste ano e ainda não peguei a manha. To aprendendo através de livros que comprei e o código que passei como referência, a maior parte peguei aky no forum, inclusive a parte do try/finaly.
Eu estou usando este código para identificar o mês:
var ... Dia, Mes, Ano : word; begin ... DecodeDate(Date,Ano,Mes,Dia); ... if DMExp.tblLancEntrada.FieldByName(´DATA´).AsDateTime = Mes then
Acho que não estou usando o código de forma correta para pegar o mês atual e calcular o total.
A propósito, minha indentação tá um lixo né?
[]s
Douglas.
Gostei + 0
02/12/2003
Douglas Bitencourt
Ainda estou com problemas com este código. Não estou conseguindo realizar o saldo por mês.
Fiz as alterações sugeridas pelo YanKleber, porém, o mensal ainda não funciona.
O que estou tentando fazer é, ao abrir o formulário, seja informado o total de entradas e saídas por dia atual(isso já funciona), e o total de entradas e saídas por mês (isso ainda não funciona).
Peço encarecidamente a ajuda de alguém neste particular.
Se precisar de mais detalhes informo, mas acho que o código das msgs anteriores já deve servir.
Desde já obrigado.
Douglas.
Gostei + 0
02/12/2003
Yankleber
Você moveu o ponteiro da tabela para a primeira posição usando o First?
Gostei + 0
02/12/2003
Douglas Bitencourt
isso já estava e seguindo seus conselhos me lembrei que tenho uma filtragem via código na tabela principal.
segue o que fiz:
{ cálculo do total do dia }
DMExp.tblLancEntrada.Filtered := false; //desliguei o filtro no onshow deste form
DMExp.tblLancSaida.Filtered := false;
DMExp.tblLancEntrada.First; //para o início da tabela
while not DMExp.tblLancEntrada.EOF do begin
if DMExp.tblLancEntrada.FieldByName(´DATA´).AsDateTime = Date then begin //esta linha permite somar pelo dia atual...
Ent := Ent + DMExp.tblLancEntrada.FieldByName(´VALOR´).AsCurrency;
DMExp.tblLancEntrada.Next;
end;
end;
DMExp.tblLancSaida.First; //para o início da tabela
while not DMExp.tblLancSaida.EOF do begin
if DMExp.tblLancSaida.FieldByName(´DATA´).AsDateTime = Date then begin
Sai := Sai + DMExp.tblLancSaida.FieldByName(´VALOR´).AsCurrency;
DMExp.tblLancSaida.Next;
end;
end;
Tentei usar isso para calcular por mês inteiro (digo o mês atual somente), e não funcionou. Tá somando todos os registros da tabela.
Eis o código:
{ cálculo do total do mês }
DecodeDate(Data,Ano,Mes,Dia);
...
DMExp.tblLancEntrada.First; //para o início da tabela
while not DMExp.tblLancEntrada.EOF do begin
if DMExp.tblLancSaida.FieldByName(´DATA´).AsDateTime = Mes then begin //pegaria o mês atual, mas...
TME := TME + DMExp.tblLancEntrada.FieldByName(´VALOR´).AsCurrency;
DMExp.tblLancEntrada.Next;
end;
end;
DMExp.tblLancSaida.First; //para o início da tabela
while not DMExp.tblLancSaida.EOF do begin
if DMExp.tblLancSaida.FieldByName(´DATA´).AsDateTime = Mes then begin
TMS := TMS + DMExp.tblLancSaida.FieldByName(´VALOR´).AsCurrency;
DMExp.tblLancSaida.Next;
end;
end;
Onde estou errando?
Obrigado,
Douglas.
Gostei + 0
03/12/2003
Douglas Bitencourt
Informo que consegui resolver este problema.
Agradeço sua dedicação e empenho, pois, suas dicas foram de imensa valia (quanta formalidade)...
O que quero dizeré: Obrigado Mesmo!!! :)
segue a solução para este caso que descrevo em maiores detalhes abaixo.
procedure Formulario.FormShow(Sender: TObject);
var
Ent, Sai, TME, TMS : Currency;
begin
{
Inicializa as variáveis de valor em zero, evitando erros de cálculo por acumulo de valor
Ent = entradas / Sai = Saídas / TME = total entradas / TMS = total saídas
}
Ent := 0; TME := 0;
Sai := 0; TMS := 0;
{Desabilita o filtro nas tabelas de entrada e saída evitando erros de cálculo}
TabelaEntrada.Filtered := false;
TabelaSaida.Filtered := false;
Tabela.DisableControls;
Tabela.DisableControls;
{
Inicia um novo filtro para calcular pelo dia.
O filtro recebe a data do sistema.
Total de Entradas e Saídas do Dia.
}
TabelaEntrada.Filter:=´[DATA]=´ + DateToStr(Date);
TabelaEntrada.Filtered := true;
TabelaEntrada.First;
while not TabelaEntrada.EOF do begin
Ent := Ent + TabelaEntrada.FieldByName(´CAMPO_VALOR´).AsCurrency;
TabelaEntrada.Next;
end;
TabelaSaida.Filter:=´[DATA]=´ + DateToStr(Date);
TabelaSaida.Filtered := true;
TabelaSaida.First;
while not TabelaSaida.EOF do begin
Sai := Sai + TabelaSaida.FieldByName(´CAMPO_VALOR´).AsCurrency;
TabelaSaida.Next;
end;
TabelaEntrada.EnableControls;
TabelaSaida.EnableControls;
{
Novamente desabilita os filtros o que evita erro de cálculo
Total de Entradas e de Saídas das tabelas (Total Geral).
}
TabelaEntrada.Filtered := false;
TabelaSaida.Filtered := false;
TabelaEntrada.DisableControls;
TabelaSaida.DisableControls;
TabelaEntrada.First;
while not TabelaEntrada.EOF do begin
TME := TME + TabelaEntrada.FieldByName(´CAMPO_VALOR´).AsCurrency;
TabelaEntrada.Next;
end;
TabelaSaida.First;
while not TabelaSaida.EOF do begin
TMS := TMS + TabelaSaida.FieldByName(´CAMPO_VALOR´).AsCurrency;
TabelaSaida.Next;
end;
TabelaEntrada.EnableControls;
TabelaSaida.EnableControls;
{
Exibe os resultados em Edits formatados realizando os cálculos
}
editTotDiaE.Text := FormatFloat(´R$ #,0.00´, Ent);
editTotDiaS.Text := FormatFloat(´R$ ,0.00´, Sai);
editSaldoAnterior.Text := FormatFloat(´R$ ,0.00´, ((TME - TMS)-(Ent - Sai)));
editSaldoAtual.Text := FormatFloat(´R$ ,0.00´, (TME - TMS));
end;
Talvez não seja o mais prático ou mais simples, mas foi o que funcionou.
:)
Mais uma vez obrigado.
Douglas.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)