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 -----dunkelNun hab ich durch mein Programm erreicht dass mein TreeView so aussieht
- test_db
- - Name
- - - erdinger
- - - paulaner
- - - asbacher
- - - köstritzer
- - - hell
- - - dunkel
- - - hell
- - - dunkel
- - Kategoriewollte 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
mfgSteffen
[ 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. ]