Problema na conversão de texto para float
25/02/2006
0
O usuário irá digitar em um campo edit uma série de valores para calcular um determinado desconto acumulado. Exemplo:
edit1.text := ´20+1,5´ o resultador deve aparecer em um outro campo edit.
edt2.text := ´21´
O que não estou conseguindo fazer é pegar a string ´1,5´ e converter em uma variavel float, pois estes numeros podem ser decimais.
A variavel que receberá o valor, defini como currency. Estou transformando o texto através da função strtocurr(), e me retorna o seguinte mensagem: ´´1.5´ is not a valid floating point value´. Antes de fazer a conversão, substituo a ´,´ (virgula) pelo ´.´ (ponto).
Onde está o erro?
Rodolfo.pirolo
Posts
26/02/2006
Aroldo Zanela
No caso, você está querendo resolver uma fórmula. Certo? Então, acredito que esta [url=http://forum.devmedia.com.br/viewtopic.php?t=73269&highlight=formula&sid=f0be5a0fa515701209f5bd9d2c014327]thread[/url] poderá ajudá-lo.
26/02/2006
Rodolfo.pirolo
Eu não estou conseguindo transformar a string ´1,5´ que converti para ´1.5´ em um tipo de numero( currency, single).
Toda vez que uso as funcoes strtocurr ou strtofloat o Delphi da a mensagem de erro dizendo que ´1.5 não é um valor de ponto flutuante válido´.
Como posso converter a string ´1.5´ no número 1.5, para poder efetuar os cálculos?
26/02/2006
Aroldo Zanela
Mantenha a vírgula na string, ou seja, não substitua por ponto.
26/02/2006
Rodolfo.pirolo
Não funcionou, estou enviando parte do código, para melhorar nossa discussão. O valor de lr_Perc não é alterado, fica sempre em zero.
Onde estou errando?
Obrigado pela paciencia.
Somente para lembrar, este campo receberá valores assim ´1,5+2,5+3,5+10´.
Parte de código com problema:
procedure TformCadastroDesconto.ed_DescricaoExit(Sender: TObject);
var
li_Pos, li_TotCaract, i : integer;
ls_Texto, ls_Perc : String;
lr_valori, lr_valorf : real;
lr_Perc : single;
begin
inherited;
ls_Texto := trim( ed_descricao.text );
i := 1;
li_Pos := 1;
while i <= length( ls_Texto ) do
begin
If Copy( ls_texto, i, 1) = ´+´ then
begin
ls_Perc := Copy( ls_texto, li_Pos, i - li_Pos);
// ls_perc := stringreplace(ls_perc, ´,´ , ´.´, [rfReplaceAll]);
lr_Perc := StrToFloat( ls_perc );
li_pos := i + 1;
end;
i := i + 1;
end;
end;
27/02/2006
Aroldo Zanela
Assim não funciona mesmo, pois o delphi não efetua interpretação de fórmulas assim. Portanto, voltamos a minha primeira resposta nesta thread, ou seja, será necessário utilizar algum componente de terceiro para implementar isso no seu sistema, ou ainda, montar um algoritmo para decomposição e cálculo da expressão.
27/02/2006
Aroldo Zanela
hehehehehehe Desculpe, acordei agora e nem li direito o seu tópico. Agora vi que já fez o ´referido´ algoritmo. Vou olhar com calma e ver se posso ajudar.
27/02/2006
Aroldo Zanela
Criei uma classe denominada de TFormula para implementar essa rotina:
TFormula = class(TObject) private FFormula: String; FResultado: String; procedure SetFormula(const Value: String); public property Formula: String read FFormula write SetFormula; property Resultado: String read FResultado; function ParseInput(LineData: string): Boolean; end;
Para validar se a entrada está correta (dentro do que se espera) temos a implementação da função ParseInput:
{ TFormula } function TFormula.ParseInput(LineData: string): Boolean; var ValidChars: set of Char; I, N: SmallInt; begin ValidChars := [´0´,´1´,´2´,´3´,´4´,´5´,´6´,´7´,´8´,´9´,´,´,´+´]; N := Length(LineData); Result:= True; for I := 1 to N do begin if not (LineData[I] in ValidChars) then begin Result := False; Break; end; end; end;
Na procedure SetFormula, fazemos a implementação para obtenção do resultado:
procedure TFormula.SetFormula(const Value: String); var I, iPos, iLength: Integer; ClearLine: string; xValue: Double;// Valor numérico sValue: string;// Parte da formula com um valor "válido" begin FFormula := Value; // "Setar valor ao atributo" ClearLine := Value; // Atribuir o valor de entrada a variável "Linha limpa" {Verificar se a entrada contém apenas caracteres válidos} if ParseInput(Value) then begin iLength := Length(Value); // Pega o comprimento da linha iPos := Pos(´+´, ClearLine); xValue:= 0; while iPos>0 do begin sValue := Copy(ClearLine,1,iPos-1); xValue := xValue + StrToFloat(sValue); ClearLine:= Copy(ClearLine, iPos+1, iLength); iPos := Pos(´+´, ClearLine); end; if Length(ClearLine)>0 then begin xValue:= xValue + StrToFloat(ClearLine); end; FResultado := FloatToStr(xValue); end else FResultado := ´Entrada inválida.´; end;
Finalmente, para testar, codificamos a seguintes instruções no manipulador de eventos OnClick de um botão:
procedure TForm1.btnCALCULARClick(Sender: TObject); var Formula: TFormula; begin Formula:= TFormula.Create; Formula.Formula:= edtFORMULA.Text; edtRESULTADO.Text:= Formula.Resultado; Formula.Free; end;
Ah! sim, tem como fazer mais simples, mas hoje é feriado... :-)
27/02/2006
Rodolfo.pirolo
Foi muito mais do que eu queria, voce deu uma verdadeira aula. Baseado nos seus exemplos encontrei onde estava a falha no meu cálculo.
Vou estudar a sua rotina com atenção.
Valeu pela ótima explicação.
Muito obrigado,
Bom final de carnaval.
Abraços
Rodolfo
Clique aqui para fazer login e interagir na Comunidade :)