delphidelphi-xe6tclientdatasetdeltatgrid

How I get the new Field Value from a TClientDataset in Delphi?


hi i have a problem with TClientDataset in Delphi. I want to get a Dataset with the changed Data.

here is my code:

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;

for example: In column 3 is the text blueblue and I changed it to redred. the counter say me that 1 is changed it is correct but the value said me that the string is blueblue...but I want the data redred :((


Solution

  • There is no NewValue/OldValue information stored on the field. Delta will contain 1 Row for deleted rows 1 Row for new inserted rows 2 Rows for modified rows

    For every row you can ask for delta.UpdateStatus which can be usUnmodified, usModified, usInserted or usDeleted.

    Every unmodified record is followed by a Record with the modifications.

    You will take a look in both records to get Old- and NewValue.

    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;