<

The best way for TEdit Number validation by type number

Published on
19,702 Points
13,002 Views
2 Endorsements
Last Modified:
Approved
Hello everybody

This Article will show you how to validate number with TEdit control,

What's the TEdit control?

TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text.

Usually, programmer use OnKeyPress event to validate number input (Integer for example) like the following example

 
procedure TForm1.Edit12KeyPress(Sender: TObject; var Key: Char);
begin
  if not (Key in [#8, '0'..'9']) then Key := #0;
end;

Open in new window


What problems aren't covered by OnKeyPress event?

OnKeyPress event analyzes keyboard inputs, but doesn't work with Copy/Paste or Ctrl + V keyboard shortcut, for that i found that, OnChange event is better to catch any kinds of inputs.

My idea basing on Undo and ClearUndo procedures of TEdit Control.

What's Undo and ClearUndo procedure?

Undo and ClearUndo procedure used by components belong to TCustomEdit class (such TEdit, TMaskedit, TMemo, TRichEdit...), we call Undo procedure to cancel all changes made to the TCustomEdit text since the last call to the ClearUndo procedure, and we call ClearUndo to commit changes to TCustomEdit text, after the excecuting of ClearUndo procedure,  Undo procedure does nothing until the TCustomEdit text has.a new changes.

The method I will use with OnChange event work like the following statement:

if TEdit input change is valid value then ClearUndo else Undo

Validate Number by type

The following example show you how to validate an Integer.
 
procedure TForm1.Edit1Change(Sender: TObject);
var Nbr: Integer;
begin
if TEdit(Sender).Text = '-' then Exit;
if TEdit(Sender).Text = '' then
  begin
  TEdit(Sender).Text := '0';
  TEdit(Sender).SelectAll;
  end
else if not TryStrToInt(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
  else if (Nbr >= Low(Integer)) and (Nbr <= High(Integer)) then
          TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
end;

Open in new window


Explanation

1) To allow input of "-" sign we will add this line (Integer is signed number)
if TEdit(Sender).Text = "-" then Exit;

2) When we clear TEdit we need to put "0"
TEdit(Sender).Text := '0';

3) When value of TEdit is null we need to make the control ready to clear '0' when user type another number
TEdit(Sender).SelectAll;

4) To check if the input is valid integer
if not TryStrToInt(TEdit(Sender).Text, Nbr)

5) To check if the integer value is Int32 (-2147483648..2147483647)
if (Nbr >= Low(Integer)) and (Nbr <= High(Integer)) then

Validate char input

In this part I will use the event to validate input string, the following example will check if input char allowed or not.for example (allowed chars are 'M','A','H','D','I','7','8')
 
procedure TForm1.Edit12Change(Sender: TObject);
Const AllowedStr = 'MAHDI78';
var I: Integer;
begin
for I := 1 to Length(TEdit(Sender).Text) do
  begin
  if (Pos(TEdit(Sender).Text[I], AllowedStr) = 0) then
    begin
    TEdit(Sender).Undo;
    Exit;
    end;
  end;
TEdit(Sender).ClearUndo;
end;

Open in new window

   

Validate format

In this part the event will validate input format, the following example will check format ('ss-nssn-nn') the input value should be for example "AE-5DR8-34".
   
procedure TForm1.Edit13Change(Sender: TObject);
Const AllowedFormat = 'ss-nssn-nn'; // for Example AE-5DR8-34
var I : Integer;
  P: PChar;
begin
if Length(TEdit(Sender).Text) > Length(AllowedFormat) then
  begin
  TEdit(Sender).Undo;
  Exit;
  end;

  P := PChar(TEdit(Sender).Text);
  I := 1;
  while P^ <> #0 do
  begin
  if AllowedFormat[I] = 's' then
     begin
     if not (P^ in ['A'..'Z']) then
       begin
       TEdit(Sender).Undo;
       Beep; Exit;
       end;
     end else
         if AllowedFormat[I] = 'n' then
          begin
          if not (P^ in ['0'..'9']) then
             begin
             TEdit(Sender).Undo;
             Beep; Exit;
             end;
          end else if AllowedFormat[I] <> Char(P^) then
                   begin
                   TEdit(Sender).Undo;
                   Beep; Exit;
                   end;
    Inc(P);
    Inc(I);
  end;
TEdit(Sender).ClearUndo;
end;

Open in new window


For more examples with (Smallint, ShortInt, Int64, Currency...) check the following sample

PAS unit
 
unit Unit1;

/// Posted by Mahdi78 member in Experts-Exchage.com
/// Email mahdi_kamel@yahoo.fr

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Edit5: TEdit;
    Edit6: TEdit;
    Edit7: TEdit;
    Edit8: TEdit;
    Label9: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    Label13: TLabel;
    Label14: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    Edit9: TEdit;
    Label17: TLabel;
    Label18: TLabel;
    Label19: TLabel;
    Label20: TLabel;
    Edit10: TEdit;
    Label21: TLabel;
    Edit11: TEdit;
    Label22: TLabel;
    Edit12: TEdit;
    Label23: TLabel;
    Label24: TLabel;
    Edit13: TEdit;
    Label25: TLabel;
    Label26: TLabel;
    procedure Edit2Change(Sender: TObject);
    procedure Edit3Change(Sender: TObject);
    procedure Edit4Change(Sender: TObject);
    procedure Edit5Change(Sender: TObject);
    procedure Edit6Change(Sender: TObject);
    procedure Edit7Change(Sender: TObject);
    procedure Edit8Change(Sender: TObject);
    procedure Edit9Change(Sender: TObject);
    procedure Edit10Change(Sender: TObject);
    procedure Edit11Change(Sender: TObject);
    procedure Edit1Change(Sender: TObject);
    procedure Edit12Change(Sender: TObject);
    procedure Edit13Change(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses math;

{$R *.dfm}

procedure TForm1.Edit10Change(Sender: TObject);
var Nbr: Extended;
begin
if TEdit(Sender).Text = '-' then Exit;
if (TEdit(Sender).Text = '') then
  begin
  TEdit(Sender).Text := '0';
  TEdit(Sender).SelectAll;
  end
else if not TryStrToFloat(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
  else if (Nbr >= -2.9 * Power(10, -39) ) and (Nbr <= 1.7 * Power(10, 38)) then
          TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
end;

procedure TForm1.Edit11Change(Sender: TObject);
var Nbr: Currency;
begin
if TEdit(Sender).Text = '-' then Exit;
if (TEdit(Sender).Text = '') then
  begin
  TEdit(Sender).Text := '0';
  TEdit(Sender).SelectAll;
  end
else if not TryStrToCurr(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
  else if (Nbr >= -922337203685477.5808) and (Nbr <= 922337203685477.5807) then
          TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
end;

procedure TForm1.Edit12Change(Sender: TObject);
Const AllowedStr = 'MAHDI78';
var I: Integer;
begin
for I := 1 to Length(TEdit(Sender).Text) do
  begin
  if (Pos(TEdit(Sender).Text[I], AllowedStr) = 0) then
    begin
    TEdit(Sender).Undo;
    Exit;
    end;
  end;
TEdit(Sender).ClearUndo;
end;

procedure TForm1.Edit13Change(Sender: TObject);
Const AllowedFormat = 'ss-nssn-nn'; // for Example AE-5DR8-34
var I : Integer;
  P: PChar;
begin
if Length(TEdit(Sender).Text) > Length(AllowedFormat) then
  begin
  TEdit(Sender).Undo;
  Exit;
  end;

  P := PChar(TEdit(Sender).Text);
  I := 1;
  while P^ <> #0 do
  begin
  if AllowedFormat[I] = 's' then
     begin
     if not (P^ in ['A'..'Z']) then
       begin
       TEdit(Sender).Undo;
       Beep; Exit;
       end;
     end else
         if AllowedFormat[I] = 'n' then
          begin
          if not (P^ in ['0'..'9']) then
             begin
             TEdit(Sender).Undo;
             Beep; Exit;
             end;
          end else if AllowedFormat[I] <> Char(P^) then
                   begin
                   TEdit(Sender).Undo;
                   Beep; Exit;
                   end;
    Inc(P);
    Inc(I);
  end;
TEdit(Sender).ClearUndo;
end;

procedure TForm1.Edit1Change(Sender: TObject);
var Nbr: Integer;
begin
if TEdit(Sender).Text = '-' then Exit;
if TEdit(Sender).Text = '' then
  begin
  TEdit(Sender).Text := '0';
  TEdit(Sender).SelectAll;
  end
else if not TryStrToInt(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
  else if (Nbr >= Low(Integer)) and (Nbr <= High(Integer)) then
          TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
end;

procedure TForm1.Edit2Change(Sender: TObject);
var Nbr: Integer;
begin
if (TEdit(Sender).Text = '') or (TEdit(Sender).Text = '-') then
  begin
  TEdit(Sender).Text := '0';
  TEdit(Sender).SelectAll;
  end
else if not TryStrToInt(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
  else if (Nbr >= Low(Byte)) and (Nbr <= High(Byte)) then
          TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
end;

procedure TForm1.Edit3Change(Sender: TObject);
var Nbr: Integer;
begin
if TEdit(Sender).Text = '-' then Exit;
if TEdit(Sender).Text = '' then
  begin
  TEdit(Sender).Text := '0';
  TEdit(Sender).SelectAll;
  end
else if not TryStrToInt(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
  else if (Nbr >= Low(Shortint)) and (Nbr <= High(Shortint)) then
          TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
end;

procedure TForm1.Edit4Change(Sender: TObject);
var Nbr: Integer;
begin
if TEdit(Sender).Text = '-' then Exit;
if TEdit(Sender).Text = '' then
  begin
  TEdit(Sender).Text := '0';
  TEdit(Sender).SelectAll;
  end
else if not TryStrToInt(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
  else if (Nbr >= Low(Smallint)) and (Nbr <= High(Smallint)) then
          TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
end;

procedure TForm1.Edit5Change(Sender: TObject);
var Nbr: Integer;
begin
if (TEdit(Sender).Text = '') or (TEdit(Sender).Text = '-') then
  begin
  TEdit(Sender).Text := '0';
  TEdit(Sender).SelectAll;
  end
else if not TryStrToInt(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
  else if (Nbr >= Low(Word)) and (Nbr <= High(Word)) then
          TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
end;

procedure TForm1.Edit6Change(Sender: TObject);
var Nbr: Int64;
begin
if (TEdit(Sender).Text = '') or (TEdit(Sender).Text = '-') then
  begin
  TEdit(Sender).Text := '0';
  TEdit(Sender).SelectAll;
  end
else if not TryStrToInt64(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
  else if (Nbr >= Low(Cardinal)) and (Nbr <= High(Cardinal)) then
          TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
end;

procedure TForm1.Edit7Change(Sender: TObject);
var Nbr: Int64;
begin
if TEdit(Sender).Text = '-' then Exit;
if TEdit(Sender).Text = '' then
  begin
  TEdit(Sender).Text := '0';
  TEdit(Sender).SelectAll;
  end
else if not TryStrToInt64(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
  else if (Nbr >= Low(Int64)) and (Nbr <= High(Int64)) then
          TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
end;

procedure TForm1.Edit8Change(Sender: TObject);
var Nbr: Int64;
begin
if (TEdit(Sender).Text = '') or (TEdit(Sender).Text = '-') then
  begin
  TEdit(Sender).Text := '0';
  TEdit(Sender).SelectAll;
  end
else if not TryStrToInt64(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
  else if (Nbr >= Low(Longword)) and (Nbr <= High(Longword)) then
          TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
end;

procedure TForm1.Edit9Change(Sender: TObject);
var Nbr: Extended;
begin
if (TEdit(Sender).Text = '') then
  begin
  TEdit(Sender).Text := '0';
  TEdit(Sender).SelectAll;
  end
else if not TryStrToFloat(TEdit(Sender).Text, Nbr) then TEdit(Sender).Undo
  else if (Nbr >= 0 ) and (Nbr <= (1.7 * Power(2, 64)) - 1) then
          TEdit(Sender).ClearUndo else TEdit(Sender).Undo;
end;

end.

Open in new window

 

DFM unit
   
object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 441
  ClientWidth = 804
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 33
    Top = 32
    Width = 36
    Height = 13
    Caption = 'Integer'
  end
  object Label2: TLabel
    Left = 33
    Top = 60
    Width = 22
    Height = 13
    Caption = 'Byte'
  end
  object Label3: TLabel
    Left = 33
    Top = 86
    Width = 38
    Height = 13
    Caption = 'Shortint'
  end
  object Label4: TLabel
    Left = 33
    Top = 114
    Width = 36
    Height = 13
    Caption = 'Smallint'
  end
  object Label5: TLabel
    Left = 33
    Top = 141
    Width = 26
    Height = 13
    Caption = 'Word'
  end
  object Label6: TLabel
    Left = 33
    Top = 168
    Width = 39
    Height = 13
    Caption = 'Cardinal'
  end
  object Label7: TLabel
    Left = 33
    Top = 195
    Width = 26
    Height = 13
    Caption = 'Int64'
  end
  object Label8: TLabel
    Left = 33
    Top = 221
    Width = 47
    Height = 13
    Caption = 'Longword'
  end
  object Label9: TLabel
    Left = 522
    Top = 32
    Width = 132
    Height = 13
    Caption = '-2147483648..2147483647'
  end
  object Label10: TLabel
    Left = 522
    Top = 59
    Width = 32
    Height = 13
    Caption = '0..255'
  end
  object Label11: TLabel
    Left = 522
    Top = 86
    Width = 48
    Height = 13
    Caption = '-128..127'
  end
  object Label12: TLabel
    Left = 522
    Top = 114
    Width = 72
    Height = 13
    Caption = '-32768..32767'
  end
  object Label13: TLabel
    Left = 522
    Top = 140
    Width = 44
    Height = 13
    Caption = '0..65535'
  end
  object Label14: TLabel
    Left = 522
    Top = 169
    Width = 74
    Height = 13
    Caption = '0..4294967295'
  end
  object Label15: TLabel
    Left = 522
    Top = 198
    Width = 74
    Height = 13
    Caption = '-2^63..2^63-1'
  end
  object Label16: TLabel
    Left = 522
    Top = 221
    Width = 74
    Height = 13
    Caption = '0..4294967295'
  end
  object Label17: TLabel
    Left = 33
    Top = 248
    Width = 33
    Height = 13
    Caption = 'UInt64'
  end
  object Label18: TLabel
    Left = 522
    Top = 248
    Width = 52
    Height = 13
    Caption = '0..2^64'#8211'1'
  end
  object Label19: TLabel
    Left = 33
    Top = 280
    Width = 33
    Height = 13
    Caption = 'Real48'
  end
  object Label20: TLabel
    Left = 522
    Top = 280
    Width = 150
    Height = 13
    Caption = '-2.9 x 10^'#8211'39 .. 1.7 x 10^38  '
  end
  object Label21: TLabel
    Left = 32
    Top = 312
    Width = 44
    Height = 13
    Caption = 'Currency'
  end
  object Label22: TLabel
    Left = 522
    Top = 312
    Width = 251
    Height = 13
    Caption = '-922337203685477.5808.. 922337203685477.5807'
  end
  object Label23: TLabel
    Left = 537
    Top = 352
    Width = 162
    Height = 13
    Caption = 'AllowedStr = '#39'M'#39','#39'A'#39','#39'H'#39','#39'D'#39','#39'I'#39','#39'7'#39','#39'8'#39
  end
  object Label24: TLabel
    Left = 32
    Top = 352
    Width = 23
    Height = 13
    Caption = 'Char'
  end
  object Label25: TLabel
    Left = 34
    Top = 398
    Width = 34
    Height = 13
    Caption = 'Format'
  end
  object Label26: TLabel
    Left = 537
    Top = 398
    Width = 177
    Height = 13
    Caption = 'ss-nssn-nn  for example AE-5DR8-34'
  end
  object Edit1: TEdit
    Left = 112
    Top = 29
    Width = 400
    Height = 21
    TabOrder = 0
    Text = '0'
    OnChange = Edit1Change
  end
  object Edit2: TEdit
    Left = 112
    Top = 56
    Width = 400
    Height = 21
    TabOrder = 1
    Text = '0'
    OnChange = Edit2Change
  end
  object Edit3: TEdit
    Left = 112
    Top = 83
    Width = 400
    Height = 21
    TabOrder = 2
    Text = '0'
    OnChange = Edit3Change
  end
  object Edit4: TEdit
    Left = 112
    Top = 110
    Width = 400
    Height = 21
    TabOrder = 3
    Text = '0'
    OnChange = Edit4Change
  end
  object Edit5: TEdit
    Left = 112
    Top = 137
    Width = 400
    Height = 21
    TabOrder = 4
    Text = '0'
    OnChange = Edit5Change
  end
  object Edit6: TEdit
    Left = 112
    Top = 164
    Width = 400
    Height = 21
    TabOrder = 5
    Text = '0'
    OnChange = Edit6Change
  end
  object Edit7: TEdit
    Left = 112
    Top = 191
    Width = 400
    Height = 21
    TabOrder = 6
    Text = '0'
    OnChange = Edit7Change
  end
  object Edit8: TEdit
    Left = 112
    Top = 218
    Width = 400
    Height = 21
    TabOrder = 7
    Text = '0'
    OnChange = Edit8Change
  end
  object Edit9: TEdit
    Left = 112
    Top = 245
    Width = 400
    Height = 21
    TabOrder = 8
    Text = '0'
    OnChange = Edit9Change
  end
  object Edit10: TEdit
    Left = 112
    Top = 277
    Width = 400
    Height = 21
    TabOrder = 9
    Text = '0'
    OnChange = Edit10Change
  end
  object Edit11: TEdit
    Left = 112
    Top = 309
    Width = 400
    Height = 21
    TabOrder = 10
    Text = '0'
    OnChange = Edit11Change
  end
  object Edit12: TEdit
    Left = 112
    Top = 352
    Width = 400
    Height = 21
    TabOrder = 11
    OnChange = Edit12Change
  end
  object Edit13: TEdit
    Left = 112
    Top = 395
    Width = 400
    Height = 21
    TabOrder = 12
    OnChange = Edit13Change
  end
end

Open in new window

2
Author:Mahdi78
Enjoy this complimentary article view.

Get unlimited access to our entire library of technical procedures, guides, and tutorials written by certified industry professionals.

Get 7 days free
Click here to view the full article

Using this article for work? Experts Exchange can benefit your whole team.

Learn More
COLLABORATE WITH CERTIFIED PROFESSIONALS
Experts Exchange is a tech solutions provider where users receive personalized tech help from vetted certified professionals. These industry professionals also write and publish relevant articles on our site.
Ask questions about what you read
If you have a question about something within an article, you can receive help directly from the article author. Experts Exchange article authors are available to answer questions and further the discussion.
Learn from the best.