если тогда еще проблема петли Delphi - PullRequest
1 голос
/ 10 мая 2011

Я все еще новичок, и я пытался решить эту проблему самостоятельно, но, думаю, мне не повезло. Я думаю, что это, вероятно, довольно просто, но вот сделка.

У меня есть 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.');

Ответы [ 6 ]

6 голосов
/ 10 мая 2011

Для чего бы это ни стоило, я бы, вероятно, изменил логику и написал бы такой хлопотный тест:

6 голосов
/ 10 мая 2011

попробуйте заменить if sentence на

if not (cbBTK.Checked) and not (cbMP.Checked) and not (cbSCV.Checked) then

потому что вы проверяете значение cbBTK.checked дважды

2 голосов
/ 10 мая 2011

В дополнение к @ soid's answer : я бы написал так:

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;

Это еще несколько строк, но это, ИМХО, менее подвержено ошибкам и более "автоматическое«если позже вам понадобится четвертый или пятый флажок.

1 голос
/ 10 мая 2011

Хммм.За эти вещи мне нравится подход, основанный на множестве.Одним из способов является

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 сейчас ...

1 голос
/ 10 мая 2011

Я бы переписал это так:

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.');

Это занимает одинаковое количество строк, но объединяет повторяющиеся элементы, чтобы облегчить быстрое чтение всей конструкции и определить места, где вы не следуетешаблон.Ваш баг, который мы все имели в нашем коде, легче увидеть, если он написан так:

0 голосов
/ 11 мая 2011

Я бы не стал переписывать это так, но эй, это весело. Я на работе, и у меня нет 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...