Filtrer la saisie valide d'un nombre entier, flottant, signé ou non, dans un tedit

1/5 (12 avis)

Vue 15 748 fois - Téléchargée 1 135 fois

Description

Fonction à appeler dans l'évènement OnKeyPress de ou des Edits.

Comment n'admettre que la saisie de chiffres dans mon Edit ?
La question revient souvent sur le forum...

J'ai donc un peu remanié mon code afin d'en faire un fonction polyvalente.
Attention, cette fonction ne teste pas un éventuel dépassement de capacité selon le type du nombre attendu. Mais c'est une évolution à envisager.
Elle se limite à filtrer au moment de la saisie les caractères admis et ceux qui ne le sont pas, selon que le nombre attendu est un entier, un flottant, qu'il est signé ou non.
Le caractère '-', s'il est autorisé, ne sera admis qu'au début.
Le séparateur décimal, s'il est autorisé, ne pourra pas se répéter. Il est toléré au début ou à la fin de la saisie.
Le 3ème paramètre peut être négligé si l'on ne veut filtrer qu'un entier positif.

Dans le code de démonstration, j'aurais pu regrouper les évènements OnKeyPress des Edits, mais j'ai laissé comme ça pour plus de clarté.
Vous trouverez également 2 ou 3 bricoles, comme le changement de focus d'un Edit à l'autre avec les flèches de direction, la touche Enter, etc...

N'hésitez pas à me signaler toute défaillance :( ou amélioration à apporter :)

Bonne prog' :p

Source / Exemple :


type
  TTypeOfNumber = (INT_NOSIGN, INT_SIGN, FLOAT_NOSIGN, FLOAT_SIGN);

function NumberIsValid(Sender: TObject; K: Char;
  const TN: TTypeOfNumber = INT_NOSIGN): Char;
const
  Valid = #13, '0'..'9';
  Signe = ['-'];
var
  Ok: Boolean;
    function IsNotYet: Boolean;
    begin
      Result := True;
      if ((K = DecimalSeparator) or (K = '-')) and (Pos(K, TEdit(Sender).Text) > 0) then
        Result := False;
    end;
    function Is1st: Boolean;
    begin
      Result := True;
      if (K = '-') and (TEdit(Sender).SelStart <> 0) then
        Result := False;
    end;
begin
  Result := #0;
  Ok := False;
  if not (Sender is TEdit) then Exit;
  case TN of
    INT_NOSIGN  : Ok := (K in Valid);
    INT_SIGN    : Ok := (K in Valid + Signe) and IsNotYet and Is1st;
    FLOAT_NOSIGN: Ok := (K in Valid + [DecimalSeparator]) and IsNotYet;
    FLOAT_SIGN  : Ok := (K in Valid + Signe + [DecimalSeparator]) and IsNotYet and Is1st;
  end;
  if Ok then Result := K;
end;

{ Exemple d'utilisation }
procedure TForm1.edIntNoSignedKeyPress(Sender: TObject; var Key: Char);
begin
  //Key := NumberIsValid(Sender, Key, INT_NOSIGN);    // les 2 lignes donnent...
  Key := NumberIsValid(Sender, Key);                // ...le même résultat  
end;

Codes Sources

A voir également

Ajouter un commentaire Commentaires
EddiTheHead Messages postés 58 Date d'inscription mercredi 16 février 2005 Statut Membre Dernière intervention 2 juin 2006
30 août 2005 à 18:55
Juste.
Faudrait poser la question dans le forum.
Pioko Messages postés 2 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 29 août 2005
29 août 2005 à 03:28
Si je fais un copier/coller d'un texte qui ne représente pas un nombre, par exemple le texte : "ca ne marche pas", mon TEdit contient alors ce texte ... qui n'est pas un nombre valide.
Or ceci est contraire à ce qu'affirme faire ce morceau de code : "FILTRER LA SAISIE VALIDE D'UN NOMBRE ENTIER, FLOTTANT, SIGNÉ OU NON, DANS UN TEDIT".
Je cherche encore une solution simple si possible.
EddiTheHead Messages postés 58 Date d'inscription mercredi 16 février 2005 Statut Membre Dernière intervention 2 juin 2006
28 août 2005 à 19:44
Qu'est-ce qui ne marche pas?
Plus d'infos, S.V.P.
Pioko Messages postés 2 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 29 août 2005
26 août 2005 à 17:04
OK, c'est bien tout ça mais qu'est-ce qui se passe si on colle un texte du style "ca ne marche pas" ?

Je n'ai pas fait le test mais je suis certain que CA NE MARCHE PAS !

Alors, une solution ?
EddiTheHead Messages postés 58 Date d'inscription mercredi 16 février 2005 Statut Membre Dernière intervention 2 juin 2006
19 août 2005 à 17:01
Slt,

Je me suis permis de modifier ta source en rajoutant une limite de saisie.
J'aimerai avoir vos avis.

On peut utiliser un masque différent pour chaque TEdit en utilisant sa valeur TAG.

A déclarer en global (dont l'indice sera le TAG du TEdit) :
---------------------------------------------------------
Const Limite : Array [1..4] Of String = ('9999', '9999', '999,99', '9999,999');

Dans la fonction "NumberIsValid",
déclaration :
-----------
Var Ok : Boolean;
L1, L2, E1, E2 : Byte; // L1, E1 : Le nbre de chiffre avant la virgule
// L2, E2 : Le nbre de chiffre après la virgule
// L pour Limite / E pour le TEdit
Chaine : String // Variable temporaire

Code,
remplacer :
---------
if Ok then Result := K;

par :
---
If Ok Then
If (TEdit(Sender).Tag > 0) And (K In ['0'..'9']) Then // Si TAG > 0 alors travailler avec
// LIMITE[?] => (1)
Begin
// On défini le masque de saisie
L1 := Pos(DecimalSeparator, Limite[TEdit(Sender).Tag]); // Position de la virgule
If L1 = 0 Then L1 := Length(Limite[TEdit(Sender).Tag]) // Si pas de virgule,
// alors nbre entier ...
Else Dec(L1); // ...Sinon, Pos-1 va
// donner le nbre de
// chiffre avant la virgule
L2 := Pos(DecimalSeparator, Limite[TEdit(Sender).Tag]); // Position de la virgule.
// Si = 0, pas de décimal
If L2 > 0 Then L2 := Length(Limite[TEdit(Sender).Tag]) - L2; // Si virgule, on calcul
// le nbre du chiffre
// après la virgule

// On défini à quoi ressemble la valeur entrée dans le TEdit
Chaine := TEdit(Sender).Text; // On stock le contenu du TEdit
Insert(K, Chaine, TEdit(Sender).SelStart+1); // On insert le nouveau caractère
E1 := Pos(DecimalSeparator, Chaine); // Idem que pour L
If E1 = 0 Then E1 := Length(Chaine)
Else Dec(E1);
If Chaine[1] = '-' Then Dec(E1); // Si le signe "-" est présent, on le
// supprime dans le décompte
E2 := Pos(DecimalSeparator, Chaine);
If E2 > 0 Then E2 := Length(Chaine) - E2;

// On teste si on est dans la limite
If (E1 <= L1) And (E2 <= L2) Then Result := K;
End
Else Result :K; // (1)> Sinon, on travaille sans limite
Afficher les 12 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.