[SOLVED] Iterating over DBGrid.SelectedRows and editing each selected row give Access Violation

The following code works nicely with standard TTable but generates an Access violation with a TDAMemDataTable.
Maybe that the Edit/Post alters in some way the TDAMemDataTable.TBookmarkList?

How can I iterate over the SelectedRows of a DBGrid, editing each row during the iteration, without having to use a parameterized DACommand/StoredProcedure? :wink:


var
  Giorno: TDAMemDataTable;
.....

Giorno := ClientDataModule.tbl_GIORNO;

Giorno.DisableControls;

for i := 0 to dbgrd_GIORNO.SelectedRows.Count - 1 do begin
  Giorno.GoToBookmark(TBookmark(dbgrd_GIORNO.SelectedRows[i])); <=== // Access Violation here!
  Giorno.Edit;
  Giorno.FieldByName('GIUSTIFICATIVO_ID').AsLargeInt := 5;
  Giorno.Post;
end;

Giorno.EnableControls;

Edit: Problem solved (mea culpa)!

ClientDataModule.tbl_GIORNO has two events wired: BeforePost and AfterPost. These events where fired, as they names suggest, BeforePost and AfterPost, thus messing up the Giorno.GoToBookmark(TBookmark(dbgrd_GIORNO.SelectedRows[i])) statement.
Temporarily setting both the events to Nil (and reassigning them after the updates are done), solved the problem for me.


var
  i: integer;
  Giorno: TDAMemDataTable;
begin
  Giorno := ClientDataModule.tbl_GIORNO;
  Giorno.DisableControls;
  Giorno.BeforePost := nil;
  Giorno.AfterPost   := nil;
  Giorno.RemoteUpdatesOptions := Giorno.RemoteUpdatesOptions - [ruoOnPost];

  for i := 0 to dbgrd_GIORNO.SelectedRows.Count - 1 do begin
    Giorno.GoToBookmark(TBookmark(dbgrd_GIORNO.SelectedRows[i]));

    if (Giorno.FieldByName('ORE_EFFETTIVE_HH_MM').AsCurrency > 0) then  begin
      Giorno.Edit;
      Giorno.FieldByName('GIUSTIFICATIVO_ID').AsLargeInt := 5;
      Giorno.Post;
    end;
  end;

  Giorno.ApplyUpdates(False, True);
  Giorno.RemoteUpdatesOptions := Giorno.RemoteUpdatesOptions + [ruoOnPost];
  Giorno.BeforePost := ClientDataModule.tbl_GIORNOBeforePost;
  Giorno.AfterPost   := ClientDataModule.tbl_GIORNOAfterPost;
end;

–

fabio vitale

Hello,
We attached our testcase. Please retest it. Can you attach a small testcase which reproduces it?

I apologize for not being able to upload a test case since my application is very large and it would be difficult to extract it.
As said in my own answer, the problem was that in my BeforePost and AfterPost ClientDatamodule events for the table in question, several DARemoteCommand are launched one after the other, that perform calculations on the data. So if I try to iterate over my dbgrid seleted rows, performing table.edit/table.post, BeforePost and AfterPost events are fired for each post, launching several DARemoteCommands and some table.locate (I know, table.locate in AfterPost are a search for troubles, I’ll modify this) that fiddle in some way with the dbgrid bookmark list.
If I commented out all the statements in both BeforePost and AfterPost events (leaving them wired), the problem vanished. This is why I ended up temporarily un-wiring these events, process the selected items in my grid, then re-wiring the events. Hope it helps. So definitely I confirm that your test case, with wired but empty BeforePost and AfterPost events, works fine.