Search code examples
delphidatasourcelazarusdbftdbgrid

DBGrid, dbf merging 2 same rows


I'm using DBGrid, dbf and DataSource just figured how to make so when removing a certain book only the ammount removes by 1. I have been stuck on a task to make 2 rows merge if theyre made identical for example if the books name is "Test" and i'd add another row with books anem "Test" it would merge and change the ammount of the book from 1 to 2 or 2 to 3 etc.

procedure TForm1.Button1Click(Sender: TObject);

begin
  with dbgrid1.DataSource.DataSet do begin
    Insert;
    Edit;
    DBGrid1.DataSource.DataSet.FieldByName('Nr.').AsInteger;
    Fields.fieldbyname('Year').value := Edit1.Text;
    Fields.fieldbyname('Author').value := Edit2.Text;
    Fields.fieldbyname('Name').value := Edit3.Text;
    Fields.fieldbyname('Ammount').value := Edit4.Text;
    Post;
    Next;

  end;
end;  

Here you can see how it look enter image description here

Gads - Year Autos - Author Nosaukums - BooksName Kopijas- Ammount


Solution

  • You could do it doing something like this:

    procedure TForm1.AddBook;
    var
      ADataSet : TDataSet;
    begin
      //  Note: you need to complete this by filling in the DBGrid1.DataSource.DataSet.FieldByName('Nr.').AsInteger;
      //  Also, I'm assuming that the field which stores the number of copies is called "Amount" - change if necessary
      ADataSet := dbgrid1.DataSource.DataSet;
      if ADataSet.Locate('Name', Edit3.Text, []) then begin
        ADataSet.Edit;
        ADataSet.FieldByName('Amount').AsInteger := ADataSet.FieldByName('Amount').AsInteger + 1;
      end
      else begin
        ADataSet.Insert;
        ADataSet.fieldbyname('Year').value := Edit1.Text;
        ADataSet.fieldbyname('Author').value := Edit2.Text;
        ADataSet.fieldbyname('Name').value := Edit3.Text;
        ADataSet.fieldbyname('Amount').value := Edit4.Text;
      end;
      ADataSet.Post;
    end;
    

    This way avoids having two rows in the database with the same Name field value, which is preferable to having duplicates and then merging them together by updating one and deleting the other.

    Also, note that I've avoided using the "with" construct. When you use "with", what you save in typing is often exceeded by the amount of debugging you have to do to fix errors that creep in because of its use.

    However, if this is a multi-user database with a back-end RDMS that supports Sql, it would be better to do the insert or update using Sql statements executed at the server, e.g. using a parameterized Stored Procedure (to avoid Sql-Injection risk), and then refresh the data in the client application.