if then else loop problem delphi
I'm still a beginner and I have been trying to solve this problem by my self but I guess I 'm out of luck. I think it is probably quite simple but here's the deal.
I have 3 checkboxes. Each one writes a specific line in a text file when a button is pressed but if none are selected. I want a message to be displayed. But what happens there is that the message pops out even if one checkbox is checked. Here's the code: (btw, feel free to suggest any other code that would make it easier/clearer)
if cbSCV.Checked then
WriteLn(permFile, '开发者_StackOverflow中文版scv');
if cbMP.Checked then
WriteLn(permFile, 'mp');
if cbBTK.Checked then
WriteLn(permFile, 'btk');
if not (cbBTK.Checked) and not (cbMP.Checked) and not (cbBTK.Checked) then
showmessage('Choose at least 1 option.');
try replacing the if sentence
to
if not (cbBTK.Checked) and not (cbMP.Checked) and not (cbSCV.Checked) then
because you are checking the cbBTK.checked
value twice
For what it's worth I'd probably reverse the logic and write the troublesome test like this:
if not (cbBTK.Checked or cbMP.Checked or cbSCV.Checked) then
To complement @soid's answer: I'd probably write it like this:
procedure TForm1.CheckIt;
var
Count: Integer;
procedure HandleCheckBox(ACheckBox: TCheckBox; const AID: string);
begin
if ACheckBox.Checked then
begin
WriteLn(permFile, AID);
Inc(Count);
end;
end;
begin
Count := 0;
HandleCheckBox(cbSCV, 'scv');
HandleCheckBox(cbMP, 'mp');
HandleCheckBox(cbBTK, 'btk');
if Count = 0 then
ShowMessage('Choose at least 1 option.');
end;
This is a few more lines but it is IMHO less error prone and more "automatic" if you later need a fourth or fifth checkbox.
I would rewrite it like this:
if cbSCV.Checked then WriteLn(permFile, 'scv');
if cbMP .Checked then WriteLn(permFile, 'mp' );
if cbBTK.Checked then WriteLn(permFile, 'btk');
if not (cbSCV.Checked) and
not (cbMP .Checked) and
not (cbBTK.Checked) then
showmessage('Choose at least 1 option.');
This takes the same number of lines but places the repeated elements together to make it easy to read the whole construct quickly and spot places where you are not following the pattern. Your bug, which we have all had in our code, is easier to see if it is written like this.
Hmmm. For those things I like a set-based approach. One way is this
type
TEnumSomething = (esSCV, esMP, esBTK);
TSomethingSet = set of TEnumSomething;
{var section}
var
Conj: TSomethingSet;
{code section}
Conj := [];
if cbSCV.checked then
begin
Conj := conj + [esSCV];
WriteLn(permFile, 'scv');
end;
{do this for the other 2 checkboxes}
If Conj = [] then ShowMessage('');
You can also make Conj
an form field and make checkboxes
set/unset this on their OnClick event.
Warning: maybe some syntax detail is missing, I'm not on delphi IDE now...
I probably wouldn't rewrite it like this, but hey, this is fun. I'm at work and I don't have Delphi here, so this is just sample code. Generics!
type
TCheckBoxDict: TDictionary<String, TCheckBox>;
var
Dict: TCheckBoxDict;
function HandleCheckBoxes(ADict: TCheckBoxDict) : boolean;
var
Key: String;
CheckBox: TCheckBox;
begin
Result := false;
for Key in ADict.Keys do
if ADict.Items[Key].Checked then
begin
WriteLn(permFile, Key);
Result := true;
end;
end;
begin
Dict := TCheckBoxDict.Create;
Dict.Add('scv', cbSCV);
Dict.Add('mp', cbMP);
Dict.Add('btk', cbBTK);
if not HandleCheckBoxes(Dict) then
ShowMessage('Choose at least one option');
Dict.Destroy;
end;
精彩评论