11

我需要向 TDataSet 添加其他字段,这些字段在基础数据库中不存在,但可以从现有字段派生。我可以使用 caclulated 字段轻松地做到这一点,并且效果很好。

现在我想编辑这些字段并将更改的数据写回。我可以反转计算以将数据写回现有字段,但数据库控件只是不允许我编辑计算字段。

有什么方法可以让我这样做吗?

更新: 好的,关于背景的更多细节。

数据集有一个 blob 字段,它是一个 TBytes 表示。一些字节被标识为包含可以用现有 DB 编辑字段以方便的方式表示的信息。但是,并非所有字节都是已知的,因此 TBytes 表示必须保持原样,以便通过另一个知道它的应用程序进行处理。此应用程序还修改现有记录并插入新记录。

数据集中不同记录的 TBytes 通常映射到不同的字段表示,尽管在数据集上设置过滤器或范围将确保它们具有相同的映射。

正如我所说,提取已知字节并通过计算字段将其转换为字符串、日期、数字等是没有问题的。也可以将这些值重新转换为 TBytes。问题是使这些额外的字段可编辑,同时保持数据集导航不变。

如果有帮助:我们有执行双向映射的类,将字段公开为已发布的属性。

4

7 回答 7

4

答案取决于您使用的数据访问组件。我正在使用 Anydac,它支持 fkInternalCalc 字段,可以像手动编辑一样计算。

于 2011-03-19T09:14:27.763 回答
3

我认为计算字段根据定义是只读的,其值是在客户端计算的。您想要的可能可以通过可更新的视图来实现。您已经可以使用计算字段定义视图 - 这些将在服务器上的 SQL 中计算 - 以及一个更新触发器,也可能是一个插入触发器 - 以执行反向计算。然后从客户端您可以像表格一样透明地使用视图。

于 2011-03-18T12:04:19.827 回答
3

我在 ClientDataSet 上遇到了类似的问题,我已经使用 SQL-Stmt 上的虚拟文件解决了这个问题,因此我可以模拟数据库中的字段。

看我的问题

于 2011-03-18T12:16:52.550 回答
1

您可以使用 TDatasetProvider.OnGetRecords (不记得这是否是事件的正确名称)并修改发送到 Clientdataset 的数据包。

当然,正如 TOndrej 所说,您必须在 ApplyUpdates 处理程序上处理它们。

于 2011-03-18T13:39:00.213 回答
0

Woll2Woll 的 infopower 组件(我刚刚测试了他们的 TwwDBEdit)允许这样做。因此,我认为无论您处于 TDBEdit 级别(或 TFieldDataLink 级别)的任何块。

我不知道 TwwDBEdit 有什么不同。(而且我不确定许可协议是否允许我在这里发布......)。

于 2011-03-18T14:46:12.637 回答
0

在我们的数据库设计中,一些值是相对于另一列(oMean下面称为)的百分比,而其他浮点值存储为绝对值。我们的客户后来想要所有字段的两个选项(rel. 和 abs.),所以我们想出了以下派生自TFloatField. 它应该适用于所有 TDataSet 后代。

unit EditableCalcFloatField;

interface

uses
  db, classes;

type
  TEditableCalcFloatField = class(TFloatField)
  public
    oAbs, oRel, oMean: TField;
  protected
    function GetCanModify: Boolean; override;
    procedure SetAsFloat(Value: Double); override;
  end;

implementation

function TEditableCalcFloatField.GetCanModify: Boolean;
begin
  Result := oMean.AsFloat <> 0;
  if not Result then Exit;
  Result := (oAbs <> nil) or (oRel <> nil);
end;

procedure TEditableCalcFloatField.SetAsFloat(Value: Double);
var
  fMean                                 : Double;
begin
  inherited;

  if DataSet.State in [dsEdit, dsInsert] then begin
    fMean := oMean.AsFloat;
    if fMean = 0 then Exit;
    if oAbs <> nil then
      oAbs.AsFloat := Value / 100 * fMean
    else
      oRel.AsFloat := Value / fMean * 100;
  end;
end;

end.

要在没有包的情况下使用它,您必须在打开数据集之前在 中创建字段FormCreate

with TEditableCalcFloatField.Create(Self) do
begin
  oAbs := sqlMerkmaleYourAbsoluteColumn;
  DisplayLabel := sDisp;
  oMean := sqlMerkmaleAssignedValue_Mean;
  Calculated := True;
  FieldName := 'R' + oAbs.FieldName;
  DataSet := sqlMerkmale;
end;

当然,它的内容可以在OnCalcFields事件中设置,也可以由用户设置。

于 2013-04-17T11:02:23.893 回答
0

使用带有“Select *, 0 as TempField from MyTable”的 TQuery 后代 (MyQuery)

Procedure MyQueryAfterOpen(Dataset:TDataSet);
Begin
    DataSet.FieldByName('TempField').ReadOnly := False;
End;

它现在是一个可编辑的临时字段

于 2015-09-15T06:43:55.713 回答