StringGrid Ram wird voll - Hilfe



  • Hat doch Braunstein schon geschrieben.
    Am einfachsten ein TDBGrid verwenden.
    Wenn du aus welchen Gründen auch immer ein TStringGrid verwenden willst, dann ist das nunmal so dass du alles selbst reinkopieren musst.
    Und wenn du dann viele Daten hast, dann verbraucht das auch entsprechend Ressourcen.



  • bin zufällig auf der Suche nach einer Lösung auf folgendes getroffen und habe folgende Frage nun, wie wird dieses Problem hier gelöst?

    Screen:
    http://www.abload.de/img/unbenannt4reb.jpg

    ............................................................

    Ist das kein StringGrid?



  • Hallo

    Das kann alles möglich sein. Vor allem wenn diese Anwendung gar nicht mit dem Builder programmiert wurde.
    Ich vermute, daß das ein TListView ist. Damit kann man auch eher ein dynamisches Nachladen von Daten implementieren, um wenigstens nur die wirklich gebrauchten Daten laden zu müßen.

    bis bald
    akari



  • besteht bei TListView auch die Möglichkeit, die einzelnen Spalten anzusprechen?



  • Hallo

    Ja, über die Eigenschaft TListView::Items. Steht alles in der Builder-Hilfe.

    bis bald
    akari



  • Hab folgenden Code

    TListItem *Item;
    TListColumn *Column;
    
      Column = ListView1->Columns->Add();
      Column->Caption = "ID";
      Column->Width = 100;
      Column = ListView1->Columns->Add();
      Column->Caption = "Nname";
      Column->Width = 100;
      Column = ListView1->Columns->Add();
      Column->Caption = "geb";
    
    for (int i=0;i<80;i++)
    {
    	Item = ListView1->Items->Add();
    	Item->Caption = "Klasse G9"+IntToStr(i);
    
       Item->SubItems->Add(ID);
    	Item->SubItems->Add(Name);
    	Item->SubItems->Add(Nname);
    	Item->SubItems->Add(geb);
    }
    

    funktioniert soweit auch ganz gut,

    nur wie kann ich nun beim dblklick auf die Zeile, zb Zeilen NR und Spalten Nr einzeln ermitteln,zugreifen, sodass zb bei klick auf Nname der Nname im MemoFeld dargestellt wird.



  • keiner eine Idee?

    *
    
          als erstes sollte man sich eine Klasse definieren, die die Speicher-Objekte beschreibt (in einer Header-Datei) 
    
        class TListItemData
        {
    
            public:
    
            // Konstruktor der Klasse
            TListItemData(){};
    
            // Objektvariablen
            int iId;
            AnsiString sName;
    
        };
    
        *
    
          Um ein Objekt einem Listview-Item zuzuordnen muss man folgendermaßen vorgehen: 
    
        // Zeiger für das Listitem definieren
        TListItem *ListItem;
    
        // neues Listitem hinzufügen
        ListItem = ListView->Items->Add();
        ListItem->Caption = "Eintrag";
    
        // neues Datenobjekt erzeugen
        TListItemData *ItemData = new TListItemData();
        ItemData->iId = 1;
        ItemData->sName = "Horst";
    
        // Datenobjekt dem Listitem zuordnen (Zeiger übergeben)
        ListItem->Data = ItemData;
    
        *
    
          Der Zugriff auf ein solches Objekt kann wie folgt realisiert werden: 
    
        void __fastcall TForm1::ListViewClick(TObject *Sender)
        {
    
            if (ListView->Selected)
            {
    
                TListItemData *TempItem;
    
                // Datenzeiger vom akt. Listviewelement holen
                TempItem = (TListItemData*)ListView->Items->Item[i]->Data;
    
                // Wenn ein gültiger Zeiger vorhanden (!= NULL)
                if (TempItem)
                {
    
                    Label1->Text = IntToStr(ItemData->iId);
                    Label2->Text = ItemData->sName;
    
                }
                else // sonst Fehlermeldung
                {
    
                    ShowMessage("Objekt nicht verfügbar!");
    
                }
    
            }
    
        }
    
        *
    
          naturlich darf man das Löschen der so zugewiesenen Speicherobjekte nicht vergessen, dazu dient folgende Funktion: 
    
        void __fastcall TForm1::DeleteAllItemData()
        {
    
            TListItemData *TempItem;
    
            // Alle Items->Data des Listviews löschen
            for (int i=0; i<ListView->Items->Count; i++)
            {
    
                // Zeiger auf das akt. ListItem->Data->Objekt holen
                TempItem = (TListItemData*)ListView->Items->Item[i]->Data;
                if (TempItem)
                {
    
                    // alle Zeiger und Objekte löschen
                    ListView->Items->Item[i]->Data=NULL;
                    delete TempItem;
                    TempItem = NULL;
    
                }
    
            }
    
        }
    

    Hab das im Netz gefunden, aber fnktionieren tut es leider nicht!



  • Die einzelnen Einträge in der ListView sind vom Typ TListItem. Dieses hat die Eigenschaft SubItems, mit der Du auf die weiteren Spaltenwerte des Objektes zugreifen kannst.



  • sry doppelpost



  • ich habe das gleiche Problem beobachtet.
    Bei meiner Applikation lade ich große Dateien in StringGrid und von dort
    mache ich meine Datenauswertungen.
    Anschließend werden alle Zelleninhalte auf "" gesetzt und die Anzahl der
    Zeilen und Spalten auf 1 gesetzt.
    Und nach mehrmaligem Laden der Dateien wird nicht der ganze zuvor belegte
    Speicherbereich freigegeben.

    Ich denke, dass die TStringGrid irgendwo intern nicht ganz sauber programmiert
    wurde, und dass dadurch Speicherbereiche einfach belegt bleiben.



  • Nö, ich denke es ist eher die Speicherverwaltung, die den Speicher fragmentiert und dadurch relative große Blöcke verwendet werden, die aber dann teilweise ungenutzt sind. Dem Programm stehen sie zur Verfügung, nicht aber Windows.


Anmelden zum Antworten