StrToFloat avec séparateur de milliers = un espace [Résolu]

Signaler
Messages postés
40
Date d'inscription
mardi 28 novembre 2006
Statut
Membre
Dernière intervention
3 août 2010
-
Messages postés
1
Date d'inscription
lundi 11 décembre 2000
Statut
Membre
Dernière intervention
6 février 2012
-
Bonjour,
Je travaille avec Delphi 7.
Le séparateur de milliers défini comme paramètre régional est un espace. Ex : 38 256.28
J'encode mes données dans un tableau sous forme de string:

Table8[2,ct1] := FloatToStrF(Table8T2,ffNumber,9,0);

Je veux maintenant utiliser la valeur encodée dans un calcul :

test := StrToFloat(Table8[2,ct1])*10 ;

Lorsque je lance l'application je reçois comme message d'erreur : classe d'exception EConvertError ... '38 256' n'est pas une valeur en virgule flottante correcte.

Or dans un autre programme où j'applique les mêmes technique, je n'ai aucun problème.

Qui peut m'aider?

G. PLETINCKX

19 réponses

Messages postés
4719
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
1 février 2021
14
Bonsoir,

faudrait pas stocker le format, mais plutôt l'appliquer lorsque tu en as besoin..

cantador
Messages postés
2527
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
16 octobre 2019
18
Salut,

Je suis d'accord avec Cantador. Surtout pour des valeurs que tu dois réutiliser dans des calculs...
Sinon, tu peux adapter ça à tes besoins:

function FormatedFloatToFloat(FloatString, ThousSep:String; var E:Extended):Integer;
  begin
  val(StringReplace(FloatString,ThousSep,'',[rfReplaceAll]),E,Result);
end;






{Utilisation}
procedure TForm1.Button1Click(Sender: TObject);
  var        E : Extended;
              S : String;
  begin
  S := '1 000.10';
  if FormatedFloatToFloat(S,' ',E) = 0 then Edit1.Text := Floattostr(E)
     else MessageDlg('Erreur en position:'
           +IntToStr(FormatedFloatToFloat(S,' ',E)),mtWarning,[mbOk],0);
end;
Messages postés
40
Date d'inscription
mardi 28 novembre 2006
Statut
Membre
Dernière intervention
3 août 2010

Salut,

Je stocke en str pour l'imprimer.
Et j'ai utilisé StringReplace :

StrToInt(StringReplace(Table8[2,ct1], ' ', '', [rfReplaceAll]));

Le but est d'introduire les chiffres dans un graphique. Donc str est suffisant.

Merci pour votre aide.

G. PLETINCKX
Messages postés
3826
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
10 mai 2021
44
@Caribensila:
c'est quoi le problème avec la variable j'ai pas bien saisi le souci
normale elle est insaisissable

 
@+
Cirec

<hr siz="" />
Messages postés
40
Date d'inscription
mardi 28 novembre 2006
Statut
Membre
Dernière intervention
3 août 2010

La variable vaut dans les 10 000.00;
Donc pas de souci qu'elle vaille 0.
Quand tu dis insaisissable, tu entends quoi?

G. PLETINCKX
Messages postés
3826
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
10 mai 2021
44
"

La variable vaut dans les 10 000.00;"
attention c'est très important
la variable en String vaut
10 000.00 ?

10 000,00 ?

"Quand tu dis insaisissable, tu entends quoi?"
cette partie s'adresse à Caribensila en réponse à son dernier message 
 
@+
Cirec

<hr siz="" />
Messages postés
40
Date d'inscription
mardi 28 novembre 2006
Statut
Membre
Dernière intervention
3 août 2010

si tu regardes dans le dessus du code, le tableau est créé par:

Table2[5,ct1] := (FloatToStrF(Donnees.QStatGenMOYBRUT.AsFloat,ffNumber,9,0));

donc la valeur est devenue 10 000. Il n'y a pas de décimales.

G. PLETINCKX
Messages postés
3826
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
10 mai 2021
44
oui j'ai bien compris mais ma question portait sur le caractère des décimales utilisé dans l'enregistrement en String

si le String est enregistré avec un point "."   ------ >'10 000.00'
ou avec une virgule comme il devrait l'être par défaut ","  --- >'10 000,00'

donc tu fais:
Var
S : String;
begin
  S := Table2[5,ct1];
end;

et tu me donnes la valeur de S
 
@+
Cirec

<hr siz="" />
Messages postés
40
Date d'inscription
mardi 28 novembre 2006
Statut
Membre
Dernière intervention
3 août 2010

