为什么我的Delphi过滤器不起作用?

时间:2017-03-27 05:32:42

标签: delphi

test := TFDMemTable.Create(nil);
test.CopyDataSet(TempUnplannedDemand, [coStructure, coRestart, coAppend]);
test.First;
    while not test.Eof do
    begin
      ShowMessage(DateTimeToStr(test.FieldByName('demand_date').AsDateTime) +
                ' - ' +
                IntToStr(test.FieldByName('level').AsInteger));
      test.Next;
    end;

将显示
2017/03/24 - 1 2017/03/24 - 0
2017/03/24 - 1 2017/03/24 - 1

  test.IndexFieldNames := 'level';

  //test.SetRangeStart;
  //test.FieldByName('level').AsInteger := 0;
  //test.SetRangeEnd;
  //test.FieldByName('level').AsInteger := 0;
  //test.ApplyRange;

  //test.SetRange([0],[0]);

  test.Filter := 'level=0';
  test.Filtered := True;

  test.First;
  while not test.Eof do
  begin
      ShowMessage(DateTimeToStr(test.FieldByName('demand_date').AsDateTime) +
                ' - ' +
                IntToStr(test.FieldByName('level').AsInteger));
      test.Next;
    end;

将显示
2017/03/24 - 1 2017/03/24 - 0
2017/03/24 - 1 2017/03/24 - 1

为什么test.Filter:='level = 0';不工作

test.Filter:='level = 0'后的抱歉结果是RecCount = 0.

test.Filter:='level = 1'=> RecCount = 3
test.Filter:='level<> 1' => RecCount = 1

2 个答案:

答案 0 :(得分:5)

我认为你的问题必须在于你没有包含在你的q中。以下工作正常并产生Level = 0和Level = 1的预期结果。Test数据集的字段ID = ftInteger,Demand_Date = ftDateTime和Level = ftInteger,并通过a TDBGrid连接到TDataSource procedure TForm1.FormCreate(Sender: TObject); begin Test.CreateDataSet; Test.InsertRecord([1, '24/03/2017', 0]); Test.InsertRecord([2, '24/03/2017', 1]); Test.InsertRecord([3, '24/03/2017', 0]); Test.InsertRecord([4, '24/03/2017', 1]); Test.InsertRecord([5, '24/03/2017']); // <- this leaves the Level column as Null Test.IndexFieldNames := 'Level'; end; procedure TForm1.ApplyFilter; begin Test.Filtered := False; Test.Filter := 'Level=0'; // or 'Level=1' Test.Filtered := True; end;

public boolean add(Virus v) {
    if((this.size()< ConfigObject.getInstance().surviverPopulation  //if the size of the new population is < surviverPopulation
            || v.getFitness() > this.getLast().getFitness())        //or the fitness is higher than that of the last member
            && v.getFitness() > 0.0                                 //and the fitness is higher than 0
            && !v.isDead()                                          //and the virus is alive
            && !this.contains((Virus)v)) {                          //and it is not yet in the list
        super.add(v);                                               //add it normally
        Collections.sort(this, new Comparator<Virus>() {            //sort the list
            //define parameter to sort by
            @Override
            public int compare(Virus virus1, Virus virus2) {        //with custom comparator
                if(virus1.getFitness() == virus2.getFitness()) {
                    return 0;
                } else if (virus1.getFitness() > virus2.getFitness()) {
                    return -1;
                } else {
                    return 1;
                }
            }
           });
    }
    while(this.size() > 300) {
        this.removeLast();
    }
    return true;
} 

注意ID = 5的数据行;这不包含Level列的值,FireDAC因此将其视为包含Null值,因此,该行将不会包含在已过滤的重新设置中,无论Level是否指定为1或0,因为Null不匹配这些

顺便说一下,一个空的ftInteger列将返回0作为其AsInteger值,因此将返回一个ftString值。

答案 1 :(得分:-1)

如果它可以找到级别为1的记录但是它在级别0失败,那么它就可以为过滤中的某些内容保留0或者根本没有0。试试这个

filter:='level<1';

或尝试使用like语句(更好的解决方案)将文本作为文本访问

filter:='level like '+quotedStr('0');

同时检查您的数据类型。这可能是你不期望的。如果是文本,则空值可以存储在表格中(因此您无法找到它)