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;
30 août 2005 à 18:55
Faudrait poser la question dans le forum.
29 août 2005 à 03:28
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.
28 août 2005 à 19:44
Plus d'infos, S.V.P.
26 août 2005 à 17:04
Je n'ai pas fait le test mais je suis certain que CA NE MARCHE PAS !
Alors, une solution ?
19 août 2005 à 17:01
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
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.