LA valeur de S est une valeur entière car le format de (FloatToStrF(Donnees.QStatGenMOYBRUT.AsFloat,ffNumber,9,0)) est sans chiffre après la virgule. Mais le signe des décimales est le point et non la virgule.
La valeur de S en l'occurence est bien "10 000" sans point ni chiffre après la virgule.

G. PLETINCKX
Messages postés
2527
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
16 octobre 2019
18
@Cirec

Quand je dis que "

ThousandSepartor" est une variable insaisissable, c'est à cause de ça :


var  S : string;
      C : Char;
  begin
  S := '1 000.21';
  C := ' ';
  Edit1.Text := IntToStr(pos(C,S)); // <-- ça marche ' ' est bien en 2ème place.
  C := ThousandSeparator;  //ThousandSeparator est une variable de type Char
  Edit1.Text := IntToStr(pos(C,S)); // <-- ça marche pas. Revoie 0.
  //pourtant
  Edit1.Text := '___'+C+'___';  // <-- ça marche.
Messages postés
3826
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
10 mai 2021
44
bon j'ai essayé dans tous les sens et je n'ai pas réussit à reproduire ton problème !!!!
Désolé.

@Caribensila:

l'explication en est toute simple
ThousandSeparator = #0160
et nous on met un espace = #32

donc si à la place de mettre un espace tu mets Alt+0160 ça fonctionne

 
@+
Cirec

<hr siz="" />
Messages postés
2527
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
16 octobre 2019
18
Aaaaaaah ouais !

Alors, il n'est pas exact de dire que ThousandSeparator est un espace.
Il faut dire que ThousandSeparator est le caractère chr(0160)... 

Merci Cirec. 
Messages postés
3826
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
10 mai 2021
44
tout mais pas StringReplace !!!!!
il est bien trop gourmand en temps et en ressources

@ Caribensila:

ton code est bien beau mais ne respecte pas les "standards"
FloatToStr convertit (par défaut en Français) le point "." en virgule ","
de ce fait ton code n'est pas exacte puisqu'il faut avoir S = '1000 .
10' alors
que les fonctions retournent S = '1000,
10'

voici un bout de code qui est au moins 100 fois plus rapide que StringReplace et qui respecte les normes locales:

Function trouvé sur Codyx
Function ExcludeChars(Const S : String;
Const CS : TSysCharSet): String;
Var P,
PR : PByte;
    Size, I : Integer;
Begin

  P := PByte(S);
  Size := Length(S);
  SetLength(Result,
Size);
  PR := PByte(Result);
  I := 0;

   While P^ <> $0  Do
  Begin
    If Not
(Chr(P^) In CS) Then
    Begin
      Pr^ : = P^;

      Inc(Pr);
    End
    Else
Inc(I);
      Inc(P);
  End;
  If I
> 0  Then
SetLength(Result, Size - I)
End;

Procedure
TForm1.Button1Click(Sender: TObject);
Var
S : String;
Begin
  S := '1
000,10';
  Edit1.Text := Floattostr(StrToFloat(ExcludeChars(S, [' '])));
End ;
 
@+
Cirec

<hr siz ="" />
Messages postés
2527
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
16 octobre 2019
18
T'as raison Cirec. Comme d'hab!   :)



Mais je me suis surtout heurté à "ThousandSepartor" en tant que paramètre de fonction, pendant mes recherches...
T'aurais pas des infos sur cette variable insaisissable?
Histoire de pouvoir faire :

function FormatedFloatToFloat(FloatString: String; ThousandSepartor: Char; var E: Extended): Integer;
Messages postés
40
Date d'inscription
mardi 28 novembre 2006
Statut
Membre
Dernière intervention
3 août 2010

Désolé mais le réponse que j'obtiens dans mon code est 0 au lieu de la valeur recherchée.
Voici mon code:

  For ct1 := 0 To 7 Do
    Begin
      test := StrToInt(StringReplace(Table2[2,ct1], ' ', '', [rfReplaceAll]));
      S := Table2[2,ct1];
      test1 := StrToFloat(ExcludeChars(S, [' ']));
      cs2.add(test,Table2[0,ct1]);
    End;

Table2[2,ct1] est la valeur sous forme de string.
test1 devrait me donner la valeur sous forme décimale; elle renvoie 0.

J'ai recopié la fonction à l'identique et elle fonctionne.

Bien à toi,

G. PLETINCKX
Messages postés
4719
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
1 février 2021
14
bonjour,

mets le code complet, parce que si ça continue on va avoir du SMS dedans..

cantador
Messages postés
40
Date d'inscription
mardi 28 novembre 2006
Statut
Membre
Dernière intervention
3 août 2010

Voila.

procedure TFRapGlo.Button1Click(Sender: TObject);
Var
ct1 : Integer;
test : Double;
test1 : Real48;
S : String;
begin
// Stats calamités
  If Not FileExists('C:\Statistiques') Then
    ForceDirectories('C:\Statistiques');
  SetLength(Table1,2,9);
  ct1 := 0;
  NbCal := 0;
  Donnees.QCalam.Active := True;
  Try
    Donnees.QCalam.First;
    while not Donnees.QCalam.Eof do
      begin
        Table1[0,ct1] := Donnees.QCalamTYPE.Value;
        Table1[1,ct1] := (IntToStr(Donnees.QCalamNBCAL.AsInteger));
        NbCal := NbCal + Donnees.QCalamNBCAL.AsInteger;
        ct1 := ct1 + 1;
        Donnees.QCalam.Next;
      End;
  Finally;
  End;
  Table1[0,ct1] := 'TOTAL';
  Table1[1,ct1] := IntToStr(NbCal);

  Chart1.SeriesList.Clear;
  Chart1.Legend.Visible := False;
  cs := TPieSeries.Create(Self);
  cs.ParentChart := Chart1;
  For ct1 := 0 To 7 Do
    Begin
      cs.Add((StrToInt(Table1[1,ct1])),Table1[0,ct1]);
    End;
  Chart1.SaveToBitmapFile('C:\Statistiques\Typecal.bmp');
  Donnees.QCalam.Active := False;

  // Stat gén
  SetLength(Table2,7,9);
  ct1 := 0;
  Table2T1 := 0;
  Table2T2 := 0;
  Table2T3 := 0;
  Table2T4 := 0;
  Table2T5 := 0;
  Table2T6 := 0;
  Donnees.QStatGen.Active := True;
  Try
    Donnees.QStatGen.First;
    while not Donnees.QStatGen.Eof do
      begin
        Table2[0,ct1] := Donnees.QStatGenTYPE.Value;
        Table2[1,ct1] := (IntToStr(Donnees.QStatGenNOMBRE.AsInteger));
        Table2[2,ct1] := (FloatToStrF(Donnees.QStatGenBRUT.AsFloat,ffNumber,9,0));
        Table2[3,ct1] := (FloatToStrF(Donnees.QStatGenVETUSTE.AsFloat,ffNumber,9,0));
        Table2[4,ct1] := (FloatToStrF(Donnees.QStatGenNET.AsFloat,ffNumber,9,0));
        Table2[5,ct1] := (FloatToStrF(Donnees.QStatGenMOYBRUT.AsFloat,ffNumber,9,0));
        Table2[6,ct1] := (FloatToStrF(Donnees.QStatGenMOYNET.AsFloat,ffNumber,9,0));
        Table2T1 := Table2T1 + Donnees.QStatGenNOMBRE.AsInteger;
        Table2T2 := Table2T2 + Donnees.QStatGenBRUT.AsFloat;
        Table2T3 := Table2T3 + Donnees.QStatGenVETUSTE.AsFloat;
        Table2T4 := Table2T4 + Donnees.QStatGenNET.AsFloat;
        ct1 := ct1 + 1;
        Donnees.QStatGen.Next;
      End;
  Finally;
  End;
  Table2[0,ct1] := 'TOTAL';
  Table2[1,ct1] := IntToStr(Table2T1);
  Table2[2,ct1] := FloatToStrF(Table2T2,ffNumber,9,0);
  Table2[3,ct1] := FloatToStrF(Table2T3,ffNumber,9,0);
  Table2[4,ct1] := FloatToStrF(Table2T4,ffNumber,9,0);
  Table2[5,ct1] := FloatToStrF(Table2T2 / Table2T1,ffNumber,9,0);
  Table2[6,ct1] := FloatToStrF(Table2T4 / Table2T1,ffNumber,9,0);
  Donnees.QStatGen.Active := False;
  // Graphe du nombre de sinistrés
  Chart2.SeriesList.Clear;
  Chart2.Legend.Visible := False;
  cs1 := TBarSeries.Create(Self);
  cs1.ParentChart := Chart2;
  For ct1 := 0 To 7 Do
    Begin
      cs1.add(StrToInt(Table2[1,ct1]),Table2[0,ct1]);
    End;
  Chart2.SaveToBitmapFile('C:\Statistiques\NbSin.bmp');
  // Graphe du montant des dommages bruts
  Chart3.SeriesList.Clear;
  Chart3.Legend.Visible := False;
  cs2 := TBarSeries.Create(Self);
  cs2.ParentChart := Chart3;
  For ct1 := 0 To 7 Do
    Begin
      test := StrToInt(StringReplace(Table2[2,ct1], ' ', '', [rfReplaceAll]));
      S := Table2[2,ct1];
      test1 := StrToFloat(ExcludeChars(S, [' ']));
      cs2.add(test,Table2[0,ct1]);
    End;
  Chart3.SaveToBitmapFile('C:\Statistiques\MtDomBr.bmp');
  // Graphe de la moyenne des dommages bruts
  Chart4.SeriesList.Clear;
  Chart4.Legend.Visible := False;
  cs3 := TBarSeries.Create(Self);
  cs3.ParentChart := Chart4;
  For ct1 := 0 To 7 Do
    Begin
      test := StrToInt(StringReplace(Table2[5,ct1], ' ', '', [rfReplaceAll]));
      S := Table2[5,ct1];
      test1 := StrToFloat(ExcludeChars(S, [' ']));
      cs3.add(test,Table2[0,ct1]);
    End;
  Chart4.SaveToBitmapFile('C:\Statistiques\MoyDomBr.bmp');

  Sauv1 := 0;
  RvSGlob.DefaultDest:= rdFile;
  RvSGlob.DoNativeOutput := False;
  RvSGlob.RenderObject := RvRPDFGlob;
  RvSGlob.OutputFileName := 'C:\Statistiques\statglobales' + '.pdf';
  RvSGlob.SystemSetups := RvSGlob.SystemSetups - [ssAllowSetup];
  RvSGlob.Execute;
  Sauv1 := 1;
  RvSGlob.DefaultDest:= rdPreview;
  RvSGlob.DoNativeOutput := False;
  RvSGlob.SystemSetups := RvSGlob.SystemSetups;
  RvSGlob.Execute;
