我试图通过使用clone cursor来使用indexdef来查找记录,从而在clientdataset中找到记录的子集。在下面的示例中,我创建了一个按钮来实现克隆创建。该代码适用于名为cdsData的clientdataset。但是,如果我将cdsData嵌套在另一个数据集(cdsMaster)中,那么按钮代码将无法找到indexDef。
Form:(包括显示数据源和clientdatasets的两个clientdatasets。在下面的第一个单元示例中省略dsMaster& cdsMAster)
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 289
ClientWidth = 554
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 32
Top = 24
Width = 75
Height = 25
Caption = 'Clone'
TabOrder = 0
OnClick = Button1Click
end
object dsMaster: TDataSource
DataSet = cdsMaster
Left = 56
Top = 80
end
object cdsMaster: TClientDataSet
Aggregates = <>
Params = <>
Left = 56
Top = 144
end
object dsData: TDataSource
DataSet = cdsData
Left = 152
Top = 88
end
object cdsData: TClientDataSet
Aggregates = <>
Params = <>
Left = 152
Top = 144
end
end
成功的cdsData单位:
unit IndexFindTest;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Data.DB, Datasnap.DBClient;
type
TForm1 = class(TForm)
dsData: TDataSource;
cdsData: TClientDataSet;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Disp, Lbl : string;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
Clone: TClientDataset;
begin
Clone := TClientDataset.Create(nil);
try
Clone.CloneCursor(cdsData,false);
cdsData.IndexDefs.Update;
clone.IndexName := cdsData.IndexDefs.find ('Lbl').Name;
//..added code to select a range of records using the IndexDef
finally
clone.free;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
disp := 'Item 1';
lbl := 'a';
with TStringField.Create(Self) do begin
Name := 'MstrDisplays';
FieldKind := fkData;
FieldName := 'Displays';
Size := 10;
DataSet := cdsData;
end;
with TStringField.Create(Self) do begin
Name := 'MstrLabel';
FieldKind := fkData;
FieldName := 'Label';
Size := 10;
DataSet := cdsData;
end;
with cdsData.IndexDefs.AddIndexDef do begin
Name := 'Lbl';
Fields := 'Displays;Label';
Options := [ixCaseInsensitive];
end;
cdsData.CreateDataSet;
end;
end.
失败的嵌套版本:
unit IndexFindTest2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Data.DB, Datasnap.DBClient;
type
TForm1 = class(TForm)
dsMaster: TDataSource;
cdsMaster: TClientDataSet;
Button1: TButton;
dsData: TDataSource;
cdsData: TClientDataSet;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Disp, Lbl : string;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
Clone: TClientDataset;
begin
Clone := TClientDataset.Create(nil);
try
Clone.CloneCursor(cdsData,false);
cdsData.IndexDefs.Update;
//Error generated in next line
clone.IndexName := cdsData.IndexDefs.find ('Lbl').Name;
//..added code to select a range of records using the IndexDef
finally
clone.free;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
disp := 'Item 1';
lbl := 'a';
with TStringField.Create(Self) do begin
Name := 'MstrTitle';
FieldKind := fkData;
FieldName := 'Title';
Size := 10;
DataSet := cdsMaster;
end;
with TDataSetField.Create(Self) do
begin
Name := 'MstrDisplay';
FieldName := 'Displays';
DataSet := cdsMaster;
end;
cdsData.DataSetField := TDataSetField(cdsMaster.FieldByName('Displays'));
with TStringField.Create(Self) do begin
Name := 'ClientNested';
FieldKind := fkData;
FieldName := 'Notes';
Size := 10;
DataSet := cdsData;
end;
with TStringField.Create(Self) do begin
Name := 'kntLabel';
FieldKind := fkData;
FieldName := 'Label';
Size := 10;
DataSet := cdsData;
end;
cdsData.IndexDefs.Update;
with cdsData.IndexDefs.AddIndexDef do begin
Name := 'Lbl';
Fields := 'Notes;Label';
Options := [ixCaseInsensitive];
end;
cdsMaster.CreateDataSet;
end;
end.
运行第二个程序时,我收到错误
cdsData:找不到索引'Lbl'。
我可以在两个程序之间识别的唯一区别是cdsData嵌套在第二个版本中。我在CaryJensen的深度Delphi中找到了一个注释:clientDatasets第2版(第128页)声明错误可能发生并且可以使用更新修复,但无论在哪个序列中我应用更新,它都不适用于这种情况。 / p>
任何人都可以解释这个问题吗?嵌套数据集是否有其他步骤?