IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Lazarus Pascal Discussion :

Problème étrange avec l'utilisation de la fonction StrToFloat


Sujet :

Lazarus Pascal

  1. #1
    Membre actif
    Homme Profil pro
    Retraité
    Inscrit en
    Juillet 2008
    Messages
    385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juillet 2008
    Messages : 385
    Points : 223
    Points
    223
    Par défaut Problème étrange avec l'utilisation de la fonction StrToFloat
    Bonjour,
    J'avais déja évoqué mon problème dans un autre message et je croyais l'avaoir réglé en réinstallant lazarus complétement,
    Mais voila ce n'est pas le cas donc j'ouvre une nouvelle discussion sue ce sujet.
    Dans mes petites application j'utilise les composants natifs de gestion des base de données avec sqlite3
    voici 2 commandes qui dans le premier cas me donne un message d'erreur de conversion et pas dans la deuxième forme
    La déclaration de mes variables :
    ML_PREMIERen String et XL_PREMIER en Double.
    Je lie dans une table une valeur au format texte enregistrée par ajout d'espaces pour être à droite dans le champ de la donnée
    Ensuite de transforme cette chaîne en valeur décimale avec décimale pour effectuer des calculs avant d'enregistrer le résultat sous la forme d'une chaîne
    première forme avec erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ML_PREMIER:=data.Vehicule.FieldByName('L_PREMIER').AsString;
      XL_PREMIER:=StrToFloat((ML_PREMIER));
    deuxième sans erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ML_PREMIER:=data.Vehicule.FieldByName('L_PREMIER').AsString;
     XL_PREMIER:=StrToFloat(Trim(ML_PREMIER));
    Cherchant à comprendre j'ai créé une petite application utilisant les mêmes instructions avec une lecture de la base de données soit via un composant slite3 sur la fichez soit avec un datamodule qui est la frorme que j'utilise habituellement et là pas de problèmes
    J'ai donc regardé de plus près le texte de mes unités et j'ai constaté des différences dont je ne connais pas la raison ni leur fonction
    en premier le texte complet d'une unité simple de mon test sans problème
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    unit uessai;
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
     
    type
     
      { TFessai }
     
      TFessai = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { private declarations }
      public
        { public declarations }
      end;
     
    var
      Fessai: TFessai;
     
    implementation
     
    {$R *.lfm}
     
    { TFessai }
     
    procedure TFessai.Button1Click(Sender: TObject);
    begin
      close;
    end;
     
    end.
    et ensuite le début et la fin d'une unité à problème
    Début
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    unit undepense;  // unité nouvelle dépense le 04 septembre 2014 vers 16h50
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
      ExtCtrls, DBGrids, Buttons, StdCtrls, Calendar, MaskEdit, DbCtrls, ExtDlgs,
      udata, uoutils;
     
    type
     
      { TFndepense }
     
      TFndepense = class(TForm)
        BCarburant: TBitBtn;
        BAnnuler: TBitBtn;
        BChoix: TBitBtn;
        BValiderDepense: TBitBtn;
        BValiderCompteur: TBitBtn;
        BValiderLitres: TBitBtn;
        BValiderMontant: TBitBtn;
        BConfirmerDepense: TBitBtn;
        BValiderDate: TBitBtn;
        BSuite: TBitBtn;
        BPeage: TBitBtn;
        BAssurance: TBitBtn;
        BEntretien: TBitBtn;
        BReparation: TBitBtn;
        BControle: TBitBtn;
        BDivers: TBitBtn;
        BTaxe: TBitBtn;
        BRetour: TBitBtn;
        Calendrier: TCalendar;
        DBCode: TDBEdit;
        EMoyennePlein: TEdit;
        EMoyenneGenerale: TEdit;
        EInformation: TEdit;
        EPrix_L: TEdit;
        GridVehicule: TDBGrid;
        EDate: TEdit;
        GridDepenses: TDBGrid;
        EGenre: TEdit;
        Label1: TLabel;
        Label2: TLabel;
        Label3: TLabel;
        Label4: TLabel;
        Label5: TLabel;
        Label6: TLabel;
        Label7: TLabel;
        Label8: TLabel;
        Label9: TLabel;
        MaskMontant: TMaskEdit;
        MaskCompteur: TMaskEdit;
        MaskLitres: TMaskEdit;
        Navigateur: TDBNavigator;
        PCarburant: TPanel;
        PCompteur: TPanel;
        PDonnees: TPanel;
        PMoyenne: TPanel;
        PVehicule: TPanel;
        PTitre: TPanel;
        PBoutons: TPanel;
        procedure BAnnulerClick(Sender: TObject);
        procedure BAssuranceClick(Sender: TObject);
        procedure BCarburantClick(Sender: TObject);
        procedure BChoixClick(Sender: TObject);
        procedure BConfirmerDepenseClick(Sender: TObject);
        procedure BControleClick(Sender: TObject);
        procedure BDiversClick(Sender: TObject);
        procedure BEntretienClick(Sender: TObject);
        procedure BPeageClick(Sender: TObject);
        procedure BReparationClick(Sender: TObject);
        procedure BRetourClick(Sender: TObject);
        procedure BSuiteClick(Sender: TObject);
        procedure BTaxeClick(Sender: TObject);
        procedure BValiderCompteurClick(Sender: TObject);
        procedure BValiderDateClick(Sender: TObject);
        procedure BValiderDepenseClick(Sender: TObject);
        procedure BValiderLitresClick(Sender: TObject);
        procedure BValiderMontantClick(Sender: TObject);
        procedure FormShow(Sender: TObject);
      private
        { private declarations }
        procedure DebutDepense;
        procedure LectureVehicule;
        procedure LectureTotaux;
        procedure SuiteSequence;
        procedure SequenceDate;
        procedure SequenceCompteur;
        procedure SequencePlein;
        procedure CalculMoyennePlein;
        procedure CalculPrixLitres;
        procedure SequenceMontant;
        procedure TestSuiteDepense;
        procedure EnregistrementDepense;
        procedure CreationNumero;
        procedure SuiteEnregistrement;
        procedure MajTotaux;
        procedure MajVehicule;
        procedure AjoutDepense;
        Procedure Annuler;
        procedure AfficheBoutons;
        procedure CacheBoutons;
        procedure AffichageDepenses;
      public
        { public declarations }
      end; 
     
    var
      Fndepense: TFndepense;
      MQ,MQ1,MQ2,Q1,Q2,Q3,Q4,Q5,Q6,Q7,Q8,Q9,QA,QB,QC,QD,QE,QF,QG,QH,MANNEE_DEPENSE:String;
      MK_DEPENSE,MKM_ACHAT,MMASQUE,MANNEE,MDER_DATE,MKM_DEPENSE,MNUMERO,ML_PREMIER:String;
      MCODE,MDER_NUMERO,MMOYENNE_P,MMOYENNE_G,MCOMPTEUR,MKM_REALISE,MKM_DERNIER:String;
      MGENRE,MDATE,MMONTANT,MINFO,MLITRES,MT_CONTROLE,MT_DIVERS,MT_TAXES,MPRIX_L:String;
      MT_LITRES,MT_CARBURANT,MT_ASSURANCE,MT_ENTRETIEN,MT_PEAGE,MT_REPARATION:String;
      MZA,MZB,MPREMIER,MKM_D_PLEIN:String;
      XSUITE,XGENRE,XK_VEHICULE,XK_TOTAUX,XKM_D_PLEIN:Integer;
      XDER_NUMERO,XCOMPTEUR,XKM_PLEIN,XKM_REALISE,XKM_DERNIER,XKM_ACHAT,XLONG:Integer;
      XMONTANT,XMOYENNE_G,XMOYENNE_P,XT_CARBURANT,XLITRES,XT_LITRES,XL_PREMIER:Double;
      XT_ASSURANCE,XT_CONTROLE,XT_ENTRETIEN,XT_PEAGE,XT_REPARATION,XT_DIVERS:Double;
      XT_TAXES,XDER_DATE,XPRIX_L:Double;
      ZDATE:TDateTime;
      XJOUR,XMOIS,XANNEE:Word;
      YCOMPTEUR,YPLEIN:Boolean;
     
      const
        MVIDE='';
     
     
    implementation
     
    { TFndepense }
     
    procedure TFndepense.FormShow(Sender: TObject);
    begin
     data.Vehicule.Close;
     MQ:='Select * from VEHICULE WHERE ACTIF = '+quotedstr('OUI');
     data.Vehicule.SQL:=MQ;
     data.Vehicule.open;
     data.Vehicule.ExecSQL;
       if data.Vehicule.RecordCount=0 then
        begin
    et la fin
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     data.Depense.SQL:='Select * from DEPENSE  WHERE CODE= '+quotedstr(MCODE);
      data.Depense.Open;
      data.Depense.ExecSQL;
    end;
     
    initialization
      {$I undepense.lrs}
     
    end.
    J'espère avoir été assez clair, puis-je modifier mes unités anciennes comme les nouvelles et pourquoi ces différences ou puis-je les modifier via l'EDI ?
    Merci de votre aide avant que je fasse des bétises.
    A+
    PS : Précision je suis sous linux fedora 20 en 64bits

  2. #2
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 854
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 854
    Points : 11 287
    Points
    11 287
    Billets dans le blog
    6
    Par défaut
    Que donne le code suivant ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    XL_PREMIER := data.Vehicule.FieldByName('L_PREMIER').AsFloat;
    ML_PREMIER := FloatToString(XL_PREMIER);
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  3. #3
    Membre actif
    Homme Profil pro
    Retraité
    Inscrit en
    Juillet 2008
    Messages
    385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juillet 2008
    Messages : 385
    Points : 223
    Points
    223
    Par défaut
    Bonjour,
    La commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ML_PREMIER := FloatToString(XL_PREMIER);
    donne une erreur à la compilation comme quoi cette fonction n'est pas trouvée, je pense que c'est FloatToStr qui était prévue
    Avec cette modification si je fait un arrêt juste après
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     XL_PREMIER := data.Vehicule.FieldByName('L_PREMIER').AsFloat;
      ML_PREMIER := FloatToStr(XL_PREMIER);
    via l'évaluateur avec Ctr+F7 la valeur trouvée pour XL_PREMIER est 63 point 75 quand dans ML_PREMIER comme dans un DbGrid j'ai 63 virgule 75 idem via un sqlitebrowser pour afficher les données de ma table sqlite pourtant dans la fiche principale j'ai dans l'événement CREATE donné les valeurs suivantes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    procedure TFtest.FormCreate(Sender: TObject);
    begin
       // préparation de l'environnement
      defaultFormatSettings.ShortDateFormat:='DD/MM/YYYY';
      defaultFormatSettings.DateSeparator:='/';
      defaultFormatSettings.DecimalSeparator:=',';
    end;
    Concernant l'information de la directive
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    MMODIFICATION:='OUI';
    end;
     
     
    initialization
      {$I urevente.lrs}
     
    end.
    en fin de fichier j'ai l'impression que cela viendrait de windows ?? je passe quelque fois par un PC sous XP pour voir ce que donne mon application dans cet environnement

    Je complète ma réponse avec l'application de test je n'ai pas d'erreur mais avec mon application "normale" où j'ai été obliger d'ajouter la fonction TRIM la proposition faite donne le même défaut
    "Le projet à levé une classe d'exception "EConvertError avec le message " 45,30" is invalid float avec un espace au début. La longueur de mon champ dans ma table sqlite est déclaré sous 6 caractères et je l'enregistre de façon à avoir 6 caractères si il n'y en a pas 6 j'ajoute des espaces au début de la chaîne.
    Ces nouveaux essais me font penser que les 2 compilations ne se font pas de la même façon mais là je ne sais pas le trouver tout seul.
    A+

  4. #4
    Membre chevronné

    Homme Profil pro
    au repos
    Inscrit en
    Février 2014
    Messages
    429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : au repos

    Informations forums :
    Inscription : Février 2014
    Messages : 429
    Points : 1 884
    Points
    1 884
    Par défaut
    Bonjour.

    Pour ton problème 63 point 75... :
    DecimalSeparator sert à l'affichage d'un nombre ou à son encodage (TEdit, DBGrid...).

    Donc dans un TEdit :
    63,75 va pouvoir être transformé en nombre
    63.75 provoque une erreur à la transformation puisque le séparateur décimal est la virgule.

    Par contre, pour donner une valeur à un nombre réel, il faut toujours utiliser le point :
    a:= 63,75 --> erreur
    a:= 63.75 ---> ok

    La valeur de XL_PREMIER = 63.75
    Mais si tu veux l'afficher, tu obtiens 63,75

    A +
    Thierry

  5. #5
    Membre régulier Avatar de TheFreeBerga
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    63
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 63
    Points : 77
    Points
    77
    Par défaut
    Bonjour,

    A la lecture de ton code, j'ai remarqué la séquence (normale) suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    sqlite3ds.Close;
    sqlite3ds.SQL := 'LA REQUÊTE SQL';
    sqlite3ds.Open;
    Mais pourquoi ajouter un

    après le Open ?

    Le Open se suffit à lui-même et je suis même étonné que tu n'ai pas (encore) eu d'erreur à l’exécution...
    Personnellement, j'utilise soit cette formulation, soit l'accès direct avec sqlite3ds.ExecSQL( 'LA REQUÊTE SQL' ).

    Je ne suis pas un pro du composant sqlite3ds mais si tu n'as pas d'erreur à l’exécution, c'est peut-être parce que le sqlite3ds.ExecSQL lance une seconde fois la requête déjà résolue par Open...

  6. #6
    Membre actif
    Homme Profil pro
    Retraité
    Inscrit en
    Juillet 2008
    Messages
    385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juillet 2008
    Messages : 385
    Points : 223
    Points
    223
    Par défaut
    Je réponds à ThWilliam en premier, une petite précision qui a son importance dans mes tables sqlite hors la key je n'utilise que des champs au format texte et j'utilise la conversion vers les nombres décimaux avec ou sans décimales, idem pour les dates pour effectuer des calculs puis la conversion inverse pour enregistrer les nouvelles valeurs dans mes tables.
    Je répondais simplement à un test proposé.

    Pour TheFreeBerga,
    La forme d'écriture que tu indiques où la trouves-tu dans mes messages ?
    Concernant la façon la fermeture, puis l'écriture de la future commande SQL suivie de la réouverture avant l'exécution de la commande SQL ceci me permet de changer la forme de classement des données avec des fonctions de tri.
    A+

  7. #7
    Membre régulier Avatar de TheFreeBerga
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    63
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 63
    Points : 77
    Points
    77
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    { TFndepense }
     
    procedure TFndepense.FormShow(Sender: TObject);
    begin
     data.Vehicule.Close;
     MQ:='Select * from VEHICULE WHERE ACTIF = '+quotedstr('OUI');
     data.Vehicule.SQL:=MQ;
     data.Vehicule.open;
     data.Vehicule.ExecSQL; <============== ICI
       if data.Vehicule.RecordCount=0 then
        begin
    Maintenant, comme je le dit précédemment, je ne suis pas un pro de sqlite3ds mais si j'ai raison, tu lances 2 fois la requête !
    A tout hasard, ça ne coûte rien d'essayer de commenter cette ligne et voir si le programme réagit comme avant...

  8. #8
    Membre actif
    Homme Profil pro
    Retraité
    Inscrit en
    Juillet 2008
    Messages
    385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juillet 2008
    Messages : 385
    Points : 223
    Points
    223
    Par défaut
    Bonjour,
    Je ferais cet essai mais pas avant une dizaine de jours car je dois m'absenter.
    Par contre j'ai refais un essai avec une nouvelle application et les mêmes base et données et la même séquence et pas de message d'erreur de conversion.
    Donc la suite dans une dizaine de jours.
    Etrange.
    Merci
    A+

    PS : je viens de faire l'essai et cela fonctionne, un nouvel apprentissage. Merci

Discussions similaires

  1. Problème avec l'utilisation de la fonction dataset
    Par sohoney dans le forum MATLAB
    Réponses: 1
    Dernier message: 11/01/2013, 16h21
  2. problème avec l'utilisation d'une fonction
    Par mcspawn dans le forum Langage
    Réponses: 6
    Dernier message: 06/06/2007, 15h39
  3. problème étrange avec excel
    Par lanfeust42 dans le forum Modules
    Réponses: 1
    Dernier message: 15/06/2006, 10h57
  4. Problème avec l'utilisation de la fonction clock
    Par Matgic95 dans le forum C++Builder
    Réponses: 13
    Dernier message: 09/05/2005, 19h27
  5. [FLASH MX2004 PRO] Problème étrange avec LoadClip...
    Par josemoroide dans le forum Flash
    Réponses: 6
    Dernier message: 04/08/2004, 15h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo