Datensätze einer DB-Tabelle in TreeView



  • Hallo,

    ich öffne eine Datenbanktabelle aus einem Alias in ein DBGrid. Gleichzeitig hole ich mir den Tabellen und die Feldnamen in ein TreeView, ungefähr so sieht das TreeView dann aus

    • TabellenName
    • -Feld1
    • -Feld2

    Nun würde ich allerdings gern noch vollziehen, dass wenn in der Tabelle schon Datensätze drin sind, diese entsprechend ihrer Felder mit einsortiert werden in das TreeView.ungefähr so:

    • TabellenName
    • - Feld1
    • - - 1.Datensatz Feld 1
    • - - 2.Datensatz Feld 1
    • -Feld2
    • - - 1.Datensatz Feld 2

    Meine Frage daher: Gibt es Methoden um den Inhalt eines jeden Datensatzes auszulesen und ihn entsprechend der Spalte in das das TreeView einzufügen?! Habe was gelesen in der FAQ über GetBookmark(). Ist das verwendbar? Oder gehts auch anders?

    Vielen Dank schon mal für eure Antworten

    mfg
    Steffen

    [ Dieser Beitrag wurde am 10.01.2003 um 09:31 Uhr von skho editiert. ]

    [ Dieser Beitrag wurde am 10.01.2003 um 09:32 Uhr von skho editiert. ]

    [ Dieser Beitrag wurde am 13.01.2003 um 08:22 Uhr von skho editiert. ]



  • also ih habe noch mal ein bissle experimentiert, lese nun die Werte aus, aber sie werden noch nicht richtig platziert.

    Also ich öffne eine Tabelle "test-db" die wie folgt aussieht:

    Name -----------Kategorie

    erdinger -------hell
    paulaner -------dunkel
    asbacher -------hell
    köstritzer -----dunkel

    Nun hab ich durch mein Programm erreicht dass mein TreeView so aussieht

    - test_db
    - - Name
    - - - erdinger
    - - - paulaner
    - - - asbacher
    - - - köstritzer
    - - - hell
    - - - dunkel
    - - - hell
    - - - dunkel
    - - Kategorie

    wollte es aber so haben dass hell und dunkel unter Kategorie steht. Habe bestimmt einen Fehler in meiner schleife, vielleicht seid ihr so nett und schaut mal den Code nach Fehler ab

    // ... Auszug .cpp
            int Nodepunkt = 0;
            Feldanzahl = DBGrid_db->FieldCount;
            TreeV_dbfelder->Items->Clear();
            TreeV_dbfelder->Items->Add(NULL,Combo_Dbnamen->Text);
    
            for (int lauf=0;lauf<Feldanzahl;lauf++)
                {
                Feldname = DBGrid_db->Columns->Items[lauf]->FieldName;
                TreeV_aktualisieren(Nodepunkt,Feldname);
                }
    
    //Funktion TreeV_aktualisieren aus der .h
    
    void __fastcall TForm1::TreeV_aktualisieren(int NodePunkt,String feldn)
        {
         TTreeNode *Node1;
         TTreeNode *Node2;
         int DS;
         AnsiString feldinhalt;
         Node1 = TreeV_dbfelder->Items->Item[NodePunkt];
         Tab_Db->First();
         TreeV_dbfelder->Items->AddChild(Node1,feldn);
         DS = Tab_Db->RecordCount;
         while (!Tab_Db->Eof)
            {
            for (int i=0;i<=DS-1;i++)
                {
                feldinhalt = Tab_Db->FieldByName(feldn)->AsString;
                //feldinhalt.ChangeType(varString);
                Node2 = TreeV_dbfelder->Items->Item[NodePunkt+1];
                TreeV_dbfelder->Items->AddChild(Node2,feldinhalt);
                Tab_Db->Next();
                }
             }
          }
    

    beim debuggen hab ich festgestellt, dass er "Kategorie" ordnungsgemäß übergibt, aber warum schreibt er die Daten weiterhin unter "Name"?

    danke euch für die Bemühungen
    mfg

    Steffen

    [ Dieser Beitrag wurde am 10.01.2003 um 12:20 Uhr von skho editiert. ]



  • *hochschieb*



  • hat denn keiner ne Idee woran es liegen könnte 😕 😕 😕 😞

    wäre wirklich nett von Euch wenn ihr was entdeckt es mir mitzuteilen. Thx

    mfg
    steffen



  • Moinsen!

    Ich würde erst die 2 Nodes erstellen und in 2 TTreeNode-Zeigern speichern. Danach immer gleichzeitig an Node1 und Node2 die Datensätze hängen:

    int __fastcall TForm1::TreeV_aktualisieren(int NodePunkt_Name, int NodePunktKategorie, AnsiString feldn1, AnsiString feldn2)
    {
         TTreeNode *Node1;
         TTreeNode *Node2;
    
         try
         {
            Node1 = TreeV_dbfelder->Items->Item[NodePunktName];
            Node2 = TreeV_dbfelder->Items->Item[NodePunktKategorie];
    
            Tab_Db->First();
            for (int i=0;i<Tab_Db->RecordCount;i++)
            {
                TreeV_dbfelder->Items->AddChild(Node1,Tab_Db->FieldByName(feldn1)->AsString);
                TreeV_dbfelder->Items->AddChild(Node2,Tab_Db->FieldByName(feldn2)->AsString);
                Tab_Db->Next();
            }
    
            return 0;
         }
         catch ( ... )
         {
               return 1; // Exception/Fehler
         }
    }
    

    [ Dieser Beitrag wurde am 13.01.2003 um 08:44 Uhr von F98 editiert. ]

    [ Dieser Beitrag wurde am 13.01.2003 um 08:44 Uhr von F98 editiert. ]



  • danke erstmal für die Antwort,

    das Problem ist, dass ich mich wahrscheinlich dumm ausgedrückt habe. Name und Kategorie waren nur beispielhaft, wie vielleicht aus meinem code ersichtlich ist, weiß ich vorher nicht, welche Felder die Tabelle hat, dass heißt ich muss den Inhalt des Trees erst zur Laufzeit erstellen (feldnamen auslesen,knoten erzeugen, Datensätze auslesen und entsprechend des feldnamens zuordnen), bei deiner Variante gehst du von festen Feldnamen aus..

    Nach einigen test habe ich festgestellt, dass ich nicht

    Node = TreeV->Items->Item[1]

    übergeben kann ohne dass vorher

    Item[0] angelegt worden ist, und das ist doof. Wie also kann ich es sozusagen dynamisch erreichen mein TreeView zu füllen??? Kann Ich irgendwie abfragen, ob ein Knoten schon existiert?

    mfg
    Steffen



  • juhuuu ich habs raus,

    für alle die mal ähnliche sorgen haben werden, hier meine Lösung:

    //.cpp
    //...
    
    int Feldanzahl;
    TTreeNode *Nodep;
    Feldanzahl = DBGrid_db->FieldCount;
    TreeV_dbfelder->Items->Clear();
    TreeV_dbfelder->Items->Add(NULL,Combo_Dbnamen->Text);
    Nodep = TreeV_dbfelder->Items->Item[0];
    TreeV_aktualisieren(Nodep,Feldanzahl);
    
    //.h
    
    void __fastcall TForm1::TreeV_aktualisieren(TTreeNode *NodePkt,int Feldanz)
        {
        AnsiString feldinhalt;
        AnsiString feldname;
        TTreeNode *NodePktChild;
        int DS;
        //erste Spalte extra behandeln    
        feldname = DBGrid_db->Columns->Items[0]->FieldName; //name der ersten Spalte
        TreeV_dbfelder->Items->AddChild(NodePkt,feldname);//Knoten anlegen
        NodePktChild = TreeV_dbfelder->Items->Item[1]; //KindKnoten für 1.Spalte
        for(int l = 0; l<=Feldanz-1;l++) //Anzahl der weiteren felder bestimmen
            {
             if (l != 0) //wenn nicht erste Spalte
                {
                feldname = DBGrid_db->Columns->Items[l]->FieldName;//Spaltenname
                Tab_Db->First();
                TreeV_dbfelder->Items->AddChild(NodePkt,feldname);//Knoten anlegen
                NodePktChild = NodePkt->Item[l];//KindKnoten setzen
                DS = Tab_Db->RecordCount; //anzahl der Datensätze
                while (!Tab_Db->Eof) //solange nicht endofFile
                    {
    
                    for (int i=0;i<=DS-1;i++)
                        {
                        feldinhalt = Tab_Db->FieldByName(feldname)->AsString;
                        //KindKnoten setzen (Inhalt:Datensatz i)                    
                        TreeV_dbfelder->Items->AddChild(NodePktChild,feldinhalt);
                        //Nächster Datensatz
                        Tab_Db->Next();
                        if (Tab_Db->Eof)
                            break;
                        }
                    }
                }
             else //für erste Spalte Datensätze bestimmen
                {
                DS = Tab_Db->RecordCount;
                while (!Tab_Db->Eof)
                    {
    
                    for (int i=0;i<=DS-1;i++)
                        {
                        feldinhalt = Tab_Db->FieldByName(feldname)->AsString;
                        TreeV_dbfelder->Items->AddChild(NodePktChild,feldinhalt);
                        Tab_Db->Next();
                        if (Tab_Db->Eof)
                            break;
                        }
                    }
    
                }
            }
        }
    

    danke trotzdem F98 für deine Mühen

    mfg
    Steffen (-->in die FAQ wär gut)



  • Ich würde das allgemein so machen (Vorsicht ungetestet, hab ich nur mal schnell zusammengepfriemelt):

    int CodeAlarm()
    {
         TTreeNode *TempNode;
         TTreeNode *TempNode2;
         TList *NodeListe = new TList
         int iRc, iSc;
    
         // alle vorhandene Knoten entfernen
         TreeView1->Items->Clear();
    
         // Hauptknoten hinzufügen
         TreeView1->Items->Add(NULL, "RootNode");
    
         // Zeiger auf RootNode speichern
         TTreeNode RootNode = TreeView1->Items->Item[0];
         // alternativ: TTReeNode RootNode = TreeView1->Items->GetFirstNode();
    
         // soviele Unterknoten wie nötig erstellen
        for (iSc=0;iSc<Tab_Db->FieldCount;iSc++)
        {
            TempNode = new TTreeNode;
            TempNode = TreeView1->Items->AddChild(RootNode, Tab_Db->Fields->Fields[iSc]->FieldName);
            TempNode->ImageIndex = BildNummerauseinerTImageList;
            TempNode->MakeVisible();
            NodeListe->Add(TempNode);
        }
    
        Tab_Db->First();
    
        for (iRc=0;iRc<Tab_Db->RecordCount;iRc++)
        {         
            for (iSc=0;iSc<NodeListe->Count;iSc++)
            {
                TempNode2 = (TTreeNode*) NodeListe->Items[iSc];
                TempNode2 = TreeView1->Items->AddChild(TempNode2, Tab_Db->Fields->Field[iSc]->AsString);
                TempNode2->ImageIndex = iSc;
                TempNode2->MakeVisible();
            }
    
            Tab_Db->Next();
        }
    
       // Aufräumen: Listeneinträge und Liste freigeben
       for (int i = 0; i < NodeListe->Count; i++)
       {
           TempNode2 = (TTreeNode*) NodeListe->Items[i];
           delete TempNode2;
       }
    
       delete NodeListe
    }
    

    [ Dieser Beitrag wurde am 13.01.2003 um 11:53 Uhr von F98 editiert. ]


Anmelden zum Antworten