[Solved] Update form after an edit lazarus / 16-Databases ---------------------------------------------------------------------- madref · 2019-11-20 07:48 I have a form with a StringGrid on it. This string grid is filled by a query (I choose this for certain reasons above a TDBGrid). From this string grid I select 1 record to edit in another form. This all works perfect. The grid is nicely updated....but here it also goes wrong. The query is sorted on date and time. And because of this the update should also re-arrange the query so that the the dates are in the sorted order. But that doe not happen.... How can I correct this? ---------------------------------------------------------------------- MarkMLl · 2019-11-20 08:11 Please explain a little more, possibly with an example of what the grid looks like and what it should look like. MarkMLl ---------------------------------------------------------------------- madref · 2019-11-20 09:08 This is the code to edit. It opens the form to edit and then comes backt to it's routine. 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 TForm_Wedstrijd_Overzicht.BT_GameEditClick(Sender: TObject);var  wID: Integer;  fWI: TForm_WedstrijdInformatie;  c: TGridColumn;  F: TField;  begin  if TQ_Wedstrijden.RecordCount =  0 then begin    Form_Message.MsgWindow(mThink, bOk,      'There are no games in the database.' + sCrLf +      'So no game can be edited !!', Prgnaam);    Exit;  end;  // if  wID := StrToInt (Grid_wedstrijden.Cells[0, Grid_wedstrijden.Row]);  fWI := TForm_WedstrijdInformatie.Create(Self);  try    fWI.ShowWedstrijd(wID);  finally    fWI.Free;  end;  TQ_Wedstrijden.Refresh;  TQ_Wedstrijden.Locate('Wed_ID', wID, []);  for wID := 0 to Grid_wedstrijden.Columns.Count - 1 do begin    c := Grid_wedstrijden.Columns[wID];    F := TField(c.Tag);    Grid_wedstrijden.Cells [wID + Grid_wedstrijden.FixedCols, Grid_wedstrijden.Row] := F.AsString;  end;end;     // BT_GameEditClick  Notice that the 'Screen Before Edit' has the correct sorting and the 'Screen After Edit' not ---------------------------------------------------------------------- MarkMLl · 2019-11-20 09:35 As I see it you have a choice. The crude way of doing it is to use privileged information (i.e. state in the single program that's doing all the work) to recognise that something's changed, and to rerun the query that populates the main grid on screen. The less-crude way is to use a database that has a notification/event facility (PostgreSQL, Firebird) and to make sure that when a row in the database is changed the program receives an event warning it that it's got to reload the grid. MarkMLl ---------------------------------------------------------------------- madref · 2019-11-20 10:01 I am using SQLite ---------------------------------------------------------------------- MarkMLl · 2019-11-20 10:06 Which I think implies that the visibility of the database is limited to the single program. In that case the "principle of least hassle" is probably to simply re-run the query any time you know something's changed. MarkMLl ---------------------------------------------------------------------- madref · 2019-11-20 10:18 That's is what I am doing all the time. But I found the 'problem'. The problem was a piece of code that every time I called this routine it would go looking for the closest game to the current date. I only needed that part at the start when the form is being showed the first time. I made that a separate procedure and deleted that part from the routine and put it somewhere else. And vola. it worked. Thanks for the help ---------------------------------------------------------------------- Zvoni · 2019-11-21 08:29 Quote from: MarkMLl on November 20, 2019, 10:35:32 amAs I see it you have a choice. The crude way of doing it is to use privileged information (i.e. state in the single program that's doing all the work) to recognise that something's changed, and to rerun the query that populates the main grid on screen. The less-crude way is to use a database that has a notification/event facility (PostgreSQL, Firebird) and to make sure that when a row in the database is changed the program receives an event warning it that it's got to reload the grid. MarkMLl You forgot SQLite has a Data Changed Notification, too. ---------------------------------------------------------------------- MarkMLl · 2019-11-21 09:30 Quote from: Zvoni on November 21, 2019, 09:29:44 amYou forgot SQLite has a Data Changed Notification, too. I didn't forget, I didn't know. Does that mean that you're volunteering to add it to the LCL components? At the moment they only support PostgreSQL and Firebird :-) MarkMLl ---------------------------------------------------------------------- Zvoni · 2019-11-21 10:07 Quote from: MarkMLl on November 21, 2019, 10:30:20 amQuote from: Zvoni on November 21, 2019, 09:29:44 amYou forgot SQLite has a Data Changed Notification, too. I didn't forget, I didn't know. Does that mean that you're volunteering to add it to the LCL components? At the moment they only support PostgreSQL and Firebird :-) MarkMLl Hell no! Whatever gave you that idea? I'm still bumbling around a lot.  I'll probably come up with a class-helper for sqlite3conn, but that's about it. There is one thing you have to consider with this Data Change Notification in SQLite3: You cannot use the same db-connection to call a refresh for, which actually committed the update (at least that's how i understand it). Basically it boils down to: Have/use 2 sqlite3conn-Objects Register the callback-function with dbconn1 (and that's the one you use for CUD (NOT CRUD), but use dbconn2 to do the reads/display https://www.sqlite.org/c3ref/update_hook.html