Autor Beitrag
Ayumi
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Mi 03.08.05 16:17 
Hallo,
ich habe eine Funktion, die Daten aus der DB ausliest. Das Auslesen aus der DB und Anzeigen im TreeView funktioniert soweit.
Im TreeView sehen meine Daten folgendermaßen aus:
2000
--Xyz
----Test
2000
--Abc
----Test1
2000
--Abc
----Test2

Ich möchte aber, dass es folgendermaßen aussieht
2000
--Xyz
----Test
--Abc
----Test1
----Test2

Kann mir da jemand weiter helfen

Vielen Dank im Voraus
Ayumi

ausblenden volle Höhe Delphi-Quelltext
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:
function TDataModule1.fuelleTreeView( var TreeView1: TTreeView):boolean;
var
i                   : integer;
VkampagneRec        : PKampagneRec;
vJahrTreeNode       : TTreeNode;
vKundeTreeNode      : TTreeNode;
vProduktTreeNode    : TTreeNode;
vKampagneTreeNode   : TTreeNode;
vMutterTreeNode     : TTreeNode;

begin
try
   vMutterTreeNode := nil;
  begin
  with ADODataSet1 do
  begin
    close;
    CommandType := cmdText;
    CommandText :=    'select ' +
                      'decode  (to_char(max(a.sttmact), ''yyyy''), '''', ''unbekannt'', to_char(max(a.sttmact), ''yyyy'')) Jahr, ' +
                      'c.advert, c.product, c.ccamp, c.icamp ' +
                      'from campaign c, actions a ' +
                      'where c.ccamp = a.ccamp(+) ' +
                      'group by c.ccamp, c.icamp, c.product, c.advert ' +
                      'order by jahr, c.advert, c.product, c.icamp';
    Open;
    First;
  end;

  while not ADODataSet1.Eof do
   begin
    new(vKampagneRec);
    //datum, kunde, produkt, kampagne aus der Datenbankselektion lesen
    vKampagneRec^.rec_Jahr        := ADODataSet1.FieldByName('Jahr').AsString;
    vKampagneRec^.rec_Kunde       := ADODataSet1.FieldByName('advert').AsString;
    vKampagneRec^.rec_produkt     := ADODataSet1.FieldByName('product').AsString;
    vKampagneRec^.rec_kampagne    := ADODataSet1.FieldByName('icamp').AsString;


   vJahrTreeNode:=TreeView1.Items.AddObject(vMutterTreeNode,ADODataSet1.FieldByName('Jahr').AsString, vkampagneRec);
   vKundeTreeNode := TreeView1.Items.AddChildObject(vJahrTreeNode, ADODataSet1.FieldByName('advert').AsString, vKampagneRec);
   vProduktTreeNode := TreeView1.Items.AddChildObject(vKundeTreeNode, ADODataSet1.FieldByName('product').AsString, vKampagneRec);
   vKampagneTreeNode := TreeView1.Items.AddChildObject(vProduktTreeNode, ADODataSet1.FieldByName('icamp').AsString, vKampagneRec);
    ADODataSet1.next;
   end;
   result := true;
 end;
except
  begin
  result := false;
 end;
end;
end;
LigH
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 239

Win98SE, Win2000SP4
D7
BeitragVerfasst: Mi 03.08.05 16:34 
Anscheinend verwendest du einen (impliziten) JOIN in deiner SQL-Abfrage. Da sehe ich zwei Möglichkeiten:

a) Keinen JOIN (keine kombinierte Abfrage), sondern einzelne Abfragen in einer Schleife. Kostet viel Bandbreite durch dauernden DB-Zugriff!

b) Bei jedem gelesenen Datensatz vor "Add[Child]Object" immer prüfen, ob unter der Baum-Wurzel bereits ein Child-TreeNode existiert, das den selben Titel hat, so dass dann keiner neu angelegt wird.
Ayumi Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Do 04.08.05 12:18 
hallo LigH
Vielen dank für deine Hilfe. Deine Antwort b wäre das, was mir auch vorgeschwebt ist. Aber ich weiß nicht wirklich wie ich das umsetzen kann.
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Do 04.08.05 16:29 
Hallo,

hier ein Beispiel, bezogen auf ein StringGrid mit 4 Spalten:
ausblenden volle Höhe Delphi-Quelltext
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:
var z : Integer;
    aNode : TtreeNode;//aktueller Knoten
    s0,s1,s2 : string;//Werte aus letztem Datensatz
begin
  s0 := '';
  for z := 0 to StringGrid1.RowCount-1 do
    begin
    //ungleich dem vorigen Wert in Spalte 1 oder es ist die erste Zeile
    if StringGrid1.Cells[0,z] <> s0 then
      begin
      //Wurzelknoten anlegen
      aNode := TreeView1.Items.Add(nil,StringGrid1.Cells[0,z]);
      s0 := StringGrid1.Cells[0,z];//zwischenspeichern
      //damit nachfolgende if-Abfrage neuen Knoten anlegt
      //auch dann wenn Werte aus Spalte 2 identisch sind
      //und die Werte aus Spalte 1 nicht gleich sind
      s1 := '';
      //aNode hat jetzt Level 0
      end;
    if StringGrid1.Cells[1,z] <> s1 then
      begin
      //zu Level 0 gehen
      if s1 <> '' then
        begin
        aNode := aNode.Parent;
        aNode := aNode.Parent;
        end;
      aNode := TreeView1.Items.AddChild(aNode,StringGrid1.Cells[1,z]);
      s1 := StringGrid1.Cells[1,z];
      s2 := '';
      end;
    if StringGrid1.Cells[2,z] <> s2 then
      begin
      //zu Level 1 gehen
      if s2 <> '' then
        aNode := aNode.Parent;
      aNode :=TreeView1.Items.AddChild(aNode,StringGrid1.Cells[2,z]);
      s2 := StringGrid1.Cells[2,z];
      end;
    TreeView1.Items.AddChild(aNode,StringGrid1.Cells[3,z]);
    end;//Ende for z


Ich denke, das Du das an dein Vorhaben anpassen kannst.

Ps.: Könnte man sicher noch besser, einfacher und flexibler(x-Spalten) coden :gruebel:

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )