Delphi 从多个组合框应用多个筛选器

Delphi 从多个组合框应用多个筛选器,delphi,filter,combobox,pascal,tadotable,Delphi,Filter,Combobox,Pascal,Tadotable,我有一个adotable,我想应用来自多个COBOBOX的多个过滤器,每个组合框对该表应用一个过滤器。我的问题是,每当我从combobox1中选择一个项目时,它就会应用它的过滤器,但当我从下一个combobox2中选择另一个项目时,它就会删除上一个过滤器(combobox1),并应用combobox2中的过滤器。我的问题是:我如何使adotable保留combobox1或combobox2中以前的过滤器,甚至两者都保留,但还要添加combobox3中的第三个过滤器以进行更深入的排序?提前谢谢。

我有一个adotable,我想应用来自多个COBOBOX的多个过滤器,每个组合框对该表应用一个过滤器。我的问题是,每当我从combobox1中选择一个项目时,它就会应用它的过滤器,但当我从下一个combobox2中选择另一个项目时,它就会删除上一个过滤器(combobox1),并应用combobox2中的过滤器。我的问题是:我如何使adotable保留combobox1或combobox2中以前的过滤器,甚至两者都保留,但还要添加combobox3中的第三个过滤器以进行更深入的排序?提前谢谢。 这就是我到目前为止得到的:

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
ADOTable1.Filtered:=false;
ADOTable1.filter:='`enter code here`field1='+ QuotedStr(ComboBox1.Text);
ADOTable1.Filtered:=true;
end;

procedure TForm1.ComboBox2Change(Sender: TObject);
begin
ADOTable1.Filtered:=false;
ADOTable1.filter:=adotable1.Filter+'and field2='+ QuotedStr(ComboBox1.Text);
ADOTable1.Filtered:=true;
end;

procedure TForm1.ComboBox3Change(Sender: TObject);
begin
ADOTable1.Filtered:=false;
ADOTable1.filter:=adotable1.Filter+'and field3='+ QuotedStr(ComboBox1.Text);
ADOTable1.Filtered:=true;
end;

上面的代码在多次更改时是错误的,所以每次都需要重新组合筛选器文本

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
    ComboBoxChange();
end;

procedure TForm1.ComboBox2Change(Sender: TObject);
begin
    ComboBoxChange();
end;

procedure TForm1.ComboBox3Change(Sender: TObject);
begin
    ComboBoxChange();
end;


procedure TForm1.ComboBoxChange();
var
    count: integer;
    sFilter: string;
begin
    count := 0;
    sFilter := '`enter code here`';
    
    if(ComboBox1.Text <> '') then
    begin
        sFilter := 'field1=' + ComboBox1.Text;
        Inc(count);
    end;
    if(ComboBox2.Text <> '')then
    begin
        if count > 0 then
            sFilter := sFilter + 'and field2=' + ComboBox2.Text
        else
            sFilter := sFilter + ' field2=' + ComboBox2.Text
        Inc(count);
    end;
    if(ComboBox3.Text <> '')then
    begin
        if count > 0 then
            sFilter := sFilter + 'and field3=' + ComboBox3.Text
        else
            sFilter := sFilter + ' field3=' + ComboBox3.Text
        Inc(count);
    end;
    ADOTable1.Filtered:=false;
        ADOTable1.filter:=sFilter;
    ADOTable1.Filtered:=true;
end;
程序TForm1.ComboBox1Change(发送方:ToObject);
开始
comboxchange();
结束;
程序TForm1.Combox2Change(发送方:ToObject);
开始
comboxchange();
结束;
程序TForm1.Combox3Change(发送方:ToObject);
开始
comboxchange();
结束;
过程TForm1.ComboBoxChange();
变量
计数:整数;
sFilter:string;
开始
计数:=0;
sFilter:='`在此处输入代码';
如果(ComboBox1.Text“”),则
开始
sFilter:=“field1=”+ComboBox1.Text;
公司(计数);
结束;
如果(ComboBox2.Text“”),则
开始
如果计数>0,则
sFilter:=sFilter+'和field2='+ComboBox2.Text
其他的
sFilter:=sFilter+'field2='+ComboBox2.Text
公司(计数);
结束;
如果(ComboBox3.Text“”),则
开始
如果计数>0,则
sFilter:=sFilter+'和field3='+ComboBox3.Text
其他的
sFilter:=sFilter+'field3='+ComboBox3.Text
公司(计数);
结束;
ADOTABLE 1.筛选:=假;
ADOTABLE 1.过滤器:=sFilter;
ADOTABLE 1.筛选:=真;
结束;

