AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TVirtualStringTree - PerformanceProbleme

Offene Frage von "karl der große"
Ein Thema von karl der große · begonnen am 3. Apr 2005 · letzter Beitrag vom 4. Mai 2005
Antwort Antwort
karl der große

Registriert seit: 4. Mär 2005
40 Beiträge
 
#1

TVirtualStringTree - PerformanceProbleme

  Alt 3. Apr 2005, 11:45
Hallo, hab da ein kleines Problem!

Ich hab einen TVirutalStringTree. Versuche damit aus einer Tabelle mit 12 Feldern eine Anzeige mit 4 Ebenen zu basteln.

Die Tabelle hat derzeit ca. 2.400 Einträge, der Aufbau der Anzeige dauert ca. 15 sec, was aber eigentlich nicht sein kann.

Beim Kundeneinsatz wird die Tabelle ca. 200.000 Einträge haben, wenn ich das hochrechne, dann kann ich mit der Software gleich eine
Kaffeemaschine mitliefern.

Arbeite mit Delphi 6, Datenbank ACCESS 2000, Zugriff mit TADOConnection, TADOBetterDataset, TDatasource.

Hole mir die gesamten Daten mit einem SQL-String aus zwei Tabellen und verwende dafür 5 Datasets

Dataset 1 (in diesem Dataset sucht man sich einen Kunden aus, für den dann der TVirtualStringTree aufgebaut wird):

select * from tabelle1 -> ergibt die Kundennummer Dataset 2 (ergibt die Knotenpunkte der ersten Ebene)

Select Kundennummer, Sortierbegriff1 from tabelle2 where kundennummer = :kundennummer group by kundennummer, sortierbegriff1 Dataset 3 (ergibt die Knotenpunkte in der zweiten Ebene)

Select Kundennummer, Sortierbegriff1, Sortierbegriff2, sum(Betrag) as Gesamt from tabelle2 where kundennnummer =: kundennummer and sortierbegriff1 = :Sortierbegriff1 group by kundennummer, sortierbegriff1, sortierbegriff2 Dataset 4 (ergibt die Kontenpunkte in der dritten Ebene)

Select Kundennummer, Sortierbegriff1, Sortierbegriff2, Sortierbegriff3, sum(Betrag) as Gesamt from tabelle2 where kundennnummer =: kundennummer and sortierbegriff1 = :Sortierbegriff1 and sortierbegriff2 = :sortierbegriff2 group by kundennummer, sortierbegriff1, sortierbegriff2, sortierbegriff3 Dataset 5 (zeigt die Daten in der vierten Ebene an)

Select Kundennummer, Sortierbegriff1, Sortierbegriff2, Sortierbegriff3, Daten from tabelle2 where kundennnummer =: kundennummer and sortierbegriff1 = :Sortierbegriff1 and sortierbegriff2 = :sortierbegriff2 and sortierbegriff3 = :sortierbegriff3 Verwende folgenden Code:

Delphi-Quellcode:
  PTreeData = ^TTreeData;
  TTreeData = record
     FTree : TObject;
  end;

  TTreeTreeClass = class
     private
        FFeld1: string;
        FFeld2: string;
        FFeld3: double;
     published
        property Feld1: string read FFeld1 write FFeld1;
        property Feld2: string read FFeld2 write FFeld2;
        property Feld3: double read FFeld3 write FFeld3;
  end;

function Tanzeige.AddVSTTree(avsat: TCustomVirtualStringTree; asNode: PVirtualNode;
   aTree: TObject): PVirtualNode;
var
   Data: PTreeData;
begin
   Result := avsat.Addchild(asNode);
   data := avsat.GetNodeData(Result);
   avsat.ValidateNode(Result, False);
   data^.FTree := aTree;
end;

procedure Tanzeige.vstHeaderClick(Sender: TVTHeader; Column: TColumnIndex;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
   if Button = mbLeft then
   begin
      with Sender, TreeView do
      begin
         if SortColumn > NoColumn then
            Columns[SortColumn].Options := Columns[SortColumn].Options + [coParentColor];
            if (SortColumn = NoColumn) or (SortColumn <> Column) then
            begin
               SortColumn := Column;
               SortDirection := sdAscending;
            end
            else
               if SortDirection = sdAscending then
                  SortDirection := sdDescending
               else
                  SortDirection := sdAscending;
            SortTree(SortColumn, SortDirection, False);
         end;
   end;
end;


procedure Tanzeige.vstTreeCompareNodes(Sender: TBaseVirtualTree; Node1,
  Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer);
var
   Data1, Data2: PTreeData;
begin
   Data1 := Sender.GetNodeData(Node1);
   Data2 := Sender.GetNodeData(Node2);
   case Column of
      0:
         Result := CompareText(TtreeDataClass(Data1.FTree).FFeld1,
            TtreeMassenClass(Data2.FTree).FFeld2);
   end;
end;

procedure Tanzeige.vstTreeFreeNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode);
var
   Data: PTreeData;
