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

Soyez le premier à donner votre avis sur cette source.

Vue 15 030 fois - Téléchargée 1 100 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
Messages postés
58
Date d'inscription
mercredi 16 février 2005
Statut
Membre
Dernière intervention
2 juin 2006

Juste.
Faudrait poser la question dans le forum.
Messages postés
2
Date d'inscription
mercredi 22 décembre 2004
Statut
Membre
Dernière intervention
29 août 2005

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.
Messages postés
58
Date d'inscription
mercredi 16 février 2005
Statut
Membre
Dernière intervention
2 juin 2006

Qu'est-ce qui ne marche pas?
Plus d'infos, S.V.P.
Messages postés
2
Date d'inscription
mercredi 22 décembre 2004
Statut
Membre
Dernière intervention
29 août 2005

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 ?
Messages postés
58
Date d'inscription
mercredi 16 février 2005
Statut
Membre
Dernière intervention
2 juin 2006

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.