Problema na conversão de texto para float
Estou com o seguinte problema:
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?
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
Curtidas 0
Respostas
Aroldo Zanela
25/02/2006
Colega,
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.
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.
GOSTEI 0
Rodolfo.pirolo
25/02/2006
Aroldo,
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?
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?
GOSTEI 0
Aroldo Zanela
25/02/2006
Colega,
Mantenha a vírgula na string, ou seja, não substitua por ponto.
Mantenha a vírgula na string, ou seja, não substitua por ponto.
GOSTEI 0
Rodolfo.pirolo
25/02/2006
Aroldo,
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;
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;
GOSTEI 0
Aroldo Zanela
25/02/2006
Colega,
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.
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.
GOSTEI 0
Aroldo Zanela
25/02/2006
Colega,
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.
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.
GOSTEI 0
Aroldo Zanela
25/02/2006
Colega,
Criei uma classe denominada de TFormula para implementar essa rotina:
Para validar se a entrada está correta (dentro do que se espera) temos a implementação da função ParseInput:
Na procedure SetFormula, fazemos a implementação para obtenção do resultado:
Finalmente, para testar, codificamos a seguintes instruções no manipulador de eventos OnClick de um botão:
Ah! sim, tem como fazer mais simples, mas hoje é feriado... :-)
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... :-)
GOSTEI 0
Rodolfo.pirolo
25/02/2006
Aroldo,
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
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
GOSTEI 0