![]() |
Stringgrid "schnell" beladen
Hallo liebe Mitdelphianer, *g*
heute geht es mir darum eine TStringgrid Instanz möglichst Effizient zu beladen... JA ich weiß das ein TStringgrid für größere Datenmengen nicht wirklich gut geeignet ist. Und Ich weiß das es Ideal wäre nur wenig mehr als den angezeigten Bereich an Daten zu laden. Das ist jetzt nicht das Thema. Wie also bekomme ich möglichst schnell ein Gitter mit 3 * ca. 16000 Zellen gefüllt? Die 3 Datenfelder werden aus einer Datenbank gelesen und es können unterschiedlich viele Zeilen/Datensätze sein. -Ich dachte erst ich könnte mir zeitsparen wenn ich z.B. Das Gitter nicht immer Zeile für Zeile vergrößere sondern einmal die nötige Größer ermittele und setzte... leider dauert Dataset.recordcount auch lange und wird nicht überall unterstützt :( -> Also könnte es Sinn machen einfach in großen Schritten den Rowcount zu erhöhen ? Kostet das überhaupt Zeit? -Z.z. Wird Schreibend auf CELLS[c,r] zugegriffen. Ich habe es auch schon mal mit ROWS[r].commatext versucht, scheint keinen Gewinn zu bringen(vielleicht weil das zusammen bauen und auseinander bauen der Feld Inhalte die Zeit wieder auffrisst). -Rows[r].append würde ja nur sinn machen wenn das gitter dynamisch erweitert wird. Und ich weiß nicht ob es schneller ist. habt ihr ne Idee? |
Re: Stringgrid "schnell" beladen
Hat das StringGrid eventuell einen virtuellen Modus? Der arbeitet meistens schneller als ein normales Befüllen... Sonst könnte ich natürlich noch das VirtualTreeView empfehlen, mit dem sich auch ganz einfach ein Stringgrid "bauen" lässt...
Viele Grüße |
Re: Stringgrid "schnell" beladen
Virtueller Modus ? Hört sich vielversprechend an, aber ich glaube das hat es nicht.
so befülle ich es aktuell:
Delphi-Quellcode:
Nachteil ist, dass ein Dialog auf dem das drauf liegt tooootal lange lädt wenn extrem viele Datensätze in das Gitter kommen.
oldvisible := visible;
visible := false; j := 1; // Zeile Zahler initialisieren RowCount := 2; // Zeilen Anzahl ist 2 ,weniger geht nicht Protokoll := Protokoll + 'RowCount := ...init'#13#10; DataSet.first; While not DataSet.EOF do //bis das ende der datenmenge erreicht ist... begin try For i := 0 to FNames.Count - 1 do // für alle Spalten... try Cells[Anfang + i, j] := DataSet.Fields[i].asString; //..werte eintragen, Anfang = erste spalte( ?0 / 1?) except on E:Exception do raise EXception.create(e.Message + #13#10 + 'ThisRow: CELL=' + inttostr(Anfang+i) + ',' + inttostr(j) + #13#10 + 'Anfang bei=' + inttostr(Anfang) + #13#10 + 'Recordcount=' + inttostr(Dataset.RecordCount) + #13#10 + 'Zeilenanzahl=' + inttostr(Rowcount)); end; DataSet.Next; if not DataSet.eof then// Wenn noch mehr daten vorhanden.. begin //..dann schaffe platz Inc(j); //erhöhe Zeilen zähler (spalte 0 enthält die Überschriften) RowCount := succ(j); // dann Zeilen anzahl mit erhöhen; end; except on E:Exception do raise EXception.create(e.Message + 'DS-Loop position='+inttostr(j)+'Zeilenanzahl= '+inttostr(Rowcount)); end; end; Visible := oldvisible; except on e:Exception do raise exception.Create(Self.Name + '.LoadFromDataSet' + #13#10 + Protokoll + #13#10 + e.Message); end; Ich habe mir schon überlegt ob ich das befüllen des Gitters in einem Hintergrund Thread ausführe...aber leider geht das mit Datenbanken multithreaded ja nicht sooo toll... ...ab einer gewissen Anzahl macht so ein Ladebalken schon fast wieder Sinn.... |
Re: Stringgrid "schnell" beladen
Schonmal .BeginUpdate + .EndUpdate ausprobiert?
also vor dem ganzen Zeug .beginupdate aufrufen und danach .endupdate ;) |
Re: Stringgrid "schnell" beladen
Ich probiers mal aus
|
Re: Stringgrid "schnell" beladen
Diese Funktionalität (BeginUpdate, EndUpdate) bietet das Stringgrid nicht.
Aber da ich eh einen Nachfahren habe könnte ich mal sehen ob es möglich ist das dahinterliegende Persistenz Object vom Typ TStringgridStrings direkt anzusprechen... |
Re: Stringgrid "schnell" beladen
Zitat:
|
Re: Stringgrid "schnell" beladen
StringGrid.RowCount für jede einzelne Zeile erhöhen ist sehr langsam. Sieht so aus, als ob Du die Datenmenge nicht weiter filterst, also könntest Du RowCount gleich am Anfang auf den maximalen Wert setzen.
Dann wenn DataSet wärend der Anzeige des Grid die Datenmenge behält, könntest Du selber das Grid nur mit den sichtbaren Zellen "zeichnen". StringGrid.RowCount := 2.000.000 dauert nur ein paar ms und wenn du das Grid nicht wirklich füllst, gibt es keine weitere Verzögerung. |
Re: Stringgrid "schnell" beladen
Hallo,
man kann RowCount auch erst nach dem Füllen der Zellen auf den endgültigen Wert setzen. Abgesehen davon ist der Ansatz von Satty67 das schnellste, keine Daten ins Grid setzen, nur die Werte über onDrawCell ausgeben lassen. |
Re: Stringgrid "schnell" beladen
Hallo,
Zitat:
select count(*) kennt aber jede (anständige) Datenbank. Von welcher DB reden wir denn ? Ich mache das immer so, alle benötigten Datensätze in eine TList (oder ähnliches) laden Grid.RowCount:= List.Count+1 (dada ;) ). Ausserdem weder der alte Spruch: Wozu 16.000 Records anzeigen ? Heiko |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz