[SOLVED] Multi Delete from a TRxDBGrid lazarus / 16-Databases ---------------------------------------------------------------------- donnie · 2016-03-22 09:47 Hi there, I've got a TRxDBGrid(almost the same with DBGrid just has much more functions) connected to a datasource (which is connected to a tzquery.dataset). The TRxDBGrid Options allow me to have multi selection to rows(Options->dgMultiselect ->True). Can I have multi delete from this TRxDBGrid ? I have connected this TRxDBGrid  with a TDBnavigator and when I select more than one row and press the delete button(-) from navigator no multi delete happens.  It just deletes the first selected row. I don't want to use TDBnavigator  if possible. in order to delete only one row I use the following code: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  index := FindColumnIndex(TRxDBGrid1  , 'NUM');//FindColumnIndex finds the index of the column NUM from the  TRxDBGrid1    TRxDBGrid1.SelectedIndex := index;  deletednum:= TRxDBGrid1.Columns.Items[index].Field.Value;  if MessageDlg('Delete Number', 'Do you wish to Delete this NUM ?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then  begin      DbModule.GeneralQuery.Close;      DbModule.GeneralQuery.Connection := DbModule.ZConnection1;      DbModule.GeneralQuery.SQL.Clear;      DbModule.GeneralQuery.SQL.Text := 'DELETE FROM TABLE WHERE NUM= ' + InttoStr(deletednum);      DbModule.GeneralQuery.ExecSQL;      TRxDBGrid1.DataSource.DataSet.Refresh; (I have posted the same topic at the category databases but I believe this is the right path Programming»Databases) Any help if possible . Thank you. ---------------------------------------------------------------------- mangakissa · 2016-03-22 12:27 Normally only the selected record will be deleted. the deletebutton on your navigator doesn't know the multiple records are selected. You have to override de navigator post button with a procedure that tells if your records are selected or not. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.DBNavigator1Click(Sender: TObject; Button: TDBNavButtonType);begin  if Button = nbPost then  begin    if DBGrid1.SelectedRows.Count > 0 then    begin      with DBGrid1.DataSource.DataSet do      begin        for i := 0 to DBGrid1.SelectedRows.Count-1 do        begin          GotoBookmark(Pointer(DBGrid1.SelectedRows.Items[i]));          Deleterecordprocedure        end;      end;    end else      DBGrid1.DataSource.DataSet.post;  end;end; The only thing I'm not sure if other navigator buttons are working if you overide the onclick procedure. In that case you have to program each button. You also can use this procedure without TNavigator. ---------------------------------------------------------------------- rvk · 2016-03-22 12:33 Quote from: nek on March 22, 2016, 10:47:37 amI don't want to use TDBnavigator  if possible. mangakissa beat me to it... you do indeed need to use SelectedRows (TBookmarks for the TDataset) to delete all records. But because you said you wanted to avoid the TDBNavigator here is a method of using the Ctrl+Delete in the DBGrid. You can use this for rxDBGrid too. Just add this in the OnKeyDown event: It works for single and multiple selected records. It "overrides" the normal Ctrl+Delete and in case multiple records are selected, it loops through all of them and deletes them. In case 1 record is selected the it passes through and the normal Ctrl+Delete is executed. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses LCLType, LCLStrConsts; procedure TForm1.DBGrid1KeyDown(Sender: TObject; var Key: word; Shift: TShiftState);var  idx: integer;  myGrid: TDBGrid;  myDataset: TDataset;begin  if (Key = VK_DELETE) and (ssCtrl in Shift) then  begin    if Sender.InheritsFrom(TDBGrid) then    begin      myGrid := TDBGrid(Sender);      myDataset := myGrid.DataSource.DataSet;      if (myGrid.SelectedRows.Count > 1) then      begin        Key := 0; // ONLY in case of > 1, otherwise do the default Ctrl+Delete        if MessageDlg(format('Delete %d records?', [myGrid.SelectedRows.Count]),          mtConfirmation, mbOKCancel, 0) <> mrCancel then        begin          for idx := 0 to myGrid.SelectedRows.Count - 1 do            if myDataset.BookmarkValid(TBookmark(myGrid.SelectedRows.Items[idx])) then            begin              myDataset.GotoBookMark(Pointer(myGrid.SelectedRows.Items[idx]));            myDataset.Delete;            end;        end;      end;    end;  end;end; ---------------------------------------------------------------------- marcov · 2016-03-22 16:37 Bookmark handling varies wildly with Delphi version too. D2006, D2007 and D2009+ are all different. Still afaik FPC 3.0 should be ok, since it is a TBytes. It might go wrong already at the point where items[] is filled. Or maybe if you change the gotobookmark cast to TBookmark() ---------------------------------------------------------------------- rvk · 2016-03-22 16:43 Argh... I can't reproduce it anymore. It was with Laz1.7/FPC 3.1.1 (trunk) and I kept having memory-leaks multiple times 75 bytes. But I just tested it again and now it works fine. (Either way... FreeBookmark did nothing because the define noautomatedbookmark was on) (I removed the FreeBookmark from my snippet) ---------------------------------------------------------------------- donnie · 2016-03-23 09:18 Excellent!!! You've been more than helpful. I used rvk's solution as it helped me a lot. Both solutions mangakissa and rvk will help me in other commands that I want to execute in multi selected rows, not only the delete procedure. Thank you, once again.