begin
   Data := vstTree.GetNodeData(Node);
   if not Assigned(Data) then
      exit;
   Data.FTree.Free;
end;

procedure Tanzeige.vstTreeGetText(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
  var CellText: WideString);
var
   Data: PTreeData;
begin
   Data := Sender.GetNodeData(Node);
   if data.FTree <> nil then
   begin
      case Column of
         0:
            begin
                  celltext := TTreeDataClass(Data.FData).FFeld1
            end;
         1:
            begin
                  celltext := floattoStrF(TTreeDataClass(Data.FData).FFeld3,ffnumber,15,2)
            end;
         2:
            begin
                  celltext := TTreeDataClass(Data.FData).FFeld2
            end;
      end;
   end;
end;


procedure Tanzeige.FormCreate(Sender: TObject);
var
   TreeData: TTreeDataClass;
   DataWurzel: PVirtualNode;
   DataWurzel1: PVirtualNode;
   DataWurzel2: PVirtualNode;
begin
      vstTree.visible := false;
      db_Tabelle2.first;
      vstTree.BeginUpdate;
      vstTree.NodeDataSize := SizeOf(TTreeMassenClass);
      vstTree.DeleteChildren(vstTree.RootNode, true);
      while not db_Dataset2.Eof do
         begin
         TreeData := TTreeDataClass.Create;
         TreeData.Feld1 := db_Dataset2.fieldByName('Sortierbegriff1').AsString;
         DataWurzel := AddVSTTree(vstTree, Nil, TreeData);
         while not db_Dataset3.eof do
         begin
            TreeData := TTreeDataclass.Create;
            TreeData.Feld1 := db_Dataset3.fieldByName('Sortierbegriff2').AsString;
            TreeData.Feld3 := db_Dataset3.fieldByName('Gesamt').AsFloat;
            TreeData.Feld2 := db_Dataset5.fieldbyName('Feld5').AsString;
            DataWurzel1 := addvstTree(vstTree, DataWurzel, TreeData);
            while not db_Dataset4.eof do
            begin
               TreeData := TTreeDataClass.Create;
               TreeData.Feld1 := db_Dataset4.fieldbyName('Sortierbegriff3').AsString;
               TreeData.Feld3 := db_Dataset4.fieldbyName('Gesamt').AsFloat;
               TreeData.Feld2 := db_Dataset5.fieldbyName('Feld5').AsString;
               DataWurzel2 := addvstTree(vstTree, DataWurzel1, TreeData);
               while not db_Dataset5.eof do
               begin
                  TreeData := TTreeDataClass.Create;
                  TreeData.Feld1 := db_Dataset5.fieldbyName('Feld3').AsString;
                  TreeData.Feld3 := db_Dataset5.fieldbyName('Feld4').AsFloat;
                  TreeData.Feld2 := db_Dataset5.fieldbyName('Feld5').AsString;
                  addvstTree(vstTree, DataWurzel2, TreeData);
                  db_Dataset5.next;
               end;
               db_Dataset4.next;
            end;
            db_Dataset3.next;
         end;
         db_Dataset2.next;
      end;
      vstTree.EndUpdate;
      vstTree.visible := true;
   end;
end;


procedure Tanzeige.vstTreeBeforeItemErase(Sender: TBaseVirtualTree;
  TargetCanvas: TCanvas; Node: PVirtualNode; ItemRect: TRect;
  var ItemColor: TColor; var EraseAction: TItemEraseAction);
begin
   case Sender.GetNodeLevel(Node) of
   0:
      begin
         ItemColor := clMoneyGreen;
         EraseAction := eaColor;
      end;
   1:
      begin
         ItemColor := clSkyBlue;
         EraseAction := eaColor;
      end;
    2:
      begin
         ItemColor := clFuchsia;
         EraseAction := eaColor;
      end;
    end;
