TStringList will nicht so wie ich



  • Morgens,

    Leute helft mir mal. Meine StringListen wollen nich so wie ich es möchte.

    Folgendes:
    Ich habe eine Maske die als Vorlage für Positionsnummern dienen soll. Die Maske kann(!) so aussehen: AAA-000-aaa.
    Aus der Maske ist ersichtlich, dass die Positionen auf 3 Ebenen verteilt sein können.
    Ebene 0 = AAA
    Ebene 1 = 000
    Ebene 2 = aaa
    Für alle Ebenen sollen es eine fortlaufende Nummerierung geben, d.h. die erste Position wäre AAA-000-aaa, die zweite Position AAB-000-aaa. Verfügt eine Position über Unterpositionen, so würde die entsprechende Ebene hochgezählt: AAB-001-aaa, usw.

    Was ich haben möchte, ist an Hand der Baumansicht erkennbar:

    AAA-000-aaa
    AAB-000-aaa
    +--AAB-001-aaa
    +--+--AAB-001-aab
    +--AAB-002-aaa
    AAC-000-aaa
    +--AAC-001-aaa
    AAD-000-aaa

    Jetzt mein Stringlisten-Problem:
    Ich erzeuge mir eine Stringliste
    TStringList* MaskItem = new TStringList();
    Über eine Splitfunktion wird die Maske aufgeteilt und an MaskItem übergeben, so dass folgendes in MaskItem steht:
    Feld 0 = AAA
    Feld 1 = -000
    Feld 2 = -aaa

    Ich erzeuge eine zweite Stringliste
    TStringList* PosItems = new TStringList();
    Über eine Schleife lasse ich alle Felder in PosItems mit den selben Werten aus MaskItem füllen, so dass folgendes in PosItems steht:
    Feld 0 = AAA
    Feld 1 = -000
    Feld 2 = -aaa

    Ich habe eine Funktion GetNextPositionItem(...), der ich einen Wert (AAA) übergebe, diesen um 1 (AAB) erhöht und wieder zurück gibt. Geht einwandfrei.

    Dann habe ich eine Prozedur die rekursiv aufgerufen wird, und so gleich den Knackpunkt darstellt.

    Bei jedem Durchgang wird die Ebene festgestellt und der entsprechende Feldwert aus der PosItems ausgelesen. Dieser Wert über GetNextPositionItem um 1 erhöht und in das selbe Feld ins PosItems zurück geschrieben.
    Danach werden alle Felder aus PosItems ausgelesen, daraus die Positionsnummer erstellt und der entsprechenden Position übergeben.

    Laut Theorie sollte die oben angegebene Baumstruktur entstehen.

    Kurioserweise steht der um 1 erhöhte Wert sowohl in PosItems als auch in MaskItem, obwohl die beiden StringListen überhaupt nichts miteinander zu tun haben, und MaskItem auch unbedingt seine Feldwerte beibehalten muss.

    Kann mir das einer erklären?



  • Hallo

    Ohne den relevanten Quellcode nein.
    benutzt den Debugger und verfolge den Ablauf des Programms und die Werte wichtiger Variablen.

    bis bald
    akari



  • Einleitung

    // Maske splitten
    	TStringList* MaskItem = new TStringList;
    
    	MaskItem = SplitPositionMask("AAA-000-aaa");
    
    	TStringList* PosItems = new TStringList;
    
    	AnsiString sPosNr = "";
    	sPosNr = MaskItem->Strings[0];
    
    	for(int i = 0; i < MaskItem->Count;i++)
    	{
    		AnsiString item = "";
    		int counter 	= 0;
    		int len 		= 0;
    
    		len = MaskItem->Strings[i].Length();
    
    		char *s = new char[len];
    
    		strcpy(s,MaskItem->Strings[i].c_str());
    
    		counter = PosItems->Count;
    		PosItems->Insert(counter,AnsiString(s));
    	}
    	if(sPosNr != "")
    	{
    		TreeBuildNewPositionIndex2(ds,Tree->TopItem,sPosNr,PosItems,MaskItem);
    	}
    

    Hier die rekursive Prozedur

    void TreeBuildNewPositionIndex2(TDataSet *ds,TTreeNode *Node,AnsiString sPosNr, TStringList *strItems, TStringList *m)
    {
    	TLocateOptions SearchOptions;
    
    	if (Node)
    	{
    		TTreeNodeData *SelNodeData = (TTreeNodeData*)(Node->Data);
    
    		if (!SelNodeData)
    		{
    			Node = Node->GetNext();
    		}
    		if(Node->Level == 0)
    		{
    
    			Node = Node->GetNext();
    		}
    		if (!Node)
    		{	//Es gibt keine Daten
    			return;
    		}
    
    		TTreeNode *siblingNode = Node;
    		while (siblingNode)
    		{
    
    			Node = siblingNode;
    
    			if (Node->HasChildren)
    			{
    				int lvl = Node->Level;
    				AnsiString childPos = "";
    
    				childPos = m->Strings[lvl];
    				strItems->Strings[lvl] = childPos;
    				//childPos = DMCz->GetNextPositionItem(childPos);
    				TreeBuildNewPositionIndex2(ds,Node->getFirstChild(),childPos,strItems,m);
    			}
    
    			SelNodeData = (TTreeNodeData*)(Node->Data);
    			AnsiString DestPosID = SelNodeData->FID;
    
    			if (ds->Locate("ID",DestPosID,SearchOptions))
    			{
    				AnsiString NewPos = sPosNr;
    				NewPos.Trim();
    
    				int lvl = Node->Level;
    				lvl = lvl - 1;
    
    				//strItems->Strings[lvl] = sPosNr;
    
    				AnsiString s = "";
    				for(int i = 0; i < strItems->Count; i++)
    				{
    					AnsiString str = "";
    					str = strItems->Strings[i];
    					s += str;
    				}
    
    				//----------------------------------
    				// Was steht in den Feldern???
    				AnsiString mItem = "";
    				AnsiString sItem = "";
    
    				mItem = m->Strings[lvl]; // sollte -000 sein, ist aber -001
    				sItem = strItems->Strings[lvl]; ist -001
    
    				//----------------------------------
    				strItems->Strings[lvl] = sPosNr;
    
    				s = s;
    
    				ds->Edit();
    					ds->FieldByName("PosNr")->AsString = s;
    				ds->Post();
    			}// IF
    
    			sPosNr = DMCz->GetNextPositionItem(sPosNr);
    			siblingNode =  Node->getNextSibling();
    
    		}// WHILE
    	}// IF
    }
    


  • um die Listen zu kopieren reicht eigentlich die Methode Assign von TStringList, z.B.

    PosItems->Assign(MaskItem);
    

    [Edit] beim Rest blick ich nicht durch. Wann wird der TreeView gefüllt? Was steht im DataSet? usw... versuchs wirklich mal mit dem Debugger oder lass dir die beiden Listen in Memos ausgeben und aktualisier die Anzeige bei jeder neuen Wertzuweisung


Anmelden zum Antworten