Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   TFileOpenDialog fürht zu kuriosem DBGrid-Verhalten (https://www.delphipraxis.net/189778-tfileopendialog-fuerht-zu-kuriosem-dbgrid-verhalten.html)

mariusbenz 20. Jul 2016 10:53

TFileOpenDialog fürht zu kuriosem DBGrid-Verhalten
 
Vorab schon mal der Code-Abschnitt um den es geht:

Code:
procedure TfrmMain.BtnDateiZuPosClick(Sender: TObject);
  var sTemp : String;
  begin
    if Sender = TObject(BtnOrdnerZuPos) then FODDateiPos.Options:= [fdoPickFolders]
    else if Sender = TObject(BtnDateiZuPos) then FODDateiPos.Options:= [];
    // In DB schreiben
    if FODDateiPos.Execute then
      begin
        sTemp:= FODDateiPos.FileName;
        SetSQLAndExecute(AdsQryMFA, 'UPDATE RLS_Detail ' +
                                    'SET Datei = ' + QuotedStr(sTemp) + ' ' +
                                    'WHERE ID = ' + AdsQuePosition.FieldByName('ID').AsString);
        Book := AdsQuePosition.GetBookmark;
      end;
    // Aktualisieren
    AdsQuePosition.Refresh;

    LblHyperlink.Caption:= AdsQuePosition.FieldByName('Datei').AsString;
  end;
Die Funktion SetSQLAndExecute führt einfach nur den SQL-Befehl aus.

Wenn ich die Prozedur mit den Options [fdoPickFolders] ausführe, bleibt der Cursor an der gleichen Position im DBGrid stehen.

Wenn ich die Prozedur mit den Options [] ausführe, springt der Cursor an die erste Position im DBGrid. Ich habe schon versucht, mir die Position mit dem Bookmark zu merken und dann am Ende wieder dort hinzuspringen. Das funktioniert auch, wenn ich erst danach durch einen Button-Click, oder so wie ich es jetzt ziemlich unschön umgangen habe, indem ich im AfterRefresh der Query einen Timer starte, an die entsprechende Position zurückspringe. Wenn ich z.B. im AfterRefresh direkt an die Position mit GoToBookmark springe, funktioniert das zwar auch, allerdings scheint sich das Grid danach noch zu aktualisieren, sodass ich wieder beim ersten Datensatz lande.

Zudem kann ich das Springen an die erste Position manchmal verhindern, wenn ich kurz im Debugmodus anhalte und da ein paar Sekunden warte.

Hat irgendjemand eine Ahnung, warum sich das Grid in dem einen Fall so komisch verhält, und im anderen Fall richtig?

ConnorMcLeod 20. Jul 2016 11:02

AW: TFileOpenDialog fürht zu kuriosem DBGrid-Verhalten
 
Auf den ersten Blick fehlt mir hier das
Delphi-Quellcode:
GotoBookmark

mariusbenz 20. Jul 2016 11:09

AW: TFileOpenDialog fürht zu kuriosem DBGrid-Verhalten
 
Zitat:

Zitat von ConnorMcLeod (Beitrag 1343054)
Auf den ersten Blick fehlt mir hier das
Delphi-Quellcode:
GotoBookmark

Das stand sowohl in der Prozedur selbst, als auch später im AfterRefresh. Da beides nicht den gewünschten Effekt erzielt hat, steht das jetzt in der Timer-Prozedur.

Code:
procedure TfrmMain.TimerRefreshTimer(Sender: TObject);
  begin
    TimerRefresh.Enabled:= False;
    AdsQuePosition.GotoBookmark(Book);
  end;

ConnorMcLeod 20. Jul 2016 13:37

AW: TFileOpenDialog fürht zu kuriosem DBGrid-Verhalten
 
Vllt ist es einfacher, sich den Ausdruck vom primary key zu merken und nach dem Refresh wieder anzuspringen. Ich versuch halt immer, Timer zu vermeiden ;-)

mariusbenz 20. Jul 2016 14:29

AW: TFileOpenDialog fürht zu kuriosem DBGrid-Verhalten
 
Ich finde die Lösung mit dem Timer auch sehr unschön. Mir schien es nur so, dass das mit dem GotoBookmark nur klappt, wenn ich ihn aus einer komplett anderen Funktion her aufrufe(also alles was nicht direkt mit dem Button-click bzw den Query-Ereignissen zusammenhängt), weil das Grid sich GANZ am Ende irgendwie aktualisiert und dadurch auf den ersten Datensatz springt.