end;
Wie schon oben gesagt, dauert der Aufbau des TVirtualStringTrees ca. 15 sec, was lt. allen Beschreibungen in den Foren und auch auf der Homepage selbst sowie in der Dokumentation eingentlich nicht sein dürfte.

Hab auch schon versucht, eine Progressbar und eine Anzeige einzubauen, der einzige Ort, an dem mir das aber sinnvoll schien, ist im Create selbst.

Wenn ich aber an dieser Stelle den Progressbar einbaue, dann zischt er von 0 auf 100 und dann ist warten angesagt. Der Zeitverlust kann also eigentlich nicht im Create auftreten.

Hat jemand eine Idee. Ich hab im Moment keine mehr.

Danke für Eure Hilfe.

Gruss Karl
  Mit Zitat antworten Zitat
karl der große

Registriert seit: 4. Mär 2005
40 Beiträge
 
#2

Re: TVirtualStringTree - PerformanceProbleme

  Alt 4. Apr 2005, 19:04
Hallo!

Nochmal eine Info dazu:

Ich habe versucht am Anfang des Create einen Text visible zu stellen, den ich am Ende des Create wieder un-visible mache,
auch das funktioniert nicht. Es ist für ca. 15 Sekunde die gesamte EXE blockiert.

Ich hoffe, Ihr habt eine Idee, ich sollte eine Vorabversion nächste Woche vorführen.

Aber ich vertraue wie immer der Delphi-Gemeinde.

Danke für Eure Hilfe

Karl
  Mit Zitat antworten Zitat
_Sebastian_

Registriert seit: 22. Jul 2004
Ort: Lübeck
72 Beiträge
 
Delphi 2010 Professional
 
#3

Re: TVirtualStringTree - PerformanceProbleme

  Alt 4. Apr 2005, 19:47
Ich bin mir ziemlich sicher das es nicht am Tree liegen wird, sondern an deinen deinen Datenbankabfragen. Hast du da mal die zeit gemessen wie lange die dauern?
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.415 Beiträge
 
Delphi XE5 Professional
 
#4

Re: TVirtualStringTree - PerformanceProbleme

  Alt 4. Apr 2005, 20:16
vstTree.DeleteChildren -> vstree.clear;


die datenbank abfragen sind das langsamste.

du könntest noch geschwindigkeit rausholen indem du den rootnodecount auf die anzahl der benötigen knoten setzt und dann im oninitnode die daten lädst.

dann kannst du dir den tree record noch sparen.

nodedatasize:=sizeof(TTreeTreeClass);
dann mit vstTree.addchild(rootnode, objinstance) hinzufügen und abrufen mit
objinstance:=TTreeTreeClass(vstTree.getnodedata[node]^);

den aufruf von addvstTree verstehe ich nicht?!
  Mit Zitat antworten Zitat
karl der große

Registriert seit: 4. Mär 2005
40 Beiträge
 
#5

Re: TVirtualStringTree - PerformanceProbleme

  Alt 4. Apr 2005, 20:37
Hallo!

Danke für Deine Antwort!

Hab ich auch schon vermutet, ich hab die Datenbankabfragen auch oben mit reingestellt.

Hast Du eine Idee, wie ich diese anders machen bzw. otpimieren kann.

Gruss Karl
  Mit Zitat antworten Zitat
karl der große

Registriert seit: 4. Mär 2005
40 Beiträge
 
#6

Re: TVirtualStringTree - PerformanceProbleme

  Alt 4. Apr 2005, 20:43
Hallo generic!

Was meinst Du mit vsttree.deleteChildren->vstree.clear?

Hast Du eine Idee, wie ich die Datenbankabragen optimieren kann, sind hilfstabellen sinnvoll?

Sorry die Frage - bin eigentlich noch Delphi-Neuling, hat mich eh gewundert, dass das Ding läuft, langsam beginne ich es auch zu verstehen.

kannst mir sagen wie Du das mit dem rootnodecount gemeint hast, und mit oninitnode die daten laden - ist mir noch spanisch

den aufruf von addvstTree habe ich von der Doku - versteh ich auch nicht!

wär echt super, wenn Du es mir etwas erklären könntest.

Vielen Dank.

LG Karl
  Mit Zitat antworten Zitat
ratloser

Registriert seit: 4. Mai 2005
Ort: Linz
36 Beiträge
 
#7

Re: TVirtualStringTree - PerformanceProbleme

  Alt 4. Mai 2005, 21:50
Leider läuft es immer noch nicht schneller

hat jemand eine idee
Vielen Dank!

Konrad
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:42 Uhr.
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