Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi TJVCSV数据集和过滤器_Delphi_Jedi - Fatal编程技术网

Delphi TJVCSV数据集和过滤器

Delphi TJVCSV数据集和过滤器,delphi,jedi,Delphi,Jedi,在筛选TJvCsvDataSet中上载的.csv文件时,我遇到了一个问题。 以下是要解释的MCVE program Project3; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, JvCsvData, data.DB; var FJvCsvDataSet: TJvCsvDataSet; I:Integer; begin ; FJvCsvDataSet := TJvCsvDataSet.Create(nil

在筛选TJvCsvDataSet中上载的.csv文件时,我遇到了一个问题。 以下是要解释的MCVE

program Project3;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  JvCsvData,
  data.DB;

var
  FJvCsvDataSet: TJvCsvDataSet;
I:Integer;
begin
  ;
  FJvCsvDataSet := TJvCsvDataSet.Create(nil);
  FJvCsvDataSet.CsvFieldDef :=
    'VTHB:%,VTHS:%,VTHBBP:&,VTBBSP:&,VTHBLP:&,VTHBLS:&,VTHTS:@';
  FJvCsvDataSet.FieldDefs.Add('VTHB', ftInteger, 0, False);
  FJvCsvDataSet.FieldDefs.Add('VTHS', ftInteger, 0, False);
  FJvCsvDataSet.FieldDefs.Add('VTHBBP', ftFloat, 0, False);
  FJvCsvDataSet.FieldDefs.Add('VTBBSP', ftFloat, 0, False);
  FJvCsvDataSet.FieldDefs.Add('VTHBLP', ftFloat, 0, False);
  FJvCsvDataSet.FieldDefs.Add('VTHBLS', ftFloat, 0, False);
  FJvCsvDataSet.FieldDefs.Add('VTHTS', ftDateTime, 0, False);

    FJvCsvDataSet.FileName :=
    'E:\...\abc.csv';
  FJvCsvDataSet.Open;
  FJvCsvDataSet.First;
//  FJvCsvDataSet.Sort('VTHB,VTHBBP', True);
  FJvCsvDataSet.Filtered := False;
  FJvCsvDataSet.Filter := '';
  for I := 1 to 1093 do
  begin
    FJvCsvDataSet.Filter:='VTHB=' + IntToStr(I);
    FJvCsvDataSet.Filtered := True;
  end;
  FJvCsvDataSet.Free;
end.
下面是FJvCsvDataSet上传的abc.csv示例

VTHB,VTHS,VTHBBP,VTBBSP,VTHBLP,VTHBLS,VTHTS
1,1,3.05,279.86,3.1,115.98,2019-08-10 14:28:47.505
1,2,3.9,259.65,3.95,237.73,2019-08-10 14:28:47.52
1,3,3.9,136.48,3.95,31.97,2019-08-10 14:28:47.52
1,5,10.5,68.83,11,52.03,2019-08-10 14:28:47.52
1,4,12.5,41.4,13,47.75,2019-08-10 14:28:47.52
2,1,3.05,279.86,3.1,115.98,2019-08-10 14:28:47.863
2,2,3.9,259.65,3.95,237.73,2019-08-10 14:28:47.863
2,3,3.9,136.48,3.95,31.97,2019-08-10 14:28:47.863
2,5,10.5,68.83,11,52.03,2019-08-10 14:28:47.863
2,4,12.5,41.4,13,47.75,2019-08-10 14:28:47.863
当语句
FJvCsvDataSet.Filter:='VTHB='+IntToStr(I)时
FJvCsvDataSet。RecordCount
不会更改,因此不会执行筛选


我做错了什么?

我不认为您做错了什么,只是TJvCsvDataSet以一种非常奇怪的方式实现了过滤

使用您的代码设置和打开数据集,以下代码工作正常,并生成预期的记录(在VCL版本代码的DBGrid中观察到):

这将导致FJvCsvDataSet.RecordCount按其应有的值为5。这种过滤方式使用以下枚举作为SetFilterNum的第二个参数:

TJvCsvFilterNumCompare = (jfIntEqual, jfIntNotEqual, jfLessThan, jfGreaterThan);
但是,这样做,

FJvCsvDataSet.Filter:= 'VTHB=1';
产生不正确的结果,即未筛选出任何记录,且记录计数为10。显然出了点问题,如果我发现了问题所在,我稍后会回来说

更新我对它进行了更深入的研究,确实有些东西 奇怪的事情正在发生

正在做

FJvCsvDataSet.Filter:= 'VTHB = 1';
FJvCsvDataSet.Filtered := True;
没有任何影响,数据集甚至不扫描记录以查看它们是否正确 匹配过滤器。奥托这样做

FJvCsvDataSet.SetFilter('VTHB', '1');
FJvCsvDataSet.Filtered := True;
是否通过SetFilter方法导致行开始扫描

// string Filtering: Make Rows Visible Only if they match filterString
procedure TJvCustomCsvDataSet.SetFilter(const FieldName: string; Pattern: string);
行是否正确标记为已过滤取决于它们是否匹配过滤器。 然而,至少有两件奇怪的事情:

  • 所有记录,无论是否匹配,仍由网格显示。我觉得这个 意味着问题可能存在于其他地方,可能是内部SkipFiltered方法, 但是,为什么要使用
    FJvCsvDataSet.SetFilterNum('VTHB',jfIntEqual,1)
    呢? 需要进一步探索

  • 应用筛选器后对数据集调用Close和Open不会导致 按逻辑应该重新扫描的行,但是我们不调用SetFilter 第二次,所以这大概是瓦德。但这是一个stange设计,因为
    SeFilter
    首先不应该公开访问,它应该由
    Filter
    属性的setter调用,imo

更新#2好吧,我们不能说没有得到警告

请注意,此功能与通常在VCL TTable组件中找到的过滤功能不兼容或类似


前面的描述是用过滤字段作为字符数据来表达的,所以我想知道它是否打算处理ftInteger字段……

在我看来,
TJvCsvDataSet
应该扩展
TClientDataSet
。实施起来会简单得多。相反,他们选择重新发明轮子,他们的过滤功能不是标准的。@Olivier:是的,我完全同意。从资料来源来看,作者显然有一些特定的想法,他们正试图做,从过滤的角度来看,但对我来说,这仍然是一个谜。
// string Filtering: Make Rows Visible Only if they match filterString
procedure TJvCustomCsvDataSet.SetFilter(const FieldName: string; Pattern: string);