Sir Rufo 20. Jul 2016 14:40

AW: TFileOpenDialog fürht zu kuriosem DBGrid-Verhalten
 
AFAIK sind die Bookmarks von vor dem Refresh nach dem Refresh nicht mehr gültig.

Das kann man aber mit Delphi-Referenz durchsuchenTDataSet.BookmarkValid ganz einfach prüfen :stupid:

mariusbenz 21. Jul 2016 07:16

AW: TFileOpenDialog fürht zu kuriosem DBGrid-Verhalten
 
Als dieses Verhalten das erste Mal aufgetreten ist, sah die Prozedur noch folgendermaßen aus:

Code:
procedure TfrmMain.BtnDateiZuPosClick(Sender: TObject);
  var sTemp : String;
  begin
    if Sender = TObject(BtnOrdnerZuPos) then FODDateiPos.Options:= [fdoPickFolders]
    else if Sender = TObject(BtnDateiZuPos) then FODDateiPos.Options:= [];
    // In DB schreiben
    if FODDateiPos.Execute then
      begin
        sTemp:= FODDateiPos.FileName;
        SetSQLAndExecute(AdsQryMFA, 'UPDATE RLS_Detail ' +
                                    'SET Datei = ' + QuotedStr(sTemp) + ' ' +
                                    'WHERE ID = ' + AdsQuePosition.FieldByName('ID').AsString);
      end;
  end;
Die Bookmarks waren nur der Versuch, diesen Fehler zu kompensieren.

Und auch da war es schon so, dass nach dem FileOpenDialog mit PickFolders der Cursor am gleichen Datensatz stehen geblieben ist,er aber ohne PickFolders auf den ersten Datensatz zurückgesprungen ist, und zwar nachdem die Prozedur beendet war(zumindest scheint es so).

ConnorMcLeod 21. Jul 2016 07:22

AW: TFileOpenDialog fürht zu kuriosem DBGrid-Verhalten
 
Deswegen mein ich: ID merken => Update machen => Refresh => Locate auf gemerkte ID.

mariusbenz 21. Jul 2016 07:56

AW: TFileOpenDialog fürht zu kuriosem DBGrid-Verhalten
 
Danke ConnorMcLeod, die Funktion Locate war die, die meinem Arbeitskollegen nicht mehr eingefallen war, weshalb ich den Umweg über die Bookmarks gemacht habe. Sieht deutlich schöner aus mit dem Locate.

Code:
procedure TfrmMain.BtnDateiZuPosClick(Sender: TObject);
  var sTemp : String;
      LetzteID : Integer;
  begin
    if Sender = TObject(BtnOrdnerZuPos) then FODDateiPos.Options:= [fdoPickFolders]
    else if Sender = TObject(BtnDateiZuPos) then FODDateiPos.Options:= [];
    // In DB schreiben
    if FODDateiPos.Execute then
      begin
        sTemp:= FODDateiPos.FileName;
        SetSQLAndExecute(AdsQryMFA, 'UPDATE RLS_Detail ' +
                                    'SET Datei = ' + QuotedStr(sTemp) + ' ' +
                                    'WHERE ID = ' + AdsQuePosition.FieldByName('ID').AsString);
        LetzteID:= AdsQuePosition.FieldByName('ID').AsInteger;
      end;
    // Aktualisieren
    AdsQuePosition.Refresh;
    Application.ProcessMessages;
    AdsQuePosition.Locate('ID', LetzteID, []);

    LblHyperlink.Caption:= AdsQuePosition.FieldByName('Datei').AsString;
  end;
Richtig funktioniert hat es allerdings erst, nachdem ich nach dem Refresh noch ein ProcessMessages mache. Dadurch kann ich mir auch den ******* Timer sparen.

ConnorMcLeod 21. Jul 2016 08:10

AW: TFileOpenDialog fürht zu kuriosem DBGrid-Verhalten
 
Freut mich, wenns jetzt passt!
Was mir noch aufgefallen ist: das Update passiert nur, wenn FODDateiPos.Execute, aber das Refresh passiert immer. Wenn nicht FODDateiPos.Execute, dann ist LetzteID undefiniert.
Ich würde entweder alles in das if-begin-end hineintun oder die ID schon vor dem if merken (das wäre auch sicherer bezüglich dem Update - wer weiß, was in dem SetSQLAndExecute alles abgeht...).


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:37 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz