Here is an example from one of my programs that does what you want.
This is cut from a form that gets user input, in this case a zipcode.
I have another object, called ZipCrit, that I actually want to store
the valid data into. It has a couple of functions that check the user
input to make sure it is a valid zipcode, or zipcode range. These
funcitons return a True if ok, False if not. They are
ZipCrit.AddRange, and ZipCrit.AddZip.
Near the end of this paste, you can see where I test to make sure
everything on the form has valid data, and if not I display a message
with the offending data identified.
procedure TZipForm.OKbtnClick(Sender: TObject);
Var
RangeValid, ZipsValid : boolean;
ZipList : TStringList; {holding bin used for sorting}
i, {index into crit record zips}
j : integer; {index into TStringList zips}
SelectAllConflict : boolean; {flag for both data and select all}
begin
{clear out old ZipCrit data}
ZipCrit.Init;
{Save Away the Select All}
ZipCrit.SelAll := SelAllCB.Checked;
{Narrow down and save ranges}
RangeValid := (ZipCrit.AddRange(From1.Text, To1.Text) and
ZipCrit.AddRange(From2.Text, To2.Text) and
ZipCrit.AddRange(From3.Text, To3.Text) and
ZipCrit.AddRange(From4.Text, To4.Text));
{Compact and Check validity of zips}
with ZipCrit do ZipsValid := (AddZip(zip1.Text) and
AddZip(zip2.Text) and
AddZip(zip3.Text) and AddZip(zip4.Text) and AddZip(zip5.Text)
and
AddZip(zip6.Text) and AddZip(zip7.Text) and AddZip(zip8.Text)
and
AddZip(zip9.Text) and AddZip(zip10.Text) and AddZip(zip11.Text)
and
AddZip(zip12.Text) and AddZip(zip13.Text) and AddZip(zip14.Text)
and
AddZip(zip15.Text) and AddZip(zip16.Text) and AddZip(zip17.Text)
and
AddZip(zip18.Text) and AddZip(zip19.Text) and AddZip(zip20.Text)
and
AddZip(zip21.Text) and AddZip(zip22.Text) and AddZip(zip23.Text)
and
AddZip(zip24.Text));
{Sort Zips}
ZipList := TStringList.Create;
ZipList.Clear; {initialize holding bin}
for i := 1 to 24 do ZipList.Add(ZipCrit.Zips[i]);
ZipList.Sort; {sort the zips in the bin}
i := 1;
for j := 0 to 23 do
if ZipList.Strings[j] <> '' then
begin
ZipCrit.Zips[i] := ZipList.Strings[j];
i := i+1; {increment crit pointer}
{ZipCnt set/managed in AddZip}
end;
{check for data present AND select all checked}
SelectAllConflict := false;
if SelAllCB.Checked and
(( From1.Text <> '') or (Zip1.Text <> '')) then
if messagedlg('The Select All checkbox is checked and '+
chr(13)+'data is present. Data will be ignored. ' +
chr(13)+ 'Is this what you want?',
mtWarning,[mbYes, mbNo],0) = mrNo then SelectAllConflict :=
true;
{all done, close form if no error}
if RangeValid and ZipsValid and(not SelectAllConflict) then close;
end;
function TZipCrit.AddZip(Zip:TZString):boolean;
var
i : integer; {junk working vartiable}
Error : TErrorRec; {error reporting}
begin
Error.Init; {initialize to no errors}
Error.Location := 'AddZip';
Error.Data := '['+Zip+']';
{check for alphas}
for i := 1 to length(Zip) do
if (Zip[i] < '0') or (Zip[i] > '9') then
begin
Error.NoError := false;
Error.ID := 'Invalid Character in Zip';
Error.Text := 'ZipCodes can only include numeric values';
end; {alpha error}
{if ok, add to set}
if Error.NoError then
begin
if Zip <> '' then {check for a blank Zip}
begin
ZipCnt := ZipCnt + 1;
Zips[ZipCnt] := Zip;
AddZip := true;
end; {Blank Zip Check}
end; {Zip Error check}
if Error.NoError = false then
begin
Error.Msg;
AddZip := false;
end; {Zip Error Msg}
end;
procedure TZipCrit.CheckRange(FromZip, ToZip : TZString; Var
Error:TErrorRec);
var i : integer; {basic loop counter}
FromZipNum, ToZipNum : integer; {numeric version of strings}
code : integer; { err code return from val procedure}
begin
Error.Init; {initialize to no errors}
Error.Location := 'Zip CheckRange';
Error.Data := '['+FromZip+'/'+ToZip+']';
{check for blank mismatches}
if ((Fromzip='') and (Tozip<>'')) or
((Fromzip<>'') and (Tozip='')) then
begin {Blank/non-blank error detected}
Error.NoError := false;
Error.ID := 'Blank Mismatch';
Error.Text := 'One of From or To was blank, and the other was
not.';
end; {Blank Mis-match check}
{check for length imbalance}
if Error.NoError and (length(FromZip) <> length(ToZip)) then
begin
Error.NoError := false;
Error.ID := 'Zip Range Length';
Error.Text := 'The From ZipCode is different in length than the To
ZipCode';
end; {Length mismatch}
{check for alphas}
if Error.Noerror then
begin
for i := 1 to length(FromZip) do
if (FromZip[i] < '0') or (FromZip[i] > '9') then Error.NoError
:= false;
for i := 1 to length(ToZip) do
if (ToZip[i] < '0') or (ToZip[i] > '9') then Error.NoError :=
false;
if Error.NoError = false then
begin
Error.ID := 'Invalid Character in Zip';
Error.Text := 'ZipCodes can only include numeric values';
end;
end;{Alpha check in Zips}
{check for from greater than to}
val(FromZip, FromZipNum, Code);
val(ToZip, ToZipNum, Code);
if Error.NoError and (FromZipNum > ToZipNum) then
begin
Error.NoError := false;
Error.ID := 'Range Error';
Error.Text := 'The From ZipCode must be less than the To ZipCode';
end; {From greater than to error}
end; {checkrange}
procedure TZipCrit.Init;
var i : integer;
begin
SelAll := true;
ZipRangeCnt := 0;
for i := 1 to 4 do ZipFrom[i] := '';
for i := 1 to 4 do ZipTo[i] := '';
ZipCnt := 0;
for i := 1 to 24 do Zips[i] :='';
end;
Function TZipCrit.AddRange(FromZip, ToZip : TZString): boolean;
var
RangeValid : boolean;
ErrorCk : TErrorRec;
begin
{check Range}
checkrange(FromZip, ToZip, ErrorCk);
{if OK, add to set}
if ErrorCk.NoError then
begin
if FromZip <> '' then {if blank zips, do nothing}
begin
ZipRangeCnt := ZipRangeCnt +1;
ZipFrom[ZipRangeCnt] := FromZip;
ZipTo[ZipRangeCnt] := ToZip;
Addrange := true; {range OK}
end {Blank Zip check}
end {RangeValid check}
else {invalid range error, don't change ZipCrit}
begin
ErrorCk.Msg;
AddRange := false; {invalid range}
end; {invalid range error}
end; {TZip_Crit.AddRange}
I hope this helps
Dave Draffin
Software Innovations
avg...@earthlink.net
On Tue, 14 Apr 1998 23:17:08 GMT, blombard@<NOSPAM>iu.net (Bob
Quote
Lombardi) wrote:
>I'm a newbie to Delphi, and I'm using 2.0. (It's a long story...)
>I'm porting a large program I wrote in TP5.5/6, a scientific program
>that requires lots of interaction with users. The existing program
>checks the user's input and doesn't allow execution if they've left
>something out, or made a detectable mistake. I can't seem to see how
>to do this in Delphi.
>My form is modal, and I have a QuitBtnClick event handler. What I
>want to do is go over the input, check its values, and then not close
>this form if the data isn't okay. I might add a warning box if I need
>to. Can't seem to get this to work. I've tried several things like:
> CheckifReady(ready); { this a procedure that checks the variables}
> If Ready then close
> else
> ProcedureThatGetsVariables;
>When I single step this code, the boolean Ready is false and it goes
>to the else. I can see my input screen, with the blank TEdit variable
>highlighted (just like I told it to), but then it seems to go through
>the QuitBtnClick procedure again, and this time it closes. Once I tried
>enclosing this in a Repeat Until (ready = true) block. This is an
>infinite loop that tells me it never thinks ready is true. But it
>still closes the form!
>I have a few books, but they don't seem to get into this aspect. I
>thought checking user input was one of the most common things we did.
>Any help appreciated.
>And for the second real dummies question: does every little form (like
>an "about box" with only one quit button) have to be a new unit?
>Bob
>(please remove the obvious spam foiler to reply personally - or use
>one of these addresses)
>Bob Lombardi W4ATM in Melbourne, FL (ex-WB4EHS) \---\---\
>blomb...@iu.net or blomb...@freenet.fsu.edu __@ |
>Bicycling, telescope making, optics, astronomy, _`\<_ |
>Radio Design, piano, SW and ham radio (*)/ (*) |
>Visit the ATM Resource List at http://www.freenet.tlh.fl.us/~blombard
Dave Draffin
Software Innovations Technical Support
Maple Valley, WA USA
avg...@earthlink.net