delphi - 如何从 Delphi 中的 TClientDataset 获取新的字段值?

标签 delphi delphi-xe6 tclientdataset delta tgrid

嗨,我在 Delphi 中遇到 TClientDataset 问题。我想获得一个包含更改后的数据的数据集。

这是我的代码:

procedure TForm2.btnUpdateClick(Sender: TObject);
var
  I: Integer;
  counter : Integer; //for testing
  value : String;
begin
     if not Self.DatasetArtikel.Active then
     begin
       ShowMessage('Nicht aktiv');
       Exit;
     end;

     if Self.DatasetArtikel.ChangeCount = 0 then
     begin
     ShowMessage('Delta is empty');
     Exit;
     end;

     counter := DatasetArtikel.ChangeCount;

      //DatasetArtikelUpdate.ClearFields;
      //DatasetArtikelUpdate.CreateDataSet;

       DatasetArtikel.Data := Self.DatasetArtikel.Delta; //here i want to transfer the changed data
       Release;

    //for I := 0 to DatasetArtikelUpdate.Fields.Count -1 do
      // if not DatasetArtikelUpdate.Fields[I].IsNull then
        //  value := DatasetArtikelUpdate.Fields[I].NewValue;

        value := DatasetArtikel.Fields[2].OldValue; 
        value := DatasetArtikel.Fields[2].Value;
        value := DatasetArtikel.Fields[2].NewValue; //here i want the new data

        end;

例如:第 3 列中的文本为 blueblue,我将其更改为 redred。计数器告诉我 1 已更改,这是正确的,但值告诉我字符串是 blueblue...但我想要数据 redred :((

最佳答案

字段中没有存储 NewValue/OldValue 信息。 达美航空将包含 1 行用于删除的行 1 行用于新插入的行 2 行用于修改行

对于每一行,您都可以请求 delta.UpdateStatus,它可以是 usUnmodified、usModified、usInserted 或 usDeleted。

每个未修改的记录后面都有一个修改过的记录。

您将查看两条记录以获取旧值和新值。

enter image description here

enter image description here

procedure TTestForm.RunInfoClick(Sender: TObject);
type
  TMyFieldInfo = Record
    FieldName: String;
    Size: Integer;
    DataType: TFieldType;
    FieldKind: TFieldKind;
  end;

var
  I: Integer;
  sl: TStringList;
  old: String;
  FA: Array of TMyFieldInfo;
  F: TField;

  // get fielddefs after openening and a a definition for a calculated field
  // called Status to refect UpdateStatus
  Procedure GetFields;
  var
    I: Integer;
  begin
    SetLength(FA, delta.FieldCount + 1);
    for I := 0 to delta.FieldCount - 1 do
    begin
      FA[I].FieldName := delta.Fields[I].FieldName;
      FA[I].DataType := delta.Fields[I].DataType;
      FA[I].Size := delta.Fields[I].Size;
      FA[I].FieldKind := fkdata;
    end;
    FA[High(FA)].FieldName := 'Status';
    FA[High(FA)].DataType := ftString;
    FA[High(FA)].Size := 10;
    FA[High(FA)].FieldKind := fkcalculated;
    delta.Close;
  end;

// apply our fields to be able to display a calculated field
  Procedure SetFields;
  var
    I: Integer;
  begin
    delta.Fields.Clear;
    for I := Low(FA) to High(FA) do
    begin
      F := DefaultFieldClasses[FA[I].DataType].Create(delta);
      With F do
      begin
        FieldName := FA[I].FieldName;
        FieldKind := FA[I].FieldKind;
        Size := FA[I].Size;
        DataSet := delta;
      end;
    end;
    delta.Open;
  end;

  Procedure LogSL;
  begin
    if sl.Count > 1 then
      Memo1.Lines.Add(sl.Text);
    sl.Clear;
  end;

begin
  Memo1.Lines.Clear;
  sl := TStringList.Create;
  try
    delta.Close;
    delta.Fields.Clear;
    delta.Data := ClientDataSet1.delta;
    GetFields;
    SetFields;

    while not delta.Eof do
    begin
      if delta.UpdateStatus <> usModified then
      begin
        LogSL;
      end;
      if delta.UpdateStatus = usUnmodified then
        sl.Add('Unmodified:')
      else if delta.UpdateStatus = usInserted then
      begin
        sl.Add('Insert:');
      end
      else if delta.UpdateStatus = usDeleted then
      begin
        sl.Add('Deleted:');
      end
      else if delta.UpdateStatus = usModified then
      begin
        sl[0] := ('Modified:');
      end;
      for I := 0 to delta.FieldCount - 2 do // ignore our calculated field
      begin
        if delta.UpdateStatus = usModified then
        begin
          if (sl.Values[delta.Fields[I].FieldName] <> delta.Fields[I].AsString) and not delta.Fields[I].IsNull then
          begin // we had changes
            sl[I + 1] := sl[I + 1] + ' OldValue: ' + delta.Fields[I].AsString;
          end
          else
          begin // we did not have changes take stored OldValue
            sl[I + 1] := sl[I + 1] + ' OldValue: ' + sl.Values[delta.Fields[I].FieldName];
          end
        end
        else // delta.UpdateStatus = usModified
          sl.Add(delta.Fields[I].FieldName + '=' + delta.Fields[I].AsString + old);
      end;
      delta.Next;
    end;
    LogSL;
  finally
    sl.Free;
  end;
end;

procedure TTestForm.deltaCalcFields(DataSet: TDataSet);
begin
  with TClientDataSet(DataSet) do
  begin
    case UpdateStatus of
      usUnmodified:
        FieldByName('Status').AsString := 'Unmod';
      usModified:
        FieldByName('Status').AsString := 'Modi';
      usInserted:
        FieldByName('Status').AsString := 'Ins';
      usDeleted:
        FieldByName('Status').AsString := 'Del';
    end;
  end;
end;

关于delphi - 如何从 Delphi 中的 TClientDataset 获取新的字段值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25747274/

相关文章:

Delphi TThread.CurrentThread 和 EAccessViolation - 这是一个错误还是我的无能..?

delphi - 如何交换指针?

delphi - 初始化和终结的顺序是如何确定的?

delphi - XE6 ClientDataSet AV 尝试从 Firebird 加载数据

delphi - Twitter OAUTH 和 Win32 EXE 桌面应用程序

delphi - 如何将 VLC 中的视频存储到文件中?

delphi - 什么是 .vrc 文件,它是如何生成的,您可以使用 IDE 将其删除吗?

delphi - 支持多种屏幕尺寸

sql - ClientDataset.RefreshRecord 在 Delphi XE 中不再适用于连接表 - 有解决方法吗?

delphi - 如果我只想停止执行并报告错误,该如何在Delphi TDataSetProvider.OnUpdateError中做什么?