Autor |
Beitrag |
Holg_i
      
Beiträge: 79
|
Verfasst: Fr 20.08.10 09:54
Zum einen möchte ich gerne das eine ganze Reihe eines Grid getauscht wird. Bleibt mir da nix anderes übrig als
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| V1:=Grid.Cell[0,X]; Grid.Cell[0,X]:=Grid.Cell[0,X+1]; Grid.Cell[0,X+1]:=V1;
V1:=Grid.Cell[1,X]; Grid.Cell[1,X]:=Grid.Cell[1,X+1]; Grid.Cell[1,X+1]:=V1;
V1:=Grid.Cell[2,X]; Grid.Cell[2,X]:=Grid.Cell[2,X+1]; Grid.Cell[2,X+1]:=V1;
.. .. .. ..
V1:=Grid.Cell[45,X]; Grid.Cell[45,X]:=Grid.Cell[45,X+1]; Grid.Cell[45,X+1]:=V1; |
Und zum anderen möchte ich gerne einen Ringbuffer bilden, ALSO
Die erste Zeile eines Grid wird Gelöscht und alle anderen rücken nach .... aus 1 wird 0, 2 wir 1 u.s.w Der neue Wert kommt dann in die letzte chon exestierende Reihe.
Moderiert von Narses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Di 24.08.2010 um 20:25
Moderiert von Narses: Titel um "D4" erweitert.
|
|
zuma
      
Beiträge: 660
Erhaltene Danke: 21
Win XP, Win7, Win 8
D7 Enterprise, Delphi XE, Interbase (5 - XE)
|
Verfasst: Fr 20.08.10 10:52
Holg_i hat folgendes geschrieben : | Zum einen möchte ich gerne das eine ganze Reihe eines Grid getauscht wird. Bleibt mir da nix anderes übrig als
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| V1:=Grid.Cell[0,X]; Grid.Cell[0,X]:=Grid.Cell[0,X+1]; Grid.Cell[0,X+1]:=V1;
V1:=Grid.Cell[1,X]; Grid.Cell[1,X]:=Grid.Cell[1,X+1]; Grid.Cell[1,X+1]:=V1;
V1:=Grid.Cell[2,X]; Grid.Cell[2,X]:=Grid.Cell[2,X+1]; Grid.Cell[2,X+1]:=V1;
.. .. .. ..
V1:=Grid.Cell[45,X]; Grid.Cell[45,X]:=Grid.Cell[45,X+1]; Grid.Cell[45,X+1]:=V1; |
|
wie wärs mit ner Schleife ?
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| for i := 0 to Grid.Cellcount -1 do begin V1:=Grid.Cell[i,X]; Grid.Cell[i,X]:=Grid.Cell[i,X+1]; Grid.Cell[i,X+1]:=V1; end; |
_________________ Ich habe nichts gegen Fremde. Aber diese Fremden sind nicht von hier! (Methusalix)
Warum sich Sorgen ums Leben machen? Keiner überlebts!
|
|
Holg_i 
      
Beiträge: 79
|
Verfasst: Di 24.08.10 15:13
Okay so weit so gut
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| Var Rect: TGridRect; Sele,I, ZB: Integer; ZBuff: ShortString;
begin Rect:=Logik.Selection; Sele:=Rect.Top; ZB:=Logik.Rows[Sele].Capacity; for i := 0 to ZB -1 do begin ZBuff:=Logik.Cells[i,Sele-1]; Logik.Cells[i,Sele-1]:=Logik.Cells[i,Sele]; Logik.Cells[i,Sele]:=ZBuff; end; end; |
Damit kann ich nun die Selektierte Zeile nach oben rutschen lassen. Erst mal Danke.
Aber wie schaffe ich es diesen Ringbuffer aufzubauen... Also ROW[1] wird ROW[0] und ROW[2] wird ROW[1] u.s.w
Am Ende dann denn neuen Wert in Logik.RowCount-1
Es ist eventuell noch zu sagen das es mehrere 1000 Zeilen sein können.
|
|
JoelH
      
Beiträge: 806
Erhaltene Danke: 17
Win10
Delphi Alexandria 11.2 Patch 1
|
Verfasst: Di 24.08.10 15:52
wie wärs mit zwei Schleifen?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm1.Button1Click(Sender: TObject); var n,i : Integer; begin for i := 0 to Grid.Rowcount -2 do begin for n := 0 to Grid.Colcount -1 do Grid.Cells[n,i] := Grid.Cells[n,i+1]; end; end; |
_________________ mfg. Joel
|
|
Holg_i 
      