免责声明:此答案中的解决方案需要泛型支持,因此它在旧版本的Delphi中不起作用(您不应该这样做)

  • 您可以将属性应用于存储字段的索引,您将使用该索引在过滤器生成中获取字段名。

  • 要存储每个筛选器的值,可以使用窗体的私有字段

    使用
    {此处为所有其他模块},System.Generics.Collections;
    类型
    TForm1=类(TForm)
    {此处为所有组件声明}
    严格保密
    过滤器:t字典;
    
    我们应该在应用程序启动时初始化
    过滤器
    。您可以在执行初始设置的任何位置执行此操作(
    OnCreate
    OnShow
    或任何其他形式的事件;
    初始化
    部分;等等)。我将使用事件处理程序作为示例。通过双击OnCreate附近的空单元格,可以在Object Inspector的事件选项卡中自动生成空处理程序并将其附加到窗体:

    因此,现在我们应该在此事件处理程序中初始化
    过滤器

    过程TForm1.FormCreate(发送方:TObject);
    开始
    {这里是您以前的所有设置(如果存在)}
    过滤器:=t字典。创建;
    结束;
    
    此外,如果需要,还应该初始化过滤器的默认值。如果您在Object Inspector中设置了
    Text
    的默认值,并希望在筛选器查询中使用这些值,则有必要这样做,因为这样的值不会自动保存到我们的
    筛选器中,因为没有触发任何
    OnChange
    事件

  • 现在,让我们为
    TComboBox
    定义通用事件处理程序,它将值存储到
    过滤器中

    首先,我们应该将事件处理程序的签名添加到表单类的公共部分。由于public是类中的默认访问修饰符,因此可以在组件列表或其他处理程序(如果存在)下添加函数:

    类型
    TForm1=类(TForm)
    {此处为所有组件声明}
    程序变更(发送方:TObject);
    
    然后您可以将光标指向该声明,然后按ShiftCtrlC,这样IDE就会生成如下的空函数:

    程序TForm1.comboxchange(发送方:TObject);
    开始
    结束;
    
    我们已经为每个组合框定义了唯一的
    标记
    值,因此可以将其用作键。事件处理程序非常简单:

    程序TForm1.comboxchange(发送方:TObject);
    开始
    使用发送器作为目标
    Filters.AddOrSetValue(标记、文本);
    结束;
    
    最后,您应该将此事件处理程序添加到每个组合框中。复制函数名并将其粘贴到对象检查器的事件选项卡中
    OnChange
    附近的空单元格中,对要用于筛选的每个组合框重复此操作:

  • 最后一步是编写函数,该函数将生成过滤器查询并更新事件处理程序以使用ADOTable。让我们在Form类的private部分定义函数:

    类型
    TForm1=类(TForm)
    {此处为所有组件声明}
    严格保密
    过滤器:t字典;
    函数GetFilterQuery(SkipImptyValue:Boolean=False):字符串;
    
    按ShiftCtrlC生成函数。在函数中,我们将使用循环迭代
    过滤器
    ,用于为
    过滤器
    的每个元素创建过滤器字符串,并连接所有创建的字符串(我用作临时数据容器):

    函数TForm1.GetFilterQuery(SkipImptyValue:Boolean):字符串; 变量 配对:TPair; 条件:TList; 开始 结果:=字符串。空; 条件:=TList.Create; 对于过滤器中的配对,请执行以下操作: 一对一对 如果(非skipmptyvalues)或(非Value.IsEmpty),则 添加(string.Format('field%d=%s',[Key,Value.QuotedString]); 如果条件计数>0,则 结果:=string.Join('and',Conditions.ToArray); 条件。免费; 结束;
    最后,我们应该在
    OnChange
    事件处理程序中调用此函数:

    程序TForm1.comboxchange(发送方:TObject);
    变量
    查询:字符串;
    开始
    使用发送器作为目标
    过滤器。添加