end;

Function TFRapGlo.ExcludeChars(Const S : String; Const CS : TSysCharSet): String;
Var P, PR : PByte;
    Size, I : Integer;
Begin
  P := PByte(S);
  Size := Length(S);
  SetLength(Result, Size);
  PR := PByte(Result);
  I := 0;
  While P^ <> $0  Do
  Begin
    If Not (Chr(P^) In CS) Then
    Begin
      Pr^ := P^;
      Inc(Pr);
    End
    Else Inc(I);
      Inc(P);
  End;
  If I > 0  Then SetLength(Result, Size - I)
End;

G. PLETINCKX
Messages postés
3826
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
10 mai 2021
44
donne moi la valeur initiale de "Table2[5,ct1];" qui pose problème

parce que si "Table2[5,ct1];" == 0,125 alors c'est normale qu'il te renvoi 0

 
@+
Cirec

<hr siz="" />
Messages postés
1
Date d'inscription
lundi 11 décembre 2000
Statut
Membre
Dernière intervention
6 février 2012

procedure TForm1.BitBtn1Click(Sender: TObject);

var i:integer;
R: real;
begin
R:=STrToFloat(edit2.text);
i:=length(FormatFloat('0.00',R));
label1.Caption:=intToStr(i);
edit1.Text:=FormatFloat('0.00',R);
case i of
1..6:label2.Caption:=edit1.Text;
7:label2.Caption:=copy(Edit1.Text,1,1)+' '+Copy(Edit1.Text,2,6)+' DA';
8:label2.Caption:=copy(Edit1.Text,1,2)+' '+Copy(Edit1.Text,3,6)+' DA';
9:label2.Caption:=copy(Edit1.Text,1,3)+' '+Copy(Edit1.Text,4,6)+' DA';
10:label2.Caption:=copy(Edit1.Text,1,1)+' '+Copy(Edit1.Text,2,3)+' '+Copy(Edit1.Text,5,6)+' DA';
11:label2.Caption:=copy(Edit1.Text,1,2)+' '+Copy(Edit1.Text,3,3)+' '+Copy(Edit1.Text,6,6)+' DA';
12:label2.Caption:=copy(Edit1.Text,1,3)+' '+Copy(Edit1.Text,4,3)+' '+Copy(Edit1.Text,7,6)+' DA';
13:label2.Caption:=copy(Edit1.Text,1,1)+' '+Copy(Edit1.Text,2,3)+' '+Copy(Edit1.Text,5,3)+' '+Copy(Edit1.Text,8,6)+' DA';
end;


end;