Ajuda com soma numa variavel, diferença de valores?
07/07/2008
0
Exemplo
é uma soma total
se estiver assim
agora se estiver assim
Se eu colocar uma função para arredondar pra baixo, funciona o segundo resultado
6.274,33 mais o primeiro fica assim 5.783,62
Então pessoal, preciso desta soma exata
O codigo é este aqui
{:Serve para arredondar valores, com duas casas decimais mudando por exemplo de 0,165 para 0,16, ou seja sempre para baixo, tem que declarar a unit math na uses da lib´s} function TfrmEnvioemail.Min_Round(const AValue: Double; const ADigit: TRoundToRange): Double; var LFactor: Double; begin LFactor := IntPower(10, ADigit); Result := Trunc((AValue / LFactor) - 0.5) * LFactor; end; procedure TfrmEnvioemail.ppDetailBand1BeforePrint(Sender: TObject); var TotUnit, TotIPI : double; begin {if dsRelEnviaPed.DataSet.FieldByName(´DESCONTOS´).AsFloat = 0 then dsRelEnviaPed.DataSet.FieldByName(´DESCONTOS´).AsString := ´´;} {:Somas da banda DetailBand} TotUnit := ( dsRelEnviaPed.DataSet.FieldByName(´QTDE´).asFloat * dsRelEnviaPed.DataSet.FieldByName(´VL_UNITARIO´).AsCurrency ); somaValorTotal.Value := (TotUnit * ((100 - dsRelEnviaPed.DataSet.FieldByName(´DESCONTOS´).AsFloat)/100)); {soma indice ipi} TotIPI := ((somaValorTotal.Value * dsRelEnviaPed.DataSet.FieldByName(´indice_ipi´).AsFloat)/100); {:Soma o total dos produtos que vai na banda do Rodapé} SomaTotal.Value := (somaTotal.Value + somaValorTotal.Value); {:Soma total do IPI} SomaIPI.Value := (SomaIPI.Value + TotIPI); {:Soma total Descontos} SomaDesconto.Value := ( SomaDesconto.Value + (( dsRelEnviaPed.DataSet.FieldByName(´VL_UNITARIO´).AsCurrency * dsRelEnviaPed.DataSet.FieldByName(´DESCONTOS´).AsFloat)/100)); {:Soma liquido} // SomaLiquido.Value := Min_Round(( SomaTotal.Value + SomaIPI.Value - SomaDesconto.Value ),-2); SomaLiquido.Value := (SomaTotal.Value + ( SomaIPI.Value - SomaDesconto.Value )); end;
O problema de trazer o resultado final esta aqui
{:Soma liquido} // SomaLiquido.Value := Min_Round(( SomaTotal.Value + SomaIPI.Value - SomaDesconto.Value ),-2); SomaLiquido.Value := (SomaTotal.Value + ( SomaIPI.Value - SomaDesconto.Value ));
Adriano_servitec
Posts
07/07/2008
Aleriopreto
07/07/2008
Adriano_servitec
Fiz uma gambiarra aqui, a principio parece estar funcionando, mais não sei ainda, pois não testei em todos, apenas naqueles que eu vi a diferença
Olhe amigo
procedure TfrmEnvioemail.ppDetailBand1BeforePrint(Sender: TObject); var TotUnit, TotIPI, TotLiquidoMax, TotLiquidoMin : double; begin {:zera as variaveis antes de começar} TotLiquidoMax := 0; TotLiquidoMin := 0; {if dsRelEnviaPed.DataSet.FieldByName(´DESCONTOS´).AsFloat = 0 then dsRelEnviaPed.DataSet.FieldByName(´DESCONTOS´).AsString := ´´;} {:Somas da banda DetailBand} TotUnit := ( dsRelEnviaPed.DataSet.FieldByName(´QTDE´).asFloat * dsRelEnviaPed.DataSet.FieldByName(´VL_UNITARIO´).AsCurrency ); somaValorTotal.Value := (TotUnit * ((100 - dsRelEnviaPed.DataSet.FieldByName(´DESCONTOS´).AsFloat)/100)); {soma indice ipi} TotIPI := ((somaValorTotal.Value * dsRelEnviaPed.DataSet.FieldByName(´indice_ipi´).AsFloat)/100); {:Soma o total dos produtos que vai na banda do Rodapé} SomaTotal.Value := (somaTotal.Value + somaValorTotal.Value); {:Soma total do IPI} SomaIPI.Value := (SomaIPI.Value + TotIPI); {:Soma total Descontos} SomaDesconto.Value := ( SomaDesconto.Value + (( dsRelEnviaPed.DataSet.FieldByName(´VL_UNITARIO´).AsCurrency * dsRelEnviaPed.DataSet.FieldByName(´DESCONTOS´).AsFloat)/100)); {:Soma liquido} SomaLiquido.Value := (SomaTotal.Value + ( SomaIPI.Value - SomaDesconto.Value )); TotLiquidoMax := SomaLiquido.Value; TotLiquidoMax := StrToFloat(FormatFloat(´0.0000´, TotLiquidoMax ) ); TotLiquidoMin := SomaLiquido.Value; TotLiquidoMin := StrToFloat(FormatFloat(´0.00´, TotLiquidoMin ) ); if TotLiquidoMax <> TotLiquidoMin then SomaLiquido.Value := Min_Round((TotLiquidoMax ),-2) else SomaLiquido.Value := ( TotLiquidoMin ); end;
Ou seja criei + duas variaveis e passei uma condição com if de comparação para dentro delas para verificar se ha diferença entre uma e outra
{:Soma liquido} SomaLiquido.Value := (SomaTotal.Value + ( SomaIPI.Value - SomaDesconto.Value )); TotLiquidoMax := SomaLiquido.Value; TotLiquidoMax := StrToFloat(FormatFloat(´0.0000´, TotLiquidoMax ) ); TotLiquidoMin := SomaLiquido.Value; TotLiquidoMin := StrToFloat(FormatFloat(´0.00´, TotLiquidoMin ) ); if TotLiquidoMax <> TotLiquidoMin then SomaLiquido.Value := Min_Round((TotLiquidoMax ),-2) else SomaLiquido.Value := ( TotLiquidoMin );
Bom amigo, vou ver aqui se assim vai funcionar.
Mais se alguem tiver uma idéia 100¬ sobre este problema de arredondamento estejam a vontade para postar.
07/07/2008
Adriano_servitec
Olhe no D7
function SimpleRoundTo(const AValue: Double; const ADigit: TRoundToRange = -2): Double; var LFactor: Double; begin LFactor := IntPower(10, ADigit); Result := Trunc((AValue / LFactor) + 0.5) * LFactor; end;
e olhe no BDS2006
function SimpleRoundTo(const AValue: Double; const ADigit: TRoundToRange = -2): Double; var LFactor: Double; begin LFactor := IntPower(10, ADigit); if AValue < 0 then Result := Trunc((AValue / LFactor) - 0.5) * LFactor else Result := Trunc((AValue / LFactor) + 0.5) * LFactor; end;
Eu não tinha reparado nisso, fiz esta função quando estava usando o D7 pq não retornava pra baixo, mais parece que eles arrumaram como estou vendo ai.
Vou testar então.
Qualquer coisa volto a postar.
07/07/2008
Adriano_servitec
Obrigado.
08/07/2008
Luiz Henrique
Tambem ja enfrentei este tipo de problema, consegui solucionar, padraonizando os arredondamentos com uma funcao que fiz aqui e nao deixo calculos de multiplicacao ou divisao para o banco ou componente de relatorio.
É enrolado mesmo...
08/07/2008
Adriano_servitec
Tambem ja enfrentei este tipo de problema, consegui solucionar, padraonizando os arredondamentos com uma funcao que fiz aqui e nao deixo calculos de multiplicacao ou divisao para o banco ou componente de relatorio.
É enrolado mesmo...[/quote:7613986e0a]Olá [b:7613986e0a]Luiz Henrique[/b:7613986e0a], se vc puder passar o esquema da função ficarei grato.
Obrigado amigo.
09/07/2008
Emerson Nascimento
por conta do arredondamento, não é possível fazer direto.
eu faria assim:
{Serve para arredondar valores, com duas casas decimais mudando, por exemplo de 0,165 para 0,16. ou seja sempre para baixo. tem que declarar a unit math na uses da lib´s} function Min_Round(const AValue: Double; const ADigit: TRoundToRange): Double; var LFactor: Double; begin LFactor := IntPower(10, ADigit); Result := Trunc(AValue * LFactor) / LFactor; end;
e gravaria cada valor já arredondado:
procedure TfrmEnvioemail.ppDetailBand1BeforePrint(Sender: TObject); var TotUnit, TotIPI, Desconto: double; begin {if dsRelEnviaPed.DataSet.FieldByName(´DESCONTOS´).AsFloat = 0 then dsRelEnviaPed.DataSet.FieldByName(´DESCONTOS´).AsString := ´´;} {:Somas da banda DetailBand} TotUnit := Min_Round( dsRelEnviaPed.DataSet.FieldByName(´QTDE´).asFloat * dsRelEnviaPed.DataSet.FieldByName(´VL_UNITARIO´).AsCurrency, 2 ); somaValorTotal.Value := Min_Round( TotUnit * ((100 - dsRelEnviaPed.DataSet.FieldByName(´DESCONTOS´).AsFloat)/100), 2 ); {:Soma indice ipi} TotIPI := Min_Round( (somaValorTotal.Value * dsRelEnviaPed.DataSet.FieldByName(´indice_ipi´).AsFloat)/100, 2 ); {:Soma o total dos produtos que vai na banda do Rodapé} SomaTotal.Value := (somaTotal.Value + somaValorTotal.Value); {:Soma total do IPI} SomaIPI.Value := SomaIPI.Value + TotIPI; {:Soma total Descontos} SomaDesconto.Value := SomaDesconto.Value + (TotUnit - somaValorTotal.Value); {:Soma liquido} SomaLiquido.Value := SomaTotal.Value + SomaIPI.Value; end;
10/07/2008
Luiz Henrique
Posto postar sim, so que tem um problema, uso algumas funcoes dentro dela tbm minha, mas vejo que vc nao é um ´iniciante´ e vai entender a funcao, qualquer coisa ai me avisa, desculpe se ela ta escrita meio ´esquisita´ e que é antiga e nao reescrevi ela novamente:
function Arredondar(__numero: variant; __tam, _dec: integer): variant;
var _bk_tam, __tam_nr: integer; __nr_real, __nr_dec,__vlr_p_a:real;
__bk_nr_dec: variant;
__string: string;
begin
__bk_nr_dec:= frac(__numero);
__string:= formatfloat(´#0.00000000´,__numero*10); //str((__bk_nr_dec*10):12:8,__string);
if (val(__string) <> val(´1´)) then begin
__nr_dec:= 0; //inicializa para
__string:= formatfloat(stringofchar(´´,__tam-1)+´0.´+stringofchar(´0´,_dec+1),__nr_dec);//__numero); //str(__nr_dec:__tam:_dec,__string); //montar real casa do dec parametro pedido;
__string:= trim(__string)+´1´; //soma valor que servira p/ajuste no arredondamento
__vlr_p_a:= val(__string);
__nr_dec:= frac(__numero)+__vlr_p_a;
__string:= formatfloat(stringofchar(´#´,__tam-1)+´0.´+
stringofchar(´0´,_dec+1),__nr_dec); //__numero); //str(__nr_dec:__tam:(_dec+1),__string);
__string:= sonumero(__string);
__tam_nr:= length(__string);
__string:= copy(__string,1,__tam_nr-1)+DecSep+copy(__string,__tam_nr,1);
__nr_real:= val(__string);
__nr_real:= round(__nr_real);
__string:= strzero(__nr_real,_dec);
if __nr_real = 100 then __numero:= int(__numero) + 1
else __numero:= int(__numero)+val(´0´+DecSep+trim(__string));
end;
result:= __numero;
end;
espero que ajude, t+
10/07/2008
Adriano_servitec
Vou analisar a sua formula amigo, pode ser que venha a me ajudar em outros calculos também.
Obrigado a todos.
Problema resolvido
Mudaram a resposta spambot, eu nem tinha visto...demorei para conseguir postar sem ler que tinham mudado :D
Clique aqui para fazer login e interagir na Comunidade :)