如何编辑数据集?

问题描述 投票:0回答:2

短版

我怎么打电话:

dataset1.FieldByName(fieldName).AsString := 'Something';

并且有效吗?

长版

我有一个DataSet,恰好是对数据库的ADO查询的结果:

var
    qry: TADOQuery;

qry := ExecuteQueryImplementationIsntImportant('SELECT Username, Fullname FROM Users');

现在,我想在对它进行其他操作之前修改每行[[内存中的Fullname字段(即,它永远不会返回数据库):

while not qry.EOF do begin qry.FieldByName('Fullname').AsString := FormatNamePrettyLike(qry.FieldByName('Fullname').AsString; qry.Next; end;
尝试修改字段会产生例外:

Dataset not in edit or insert mode

解决方案是

克隆

数据集到内存中TClientDatasetTClientDataset
哪个给出了较大的代码:

///<summary>Clones a dataset into a TClientDataSet; which is an editable in-memory DataSet.</summary> function CloneDataSet(dsSource: TDataSet): TDataSet; //TDataSet > TCustomClientDataSet > TClientDataSet var tempProvider: TDataSetProvider; data: OleVariant; ds: TClientDataSet; begin tempProvider := TDataSetProvider.Create(nil); try tempProvider.DataSet := dsSource; data := tempProvider.Data; finally tempProvider.Free; end; ds := TClientDataSet.Create(nil); ds.Data := data; Result := ds; end;

但是这给出了错误:

var qry: TADOQuery; ds: TDataSet; qry := ExecuteQueryImplementationIsntImportant('SELECT Username, Fullname FROM Users'); //Clone to dataset to an in-memory dataset so we can modify it. ds := CloneDataSet(qry); qry.Free; while not ds.EOF do begin ds.FieldByName('Fullname').AsString := FormatNamePrettyLike(ds.FieldByName('Fullname').AsString; ds.Next; end;

解决方法是Dataset not in edit or insert mode

put the dataset in edit mode

现在重复锻炼会出现错误:

字段///<summary>Clones a dataset into a TClientDataSet; which is an editable in-memory DataSet.</summary> function CloneDataSet(dsSource: TDataSet): TDataSet; //TDataSet > TCustomClientDataSet > TClientDataSet var tempProvider: TDataSetProvider; data: OleVariant; ds: TClientDataSet; begin tempProvider := TDataSetProvider.Create(nil); try tempProvider.DataSet := dsSource; data := tempProvider.Data; finally tempProvider.Free; end; ds := TClientDataSet.Create(nil); ds.Data := data; //The in-memory ClientDataSet won't be editable until you mark it editable. ds.Edit; Result := ds; end; 无法修改。

解决方法是Fullname

set Field.ReadOnly to false

重复练习会出现错误:

试图修改只读字段。

所以我放弃了。如何编辑数据集字段?

克隆的内存中TCustomClientDataSet内容就在这里;我只想在客户端上对其进行编辑以进行显示。

delphi delphi-xe6 datasnap
2个回答
3
投票
假设我实际上正确地理解了您的问题,它归结为将

FullName的字段内容更改为一些漂亮的格式化字符串以供显示。

因此,您不想更改实际的字段内容,所以最好的选择是在字段

OnGetText

事件中。适合您任务的事件处理程序可能如下所示:///<summary>Clones a dataset into a TClientDataSet; which is an editable in-memory DataSet.</summary> function CloneDataSet(dsSource: TDataSet): TDataSet; //TDataSet > TCustomClientDataSet > TClientDataSet var tempProvider: TDataSetProvider; data: OleVariant; ds: TClientDataSet; begin tempProvider := TDataSetProvider.Create(nil); try tempProvider.DataSet := dsSource; data := tempProvider.Data; finally tempProvider.Free; end; ds := TClientDataSet.Create(nil); ds.Data := data; //The in-memory ClientDataSet won't be editable until you mark it editable. ds.Edit; //Even after marking the in-memory data-set as editable, you still can't edit it //until you mark all fields as editable. for i := 0 to ds.FieldCount-1 do ds.Fields[i].ReadOnly := False; Result := ds; end;
现在您必须将该事件处理程序连接到该字段。在处理动态字段时,每次打开数据集后都必须这样做:

procedure TMyClass.MakeFullNamePrettyGetText(Sender: TField; var Text: string; DisplayText: Boolean); begin Text := FormatNamePrettyLike(Sender.AsString); end;

只要发生在声明事件的类之外,您就需要在事件名称前加上

TMyClass

的类实例(或您可以调用的任何名称)。

0
投票
下面是从Sql Server编辑数据的完全独立的示例使用ADO + TClientDataSet。所有组件都只需从面板中删除到表单上,然后在qry.FieldByName('Fullname').OnGetText := MakeFullNamePrettyGetText; 过程中的代码中设置所有必要的属性。

[在每个步骤中,我都尝试使用最简单的代码来完成这项工作,以免混淆CDS + TDataSetProvider如何编辑数据的优雅简洁性。满怀希望该代码是不言自明的,几乎没有注释。

您将看到,绝对不会摆弄CDS的TFields的属性是必要的。顺便说一句,我是作为VCL应用程序而不是仅通过控制台来完成此操作的因此从视觉上确认一切正常,这很简单。

作为一种最低的公分母,我使用了D7。在后Unicode Delphi中,服务器上的FullName字段将为NVarChar类型,而字符串字段类型为的CDS会自动调整。

[tbc重新计算的字段]

SetUp

© www.soinside.com 2019 - 2024. All rights reserved.