Beiträge: 79
|
Verfasst: Di 24.08.10 16:06
Danke für den Tipp
ABER
Selbst
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TForm1.Button2Click(Sender: TObject);
var I: Integer;
begin QueryPerformanceCounter(Start); For I:=1 to Logik.RowCount-2 do Logik.Rows[I]:=Logik.Rows[I+1]; QueryPerformanceCounter(Stopp); Edit1.Text:=FloatToStr((Stopp-Start)/Frequenz); NeuerDatensatz; end; |
Was mir schneller erscheint ist mir noch zu langsam... 2,83sec. bei 300.000 Reihen ist bei mir ein no go.
|
|
platzwart
      
Beiträge: 1054
Erhaltene Danke: 78
Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
|
Verfasst: Di 24.08.10 16:12
Gibts da nicht auch sowas wie BeginUpdate und EndUpdate?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure TForm1.Button2Click(Sender: TObject);
var I: Integer;
begin QueryPerformanceCounter(Start); Logik.BeginUpdate; For I:=1 to Logik.RowCount-2 do Logik.Rows[I]:=Logik.Rows[I+1]; Logik.EndUpdate; QueryPerformanceCounter(Stopp); Edit1.Text:=FloatToStr((Stopp-Start)/Frequenz); NeuerDatensatz; end; |
_________________ Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
|
|
Holg_i 
      
Beiträge: 79
|
Verfasst: Di 24.08.10 16:22
So weit mir bekannt geht das bei TStrings... also bei
Rows[I]....
Bringt mir aber rein gar nix
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| procedure TForm1.Button2Click(Sender: TObject);
var I: Integer;
begin QueryPerformanceCounter(Start);
For I:=1 to Logik.RowCount-2 do begin Logik.Rows[I].BeginUpdate; Logik.Rows[I]:=Logik.Rows[I+1]; Logik.Rows[I].EndUpdate; end;
QueryPerformanceCounter(Stopp); Edit1.Text:=FloatToStr((Stopp-Start)/Frequenz); NeuerDatensatz; end; |
|
|
platzwart
      
Beiträge: 1054
Erhaltene Danke: 78
Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
|
Verfasst: Di 24.08.10 16:30
Du machst es ja auch falsch! Du machst ständig ein Begin/End Update, das wird langsam. Du musst vor der Schleife ein Begin machen, nach der Schleife erst wieder End!
Und auch nicht Elementweise mit [I]...
_________________ Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
|
|
Holg_i 
      
Beiträge: 79
|
Verfasst: Di 24.08.10 16:34
Da sich doch BeginUpdate wie auch EndUpdate auf TStrings beziehen kann ich es doch nur für den momentanen TString (Logik.Rows[I]) machen.
Ein BeginUpdate bzw. ein EndUpdate gibt es doch bei TStringGrid selber nicht.. oder sehe ich das falsch.. ach ja ich habe Delphi4
|
|
platzwart
      
Beiträge: 1054
Erhaltene Danke: 78
Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
|
Verfasst: Di 24.08.10 16:39
Du siehst das falsch... Das Begin/End Update bezieht sich auf die visuelle Komponente. Damit sagst du der, sie soll die veränderten Daten erst nach dem Endupdate anzeigen. Bedeutet für dich: anstatt 300.000 mal zu berechnen, ob was neu angezeigt werden muss, machst du das damit nur noch ein mal.
Wenn du das pro Element einmal machst, ändert sich natürlich nix, dann wird wieder 300.000 mal aktualisiert...
Teste doch mal bitte so, wie ich dir geschrieben hatte...
_________________ Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
|
|
Holg_i 
      
Beiträge: 79
|
Verfasst: Di 24.08.10 16:55
Erst mal Danke das du dich meiner annimst... Ich tu mir recht schwer etwas über die Tasten zu erklären.
Nehme ich deine Quelltext kommt
Undefinierter Bezeichner 'BeginUpdate'
wie auch
Undefinierter Bezeichner 'EndUpdate'
Da die Komponente TStringGrid kein BeginUbdate und auch kein EndUpdate kennt.
Somit kann ich deinen Vorschlag nicht testen da ich das Programm nicht zum starten bekomme.
|
|
platzwart
      
Beiträge: 1054
Erhaltene Danke: 78
Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
|
Verfasst: Di 24.08.10 16:57
Dann probier bitte vor der Schleife ein Logik.Rows.BeginUpdate; (ohne das [I]) und nach der Schleife das ganze mit EndUpdate...
_________________ Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
|
|
Holg_i 
      
Beiträge: 79
|
Verfasst: Di 24.08.10 17:03
Wir kommen doch ein Stück weiter.... Rows benötigt aber [I] sonst will es auch nicht
Habe da eben folgendes gefunden
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure LockControl(c: TWinControl; lock: boolean); begin if (c = nil) or (c.Handle = 0) then exit; if lock then SendMessage(c.Handle, WM_SETREDRAW, 0, 0) else begin SendMessage(c.Handle, WM_SETREDRAW, 1, 0); RedrawWindow(c.Handle, nil, 0, RDW_ERASE or RDW_FRAME or RDW_INVALIDATE or RDW_ALLCHILDREN); end; end; |
Werde ich nun mal testen.
|
|
platzwart
      
