Question

I'm working on a school project where I have 10 textboxes (5 pairs).

The idea is that the sum of each pair can at most be "3". So

[1] [2]

[1] [0]

...

[2] [1]

I figured that checking this during a "onChange" event is too time consuming so I decided to do it with a button which checks all of them. It will throw a showmessage() as soon as any pair does not satisfy the requirement.

Now is there a way to go over each pair and check if their value is less than or equal to three and is NOT negative? I know I can do it manually by writing a big chunk of code, but I would like to keep it as clean as possible.

Thanks!

Was it helpful?

Solution

Drop ten TEdit controls on a form. Since you have created these manually, you need to make them easily accessible in code, and there is no super-elegant way to do this. But this works:

In your implementation section, define

type
  TEditorPair = record
    First,
    Second: TEdit;
  end;

and add a private field FEditors: array[0..4] of TEditorPair; to your form class. And do

procedure TForm1.FormCreate(Sender: TObject);
begin
  FEditors[0].First := Edit1;
  FEditors[0].Second := Edit2;
  FEditors[1].First := Edit3;
  FEditors[1].Second := Edit4;
  FEditors[2].First := Edit5;
  FEditors[2].Second := Edit6;
  FEditors[3].First := Edit7;
  FEditors[3].Second := Edit8;
  FEditors[4].First := Edit9;
  FEditors[4].Second := Edit10;
end;

Now, select all your ten editor controls, and add a common OnChange event to them.

procedure TForm1.EditorChange(Sender: TObject);

  procedure FailPair(PairIndex: integer);
  begin
    FEditors[PairIndex].First.Color := clRed;
    FEditors[PairIndex].Second.Color := clRed;
  end;

  procedure PassPair(PairIndex: integer);
  begin
    FEditors[PairIndex].First.Color := clWindow;
    FEditors[PairIndex].Second.Color := clWindow;
  end;

var
  i: Integer;
  n1, n2: integer;
begin
  for i := 0 to high(FEditors) do
  begin
    if (FEditors[i].First.Text = '') or (FEditors[i].Second.Text = '') then
      Continue;
    if TryStrToInt(FEditors[i].First.Text, n1) and TryStrToInt(FEditors[i].Second.Text, n2) then
      if InRange(n1+n2, 0, 3) then
        PassPair(i)
      else
        FailPair(i)
    else
      FailPair(i);
  end;
end;

Sample compiled EXE

If you are in to code golf, the EditorChange procedure can be shortened to

procedure TForm1.EditorChange(Sender: TObject);

  procedure PairFeedback(PairIndex: integer; Pass: boolean);
  const
    Colors: array[boolean] of TColor = (clRed, clWindow);
  begin
    FEditors[PairIndex].First.Color := Colors[Pass];
    FEditors[PairIndex].Second.Color := Colors[Pass];
  end;

var
  i: Integer;
  n1, n2: integer;
begin
  for i := 0 to high(FEditors) do
  begin
    if (FEditors[i].First.Text = '') or (FEditors[i].Second.Text = '') then
      Continue;
    PairFeedback(i, TryStrToInt(FEditors[i].First.Text, n1) and
      TryStrToInt(FEditors[i].Second.Text, n2) and InRange(n1+n2, 0, 3));
  end;
end;

where we make use of a couple of 'tricks' such as boolean short-circuit (lazy) evaluation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top