Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Вывод информации согласно заданному условию


Автор: Firex 8.9.2011, 12:18
Прошу подсказки оптимального алгоритма.
Здача следующая:
Есть 4 CheckBox, каждое из которых задаёт параметр фильтрации и вывода отлильтрованной информации. Может быть одновременно нажато как 1 так и все 4 CheckBox. Вопрос в том, как наиболее рационально написать действия для каждого из CheckBox, что бы получилось поменьше кода?
Прямой как лом вариант, используя Case для каждой вариации нажатий, но тут не один десяток строк получится...

Автор: rodnover 8.9.2011, 12:27
Код

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TMainForm = class(TForm)
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    CheckBox4: TCheckBox;
    procedure CheckBoxAnyClick(Sender: TObject);
  private
    function GetFilter1: Boolean;
    function GetFilter2: Boolean;
    function GetFilter3: Boolean;
    function GetFilter4: Boolean;
    { Private declarations }
  public
    procedure   ExecuteFilterParam(F1, F2, F3, F4: Boolean);

    property Filter1: Boolean read GetFilter1;
    property Filter2: Boolean read GetFilter2;
    property Filter3: Boolean read GetFilter3;
    property Filter4: Boolean read GetFilter4;
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

{ TA }

// У всех чекбоксов событие OnClick настравиваем на эту процедуру
procedure TMainForm.CheckBoxAnyClick(Sender: TObject);
begin
  ExecuteFilterParam(Filter1, Filter2, Filter3, Filter4);
end;

procedure TMainForm.ExecuteFilterParam(F1, F2, F3, F4: Boolean);
begin
  // Здесь выполняем фильтрации
end;

function TMainForm.GetFilter1: Boolean;
begin
  Result := CheckBox1.Checked;
end;

function TMainForm.GetFilter2: Boolean;
begin
  Result := CheckBox2.Checked;
end;

function TMainForm.GetFilter3: Boolean;
begin
  Result := CheckBox3.Checked;
end;

function TMainForm.GetFilter4: Boolean;
begin
  Result := CheckBox4.Checked;
end;

end.

Автор: AndreyIQ 8.9.2011, 12:28
Цитата(Firex @ 8.9.2011,  12:18)
Прошу подсказки оптимального алгоритма.
Здача следующая:
Есть 4 CheckBox, каждое из которых задаёт параметр фильтрации и вывода отлильтрованной информации. Может быть одновременно нажато как 1 так и все 4 CheckBox. Вопрос в том, как наиболее рационально написать действия для каждого из CheckBox, что бы получилось поменьше кода?
Прямой как лом вариант, используя Case для каждой вариации нажатий, но тут не один десяток строк получится...

Не очень понятно какого рода информация.
Вы бы хоть кусок кода привели.

Автор: Firex 8.9.2011, 13:05
Цитата(rodnover @  8.9.2011,  12:27 Найти цитируемый пост)
Код

procedure TMainForm.ExecuteFilterParam(F1, F2, F3, F4: Boolean);
begin  // Здесь выполняем фильтрации
end;

Скажите, а как это будет выглядеть? У меня немного другая реализация определения нажатых CheckBox, но примерно тоже самое и имею, что вы наисали. Т.е. опять таки придётся теперь для каждой вариации нажатий описывать действия... Или я не прав?
Вот так это выглядит(думаю лучше картинкой, а не кодом):
http://s1.ipicture.ru/Gallery/Viewfull/5771326.html
При нажатии одного из CheckBox активизируются соответствующие поля, если CheckBox=false, то поля не активны.

Автор: pseud 8.9.2011, 17:57
Цитата(Firex @  8.9.2011,  13:05 Найти цитируемый пост)
При нажатии одного из CheckBox активизируются соответствующие поля, если CheckBox=false, то поля не активны. 

придется в отдельных панелях держать, чтоб чекбокс отвечал за свою паенль
http://s1.ipicture.ru/
а код что-то типа
Код

procedure TForm1.CheckBox1Click(Sender: TObject);
var
  i: Integer;
  chk: TCheckBox;
  pnl: TPanel;
  ctrl: TControl;
  bEnabled: Boolean;
begin
  chk := TCheckBox(Sender);
  bEnabled := chk.Checked;
  pnl := TPanel(chk.Parent);
  for i := 0 to pnl.ControlCount - 1 do
  begin
    ctrl := pnl.Controls[i];
    if ctrl <> chk then
      ctrl.Enabled := bEnabled;
  end;
end;

Автор: Firex 8.9.2011, 18:34
Я реализовал всё, остался только последний шаг, а именно:
Нужно как-то фильтровать данные, в зависимости от нажатых CheckBox. На каждый отдельный CheckBox фильтр есть, проблема в том, что я не понимаю как можно эфективно их объеденить(фильтры) если нажаты не 1, а несколько CheckBox. Вопрос в том, каким методом объеденить эти фильтры(если нажаты несколько CheckBox), использовать Case, или же есть что-то более эфективное для такой ситуации. Если писать через Case, то получится около 15 вариантов, а это очень много, учитывая, что нужно обрабатывать кучу операторов для каждого фильтра.

Автор: 14SatanA88 9.9.2011, 08:16
Firex, я не совсем все понял (сонный еще), но вроде бы ты хочешь собрать строку для фильтра.

ну так вот, когда будешь обрабатывать фильтрацию, соединяй куски через 'AND'.
если в строке еще ничего нет, AND там не нужен

ну например так хотя бы:
Код

filter: string;
...
if CheckBox1.Checked=true then filter:=[КУСОК НОМЕР 1];
if CheckBox2.Checked=true then if filter='' then filter:=[КУСОК НОМЕР 2] else filter:=filter+' AND '+[КУСОК НОМЕР 2]
if CheckBox3.Checked=true then if filter='' then filter:=[КУСОК НОМЕР 3] else filter:=filter+' AND '+[КУСОК НОМЕР 3]
if CheckBox4.Checked=true then if filter='' then filter:=[КУСОК НОМЕР 4] else filter:=filter+' AND '+[КУСОК НОМЕР 4]


в итоге соберется ровная строка фильтра.

надеюсь, я правильно понял, что тебе нужно.

Автор: rodnover 9.9.2011, 09:08
Это фильтры для построения запроса в SQL?

Если да, то я делаю так (продолжу свой код)

Код

select *
from table
where ((:FILTER_1 = 0) or (/*Остальные условия фильтра*/))
    and ((:FILTER_2 = 0) or (/*Остальные условия фильтра*/))
    and (/*и так далее*/)


А в программе просто переоткрываю таблицу просто меняя ее параметры

Код

// Фактически это и содержится в  CheckBoxAnyClick или вынесено в отдельную процедуру а-ля ExecuteFilterParam
DataSet.ParamByName('FILTER_1').AsBoolean := Filter1;
DataSet.ParamByName('FILTER_2').AsBoolean := Filter2;
// Забиваем прочие параметры
DataSet.Close;
DataSet.Open;


Если собирать строчку в зависимости от условий -- ошибок кучу можно получить, которые отлаживать не очень просто.

Автор: Firex 9.9.2011, 09:29
Большое спасибо всем отписавшимся! У г-на 14SatanA88 наиболее близкий вариант того, что мне надо. Глядя на его код мне в голову пришло интересное решение, при загрузке программы задать всем фильтрам дефолтные значения, в таком диапазоне, что если пользователь будет использовать несколько фильтров одновременно, то оставшиеся(если таковые будут) не будут мешать основному запросу в виду своих максимальных и минимальных значений соответственно. А при нажатии на кнопку применить запрос будет всегда одинаков, вида Фильтр1+Фильтр2+Фильтр3+Фильтр4.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)