Problema na conversão de texto para float

25/02/2006

0

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?


Rodolfo.pirolo

Rodolfo.pirolo

Responder

Posts

26/02/2006

Aroldo Zanela

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.


Responder

26/02/2006

Rodolfo.pirolo

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?


Responder

26/02/2006

Aroldo Zanela

Colega,

Mantenha a vírgula na string, ou seja, não substitua por ponto.


Responder

26/02/2006

Rodolfo.pirolo

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;


Responder

27/02/2006

Aroldo Zanela

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.


Responder

27/02/2006

Aroldo Zanela

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.


Responder

27/02/2006

Aroldo Zanela

Colega,

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... :-)


Responder

27/02/2006

Rodolfo.pirolo

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


Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar