Delphi if-then-else循环问题

Delphi if-then-else循环问题,delphi,loops,if-statement,Delphi,Loops,If Statement,我还是个初学者,我一直试图自己解决这个问题,但我想我运气不好。我认为这可能很简单,但事情是这样的 我有3个复选框。当按下按钮时,每个按钮都会在文本文件中写入一行,但如果未选择任何按钮。我想显示一条消息。但是,即使选中了一个复选框,消息也会弹出。代码如下:顺便说一句,请随意建议任何其他代码,以使其更容易/更清晰 if cbSCV.Checked then WriteLn(permFile, 'scv'); if cbMP.Checked then WriteLn(permFile, 'mp

我还是个初学者,我一直试图自己解决这个问题,但我想我运气不好。我认为这可能很简单,但事情是这样的

我有3个复选框。当按下按钮时,每个按钮都会在文本文件中写入一行,但如果未选择任何按钮。我想显示一条消息。但是,即使选中了一个复选框,消息也会弹出。代码如下:顺便说一句,请随意建议任何其他代码,以使其更容易/更清晰

if cbSCV.Checked then
  WriteLn(permFile, '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.');
尝试将if语句替换为

因为要检查cbBTK.checked值两次

请尝试将if语句替换为


因为您要检查cbBTK.checked值两次

,所以我会这样重写它:

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.');
if not (cbBTK.Checked or cbMP.Checked or cbSCV.Checked) then
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;

这需要相同的行数,但将重复的元素放在一起,以便于快速读取整个构造,并找出不遵循模式的位置。我们的代码中都有您的bug,如果它是这样写的,则更容易看到。

我会这样重写它:

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.');
if not (cbBTK.Checked or cbMP.Checked or cbSCV.Checked) then
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;

这需要相同的行数,但将重复的元素放在一起,以便于快速读取整个构造,并找出不遵循模式的位置。我们的代码中都有您的bug,如果它是这样写的,则更容易看到。

值得一提的是,我可能会颠倒逻辑,像这样编写麻烦的测试:

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.');
if not (cbBTK.Checked or cbMP.Checked or cbSCV.Checked) then
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;

值得一提的是,我可能会颠倒逻辑,编写这样一个麻烦的测试:

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.');
if not (cbBTK.Checked or cbMP.Checked or cbSCV.Checked) then
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;
为了补充@soid:我可能会这样写:

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.');
if not (cbBTK.Checked or cbMP.Checked or cbSCV.Checked) then
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;
这多了几行,但如果您以后需要第四个或第五个复选框,它就不那么容易出错,而且更自动。

要补充@soid的内容,我可能会这样写:

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.');
if not (cbBTK.Checked or cbMP.Checked or cbSCV.Checked) then
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;

这多了几行,但如果以后需要第四个或第五个复选框,它就不那么容易出错,而且更自动。

Hmmm。对于这些事情,我喜欢基于集合的方法。 一种方法是这样

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('');
您还可以将Conj设置为表单字段并设置复选框 在他们的OnClick事件中设置/取消设置此选项


警告:可能缺少一些语法细节,我现在不在delphi IDE上…

Hmmm。对于这些,我喜欢基于集合的方法。 一种方法是这样

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('');
您还可以将Conj设置为表单字段并设置复选框 在他们的OnClick事件中设置/取消设置此选项


警告:可能缺少一些语法细节,我现在不在delphi IDE上…

我可能不会这样重写它,但嘿,这很有趣。我正在工作,这里没有Delphi,所以这只是示例代码。仿制药

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;

我可能不会这样重写,但嘿,这很有趣。我正在工作,这里没有Delphi,所以这只是示例代码。仿制药

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;

只需将if语句重命名为if not cbBTK.Checked and not cbMP.Checked and not cbSCV.Checked,因为您要检查cbBTK.Checked值两次。是的,事实上,如果您查看代码,这正是我所做的…@RRUZ:您应该将您的注释作为答案发布,因为它解决了问题@盖布:当他这么做的时候,你应该接受天哪,我很抱歉。不管怎样谢谢你也许我需要一些睡眠。。。好消息是我的代码还可以。是的,否则我会出于羞愧删除这个问题。只需将if语句重命名为if not cbBTK.Checked and not cbMP.Checked and not cbSCV.Checked,因为你要检查cbBTK.Checked值两次。是的,实际上如果你看代码,这正是我所做的……@RRUZ:你应该把你的评论作为回答,因为它解决了问题@盖布:当他这么做的时候,你应该接受天哪,我很抱歉。不管怎样谢谢你也许我需要一些睡眠。。。好在我的代码还行。是的,否则我会出于羞愧删除这个问题。为什么还要麻烦帕伦斯?有什么问题:如果不是cbBTK.检查过,不是cbMP.检查过,不是cbSCV.检查过,那为什么还要麻烦父母呢?问题是:如果不是cbBTK.Checked,不是cbMP.Checked,不是cbSCV.Checked,那么+1,但我不喜欢这样使用计数;HandleCheckBox的var参数让我感觉更好;我们现在处于迂腐模式,因为只做一次检查的想法是一个很大的改进。@David:这真的是一个品味的问题。我认为将Count作为var参数只会增加不必要的噪音。即使作为局部变量,它的范围也很清楚。这个问题都是关于味道的。所有的解决方案都有效。显然,我们的品味都略有不同+1但我不喜欢那样使用Count;HandleCheckBox的var参数让我感觉更好;我们现在处于迂腐模式,因为只做一次检查的想法是一个很大的改进。@David:这真的是一个品味的问题。我认为将Count作为var参数只会增加不必要的噪音。即使作为局部变量,它的范围也很清楚。这个问题都是关于味道的。所有的解决方案都有效。显然,我们的品味都略有不同!我更喜欢哪一种
INCLUDECOJ,esSCV;到Conj:=Conj+[esSCV]@Ulrich,我试着记起在片场是怎么做的。。。就是这样。谢谢。FWIW我更喜欢IncludeConj,esSCV;到Conj:=Conj+[esSCV]@Ulrich,我试着记起在片场是怎么做的。。。就是这样。谢谢。吹毛求疵的角落:我想那应该是给Dict.Keys做的,写的npermfile,Key;。你终于错过了对迪克特的尝试。-嘿,你说得对。现在我还是不考虑最后一次尝试。非常感谢。吹毛求疵的角落:我想这应该是Dict中的Key。Key do和WriteLnpermFile,Key;。你终于错过了对迪克特的尝试。-嘿,你说得对。现在我还是不考虑最后一次尝试。非常感谢。