Beiträge: 1054
Erhaltene Danke: 78
Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
|
Verfasst: Di 24.08.10 17:08
Seltsam... Bei mir funktioniert Logik.Rows.BeginUpdate; und Logik.Rows.EndUpdate; einwandfrei...
_________________ Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
|
|
Tankard
      

Beiträge: 217
Erhaltene Danke: 96
|
Verfasst: Di 24.08.10 17:14
platzwart hat folgendes geschrieben : | Seltsam... Bei mir funktioniert Logik.Rows.BeginUpdate; und Logik.Rows.EndUpdate; einwandfrei... |
Bei mir auch.
|
|
Holg_i 
      
Beiträge: 79
|
Verfasst: Di 24.08.10 17:15
Wie getippt ich habe Delphi4 und damit geht es echt nicht.
Auch das mit dem LockControl(Logik,True); bringt kein Geschwindigkeitsvorteil.
Wie bekomme ich die ganze Sache nur schneller???? mmmmm
Welche ein Geschwindigkeitsvorteil kommt da raus... testet das mal mit so 300000 einträgen.
--- Moderiert von Narses: Beiträge zusammengefasst---
Auch ein
Logik.Visible:=False;
bringt nix an Geschwindigkeit. Was nicht sichtbar ist wird ja auch nicht neu gezeichent, dachte ich mir.
|
|
platzwart
      
Beiträge: 1054
Erhaltene Danke: 78
Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
|
Verfasst: Di 24.08.10 17:45
Kannst ein Logik.Doublebuffered:= True machen, bringt aber nicht mehr als max. 10%...
Ansonsten gibts andere, wesentlich schnellere Komponenten. Z.B. VirtualTreeView, allerdings hast du dann auch ein wenig mehr Schreibaufwand...
_________________ Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
|
|
Holg_i 
      
Beiträge: 79
|
Verfasst: Di 24.08.10 17:59
Wenn ich mein verschieben ausführe flackert nix.. das Grid wird ja auch nicht gezeichent.. nur am ende...
es muss doch möglich sein das schneller zu verschieben....
Logik.Doublebuffered:= True bringt bei mir nix ersichtliches bei 300000 Einträgen noch immer mehr als 2 Sekunden.
Zum VirtuallTreeView:
Wie getippt ich benutze Delphi4
Bei VirtuallTreeView bekomme ich folgende Anmerkung:
Anmerkung: Die Komponente lässt sich ab Delphi 6 nutzen.
|
|
Holg_i 
      
Beiträge: 79
|
Verfasst: Mi 25.08.10 11:25
Also
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TForm1.Button2Click(Sender: TObject);
var I: Integer;
begin QueryPerformanceCounter(Start); For I:=1 to Logik.RowCount-2 do Logik.Rows[I]:=Logik.Rows[I+1]; QueryPerformanceCounter(Stopp); Edit1.Text:=FloatToStr((Stopp-Start)/Frequenz); NeuerDatensatz; end; |
Geht ja schon. Die erste Zelle wird gelöscht und alle anderen rücken nach.
Wie hier aber aufgezeigt braucht das ganze bei 300000 mehr als 2 Sekunden.
Nun habe ich durch ein Beitrag hier im Forum folgendes gemacht.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56:
| public end;
type TStringGridHack = class(TStringGrid) protected procedure DeleteRow(ARow: Longint); reintroduce; end;
var Form1: TForm1;
implementation
{$R *.DFM}
procedure LockControl(c: TWinControl; lock: boolean); begin if (c = nil) or (c.Handle = 0) then exit; if lock then SendMessage(c.Handle, WM_SETREDRAW, 0, 0) else begin SendMessage(c.Handle, WM_SETREDRAW, 1, 0); RedrawWindow(c.Handle, nil, 0, RDW_ERASE or RDW_FRAME or RDW_INVALIDATE or RDW_ALLCHILDREN); end; end;
procedure TStringGridHack.DeleteRow(ARow: Longint); var GemRow: Integer; begin GemRow := Row; if RowCount > FixedRows + 1 then inherited DeleteRow(ARow) else Rows[ARow].Clear; if GemRow < RowCount then Row := GemRow; end;
procedure TForm1.Button2Click(Sender: TObject);
var I: Integer;
begin LockControl(Logik, True); QueryPerformanceCounter(Start); TStringGridHack(Logik).DeleteRow(0); QueryPerformanceCounter(Stopp); LockControl(Logik, False); Edit1.Text:=FloatToStr((Stopp-Start)/Frequenz); NeuerDatensatz; end; |
Und siehe da nun habe ich die Zeit von mehr als 2 Sekunden auf 0,0559 Sekunden verkürzt.
Eventuell hat ja noch einer das selbe Problem und liest hier nach.
|
|
|