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

Langage Delphi Discussion :

stringreplace à devenir fou


Sujet :

Langage Delphi

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Février 2007
    Messages
    400
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 400
    Points : 171
    Points
    171
    Par défaut stringreplace à devenir fou
    Bonjour,

    Je crois que je vais devenir dingo ...

    J'avais une petite fonction que je replace souvent dans mes programmes, qui permet de reformater les heures en fonction de la saisie plus ou moins respectueuse du format heure hh:ss, et surtout je ne voulais pas obliger les agents qui saisissent à aller chercher les ':' pour séparer heure et minute.
    Cette fonction fonctionnait très bien et voilà que j'ai des petits soucis

    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
     
    function reformateheure(s: string): string;
    var
       sheures, sminutes: string;
       p1, p2: integer;
    begin
    p1:=pos(':',s);
    p2:=pos('.',s);
    if p1=0 then
       begin
       if length(s)<2 then
          s:=formate(s,'0',2,0);
       if p2>0 then
          begin
          stringreplace(s,'.',':',[rfReplaceAll, rfIgnoreCase]);
          end
       else
          begin
          insert(':',s,length(s)-1);
          end;
       end;
    sheures:=copy(s,1,pos(':',s)-1);
    sminutes:=copy(s,pos(':',s)+1,2);
    if sheures='' then
       insert('0',s,1);
    if length(sminutes)<2 then
       s:=sheures+':'+formate(sminutes,'0',2,1);
    result:=s;
    end;
    Tout d'abord, à la ligne 13, si je ne met pas le stringreplace entre begin et end, l'instruction pour p2>0 correspondant à vrai ne s'exécutait pas ...?? pas compris mais en mettant begin ends; la ligne 15 s'exécute.
    Mais, si s comporte un '.', et bien il n'est pas remplacé par les ':' comme cela devrait être.
    En pas à pas, je passe bien par l'instruction de la ligne 15 mais la chaine s ressort identique ???
    Auriez_vous une idée ? un truc dans le compilateur ?

    Je précise que j'ai essayé cette fonction dans un programme test avec que un tedit, et ça fonctionne très bien !

    J'en perd mon latin

    merci d'avance

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Février 2007
    Messages
    400
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 400
    Points : 171
    Points
    171
    Par défaut
    Bon j'ai trouvé une solution de contournement, la ligne 15 devient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    s:=copy(s,1,p2-1)+':'+copy(s,p2+1,200);
    mais j'aurais bien voulu comprendre ...

    Bon je viens d'avoir une illumination en écrivant le post ...

    Il faut affecter la fonction à une variable

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    s:=stringreplace(s,'.',':',[rfReplaceAll, rfIgnoreCase]);
    Je mérite le knout et désolé de vous avoir déranger... je vais aller me coucher ...

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 268
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 268
    Points : 41 671
    Points
    41 671
    Billets dans le blog
    64
    Par défaut
    Quelques remarques sans fouet (quoique, comme c'est demandé )

    En VCL, un TMaskEdit (editmask !90:00;1;_) éviterait des soucis
    ne pas oublier qu'il existe aussi TTimePicker depuis la version Tokyo (je crois)
    et TDateTimePicker (kind:=dtktime, format='hh:ss')

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Février 2007
    Messages
    400
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 400
    Points : 171
    Points
    171
    Par défaut
    Oui j'ai vu aussi mais je voulais comprendre pourquoi ça ne marchait pas
    Je vais peut-être changer ça ...
    Mais globalement la migration ne marche pas si mal que ça ...
    Sauf que toutes mes dates nulles sous paradox s'affichent maintenant 30/12/1899 ...
    Je n'ai pas encore trouvé comment les faire apparaître vide dans les tbedit ou les tbgrid par exemple ...
    Et dans les filtres et les requêtes j'ai l'impression que ça ne fonctionne plus ... a suivre

  5. #5
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 410
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 410
    Points : 3 174
    Points
    3 174
    Par défaut
    Bonjour,

    StringReplace est une fonction, il faut que tu fasses :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    s := stringreplace(s,'.',':',[rfReplaceAll, rfIgnoreCase]);
    pour que s soit modifié.

    A+
    Charly

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Février 2007
    Messages
    400
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 400
    Points : 171
    Points
    171
    Par défaut
    Merci charly
    Je m'étais répondu à moi-même avec la même solution ... ;-)

  7. #7
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 831
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 831
    Points : 13 579
    Points
    13 579
    Par défaut
    Cette fonction pourrait être grandement simplifiée.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    uses System.StrUtils;
     
    function ReformateHeure(const Value: string): string;
    begin
      var a := Value.Split(['.', ':']);
      var h := IfThen(Length(a) > 1, a[0], '0');
      var m := IfThen(Length(a) > 1, a[1], a[0]);
     
      Result := Format('%s:%.2d', [h, m.ToInteger]);
    end;
    Et ajouter des tests de validité ne serait pas du luxe

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Février 2007
    Messages
    400
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 400
    Points : 171
    Points
    171
    Par défaut
    Merci pour cette réponse très .... synthétique finalement ;o)
    Ce code a 20 ans et effectivement je me disais qu'il fallait que je revois ça ;o)
    Et puis j'avais développé tout un tas de petites fonctions qui sont maintenant natives donc gros travail en perspective ...

    Je ne connaissais pas cette instruction IfThen ... ça semble assez pratique ... je ne suis pas fortiche en C, mais ça ressemblerait pas un peu à la syntaxe en C ?

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Février 2007
    Messages
    400
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 400
    Points : 171
    Points
    171
    Par défaut
    Alors là Andnotor je suis sur le c.l ...

    En 4 lignes de programme, tu m'as appris plusieurs notions que je ne connaissais pas :
    - ifthen : syntaxe inconnue pour moi jusqu'à ton post
    - var : mettre le mot var entre le begin et le end alors que je croyais que ce mot était réservé à l'en-tête entre le nom de la fonction ou de la procédure et begin
    - split : fonction inconnue pour moi jusqu'à ton post
    - format : la syntaxe paraît aussi obscure qu'une syntaxe en C. Malgré l'aide, il y a encore des trucs que je pige pas :

    Format('%s:%.2d', [h, m.ToInteger])

    % : description de chaque valeur de a que l'on veut placer dans la chaine résultante (en commençant par défaut à 0) donc %s %.2d avec : entre les deux ?
    s: : on insère le premier élément de a sous forme de string ?
    : : j'avais cru comprendre que : était aussi la définition d'un index de départ, mais il faut qu'il soit précédé d'un entier ? là c'est un caractère littéral si j'ai bien compris
    %.2d : pour un nouvel argument .2d qui signifie 2 décimales ??
    [h,m : ce sont les éléments du tableau a (de quel type ?) définis plus haut (heures et minutes) et qui sont insérées à la place de chaque valeur décrite
    .ToInteger : je n'ai même pas trouvé ça dans l'aide ??

    Chapeau bas. La concision de la syntaxe me rappelle quand je faisais de l'assembleur pour des ordinateurs SORD (pas des pc) en 1979, qui n'avait que 64Ko de mémoire : il fallait être concis.

  10. #10
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 831
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 831
    Points : 13 579
    Points
    13 579
    Par défaut
    Citation Envoyé par navyg Voir le message
    - ifthen
    IfThen n'est rien d'autre qu'un if ... then ... else prémâché. Il ne faut pas hésiter à parcourir les unités XXXUtils (StrUtils, DateUtils, etc.) qui contiennent plein de petites fonctions "raccourcis".

    Citation Envoyé par navyg Voir le message
    - var
    Les variables inline sont apparues tout dernièrement. Déclaration implicite et initialisation sur une ligne, c'est sympa

    Le type correspond à ce qui est assigné. a est un tableau de chaînes, h et m sont donc des chaînes.

    Citation Envoyé par navyg Voir le message
    - split
    Ici un assistant d'enregistrement (record helper) mais la fonction SplitString existe depuis longtemps. Même chose pour m.ToInteger, un assistant d'enregistrement.


    A l'ancienne, j'aurais écrit cette fonction ainsi :
    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
    function ReformateHeure(const Value: string): string;
    var
      a    :TStringDynArray;
      h, m :string;
    begin
      a := SplitString(Value, '.:');
     
      if Length(a) > 1 then
      begin
        h := a[0];
        m := a[1];
      end
      else
      begin
        h := '0';
        m := a[0];
      end;
     
      Result := Format('%s:%.2d', [h, StrToInt(m)]);
    end;

    Citation Envoyé par navyg Voir le message
    Format('%s:%.2d', [h, m.ToInteger])
    Le paramètre débute par un % et se termine par un type sous la forme d'une lettre (%s=chaîne, %d=entier, etc). Tout ce qui n'est pas entre ces balises est un caractère littéral et : en est un ici. S'il y avait un indice, il serait entre ces balises : %0:s.

    Il y a ensuite une notion de taille minimale qui permet de faire des alignement en police non proportionnelle.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Format('|%20s|', ['Andnotor']);  // Colonne de 20 car. alignée à droite
    
    |            Andnotor|
    
    Format('|%-20s|', ['Andnotor']);  // Colonne de 20 car. alignée à gauche
    
    |Andnotor            |
    Il y a enfin une notion de précision qui dépend du type.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Format('|%.3s|', ['Andnotor']);  // Chaîne tronquée
    
    |And|
    
    Format('|%.3d|', [7]);  // entier, zéros non significatifs
    
    |007|
    
    Format('|%.3f|', [7.1]);  // réel, nombre de décimales
    
    |7.100|
    Le tout mis bout à bout peut effectivement donner des choses assez compliquées à lire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Format('|%1:20.3f|', [0, 7.1]);  // 2ème paramètre (base 0) en réel avec 3 décimales dans une zone de 20 car. aligné à droite 
    
    |                7.100|
    Sans oublier que taille et précision peuvent aussi être passés en argument. Le deuxième paramètre devient alors le quatrième argument !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Format('|%1:*.*f|', [0, 20, 3, 7.1]);  // 2ème paramètre (base 0) en réel avec 3 décimales dans une zone de 20 car. aligné à droite 
    
    |                7.100|

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Février 2007
    Messages
    400
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 400
    Points : 171
    Points
    171
    Par défaut
    J'avais presque tout compris ! Merci encore.

    J'ai l'air malin avec avec toutes mes petites fonctions perso que je réutilise dans mes programmes (formatedroite, formategauche, formatecentre ... entre autres) alors que la fonction format dispose de déjà presque tout ... mais ma syntaxe est finalement peut-être plus lisible ;o)

    Bon je suis un peu rassuré par le fait que les variables inline sont récentes ... ça m'avait échappé
    Ca peut être intéressant car j'utilisais beaucoup la syntaxeet il n'est plus permis maintenant d'y affecter une autre valeur par la suite, ou alors il y a une directive de compilation que je n'ai pas mise comme il faut ?
    Je pense que la variable inline, comme tu dis, peut avantageusement le remplacer

    Mais promis je vais me pencher sur toutes ces notions car ça paraît trop intéressant.
    Bon à plus de 60 balais c'est dur d'apprendre ... et de retenir surtout ;o)

  12. #12
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 268
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 268
    Points : 41 671
    Points
    41 671
    Billets dans le blog
    64
    Par défaut
    Citation Envoyé par navyg Voir le message
    Bon à plus de 60 balais c'est dur d'apprendre ... et de retenir surtout ;o)
    Faisant partie de ce club des sexagénaires je confirme, surtout pour la mémoire

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Passage de paramètre - A devenir fou.
    Par zapgillou dans le forum Langage
    Réponses: 2
    Dernier message: 05/12/2007, 07h46
  2. [RJS] Erreur RJS à devenir fou
    Par jujudellago dans le forum Ruby on Rails
    Réponses: 8
    Dernier message: 05/09/2007, 13h59
  3. [INSERT]Problème insert Je vais devenir fou !
    Par Sephiroth_ttt dans le forum Forms
    Réponses: 5
    Dernier message: 27/06/2007, 15h41
  4. Réponses: 5
    Dernier message: 12/04/2007, 17h56
  5. [debutant]Vais devenir fou...
    Par Treuze dans le forum C
    Réponses: 4
    Dernier message: 04/01/2006, 19h33

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