Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вывод информации согласно заданному условию, нечто похожее на фильтр 
V
    Опции темы
Firex
Дата 8.9.2011, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 20.10.2010

Репутация: нет
Всего: нет



Прошу подсказки оптимального алгоритма.
Здача следующая:
Есть 4 CheckBox, каждое из которых задаёт параметр фильтрации и вывода отлильтрованной информации. Может быть одновременно нажато как 1 так и все 4 CheckBox. Вопрос в том, как наиболее рационально написать действия для каждого из CheckBox, что бы получилось поменьше кода?
Прямой как лом вариант, используя Case для каждой вариации нажатий, но тут не один десяток строк получится...
PM MAIL   Вверх
rodnover
Дата 8.9.2011, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 223
Регистрация: 7.4.2009

Репутация: 1
Всего: 10



Код

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.

PM MAIL   Вверх
AndreyIQ
Дата 8.9.2011, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 5.2.2007

Репутация: 1
Всего: 8



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

Не очень понятно какого рода информация.
Вы бы хоть кусок кода привели.
PM MAIL   Вверх
Firex
Дата 8.9.2011, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 20.10.2010

Репутация: нет
Всего: нет



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

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

Скажите, а как это будет выглядеть? У меня немного другая реализация определения нажатых CheckBox, но примерно тоже самое и имею, что вы наисали. Т.е. опять таки придётся теперь для каждой вариации нажатий описывать действия... Или я не прав?
Вот так это выглядит(думаю лучше картинкой, а не кодом):
user posted image
При нажатии одного из CheckBox активизируются соответствующие поля, если CheckBox=false, то поля не активны.
PM MAIL   Вверх
pseud
Дата 8.9.2011, 17:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Экспёрт Тыдыщ
***


Профиль
Группа: Завсегдатай
Сообщений: 1175
Регистрация: 18.5.2007
Где: Минск, Беларусь

Репутация: 10
Всего: 40



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

придется в отдельных панелях держать, чтоб чекбокс отвечал за свою паенль
user posted image
а код что-то типа
Код

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;



--------------------
Испытание чужого терпения можно считать успешным, если оно лопнуло...
PM MAIL   Вверх
Firex
Дата 8.9.2011, 18:34 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 20.10.2010

Репутация: нет
Всего: нет



Я реализовал всё, остался только последний шаг, а именно:
Нужно как-то фильтровать данные, в зависимости от нажатых CheckBox. На каждый отдельный CheckBox фильтр есть, проблема в том, что я не понимаю как можно эфективно их объеденить(фильтры) если нажаты не 1, а несколько CheckBox. Вопрос в том, каким методом объеденить эти фильтры(если нажаты несколько CheckBox), использовать Case, или же есть что-то более эфективное для такой ситуации. Если писать через Case, то получится около 15 вариантов, а это очень много, учитывая, что нужно обрабатывать кучу операторов для каждого фильтра.
PM MAIL   Вверх
14SatanA88
Дата 9.9.2011, 08:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 393
Регистрация: 13.5.2010

Репутация: нет
Всего: 5



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]


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

надеюсь, я правильно понял, что тебе нужно.
PM MAIL ICQ   Вверх
rodnover
Дата 9.9.2011, 09:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 223
Регистрация: 7.4.2009

Репутация: 1
Всего: 10



Это фильтры для построения запроса в 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;


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

Это сообщение отредактировал(а) rodnover - 9.9.2011, 09:11
PM MAIL   Вверх
Firex
Дата 9.9.2011, 09:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 20.10.2010

Репутация: нет
Всего: нет



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

Это сообщение отредактировал(а) Firex - 9.9.2011, 09:30
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0458 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.