Fórum Problema na conversão de texto para float #314357
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
Curtir tópico
+ 0Posts
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.
Gostei + 0
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?
Gostei + 0
26/02/2006
Aroldo Zanela
Mantenha a vírgula na string, ou seja, não substitua por ponto.
Gostei + 0
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;
Gostei + 0
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.
Gostei + 0
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.
Gostei + 0
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... :-)
Gostei + 0
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
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)