DBGrid: Länge Spaltenbreite automatisch nach Spaltenwert ausrichten?
-
Hallo Zusammen,
ich habe auf meinem Formular eine DBGrid Komponente deren Daten ich aus einer MySQL DB auslese.Gibt es jetzt eine Möglichkeit, die länge der einzelnen Spalten automatisch der Länge des längsten Eintrages anzupassen? Aktuell bezieht sich die Länge auf die Feldlänge in der DB. Leider kann ich die nicht ändern.
Kann man das automatisch machen lassen?
Für Hilfe, danke im voraus.
-
in einem StringGrid suche ich den längsten Eintrag einer Spalte und lege dann mit:
tw = Canvas->TextWidth( dta )*1.2; // *1.2 = etwas mehr Platz. Mir gefällts einfach besser :) if( tw > cw ) // Textbreite > Spaltenbreite ... sgrDataGrid->ColWidths[cn] = tw; // ... dann Spalte [cn] vergrössern
die neue Spaltenbreite fest.
Sollte mit einem DBGrid auch funktionieren?
grüssle
-
die automatische Anpassung der Spalten erfolgt immer über die Feldeigenschaften (TField, Field->DataTyp, Field->Size).
Wenn die Spaltenbreiten nicht auf die Feldeigenschaften, sondern auf die tatsächlichen Dateninhalte abgestimmt sein sollen, dann must du das selbst programmieren.1. Alle Datensätze in einer Schleife durchgehen
2. Jeweils die benötigte Spaltenbreite in Pixel ermitteln
=> DBGrid->Canvas->TextWidth("xxxx")
Wichtig: Vorher sicherstellen, dass DBGrid->Canvas->Font initialisiert ist
=> DBGrid->Canvas->Font = DBGrid->Font;3. Den größten Wert merken und am Ende der Schleife die Spaltenbreite setzen
for(int i=0;i < DBGrid->Columns->Count;i++)
{
if(DBGrid->Columns->Items[i]->FieldName == "MyFieldName")
DBGrid->Columns->Items[i]->Width = MyWidth;
}
-
Moin,
danke für deine Hilfe. Kleine Frage... In welcher Spalte befinde ich mich bei dieser Zeile?j.halder schrieb:
=> DBGrid->Canvas->TextWidth("xxxx")
Stehe momentan etwas auf dem Schlauch. Wie definiere ich die Spalte, aus der ich gerade den längsten Eintrag haben will?
Muss ich nicht jede einzelne Zelle durchgehen? Wenn ja, wie spreche ich eine Zelle an?
-
EPMS schrieb:
Moin,
danke für deine Hilfe. Kleine Frage... In welcher Spalte befinde ich mich bei dieser Zeile?j.halder schrieb:
=> DBGrid->Canvas->TextWidth("xxxx")
Stehe momentan etwas auf dem Schlauch. Wie definiere ich die Spalte, aus der ich gerade den längsten Eintrag haben will?
Muss ich nicht jede einzelne Zelle durchgehen? Wenn ja, wie spreche ich eine Zelle an?mit DBGrid->Canvas->TextWidth bekommst du die Breite deines Textes in Pixeln für diesen Canvas, also bei dir für das DBGrid. Spalte unwichtig
grüssle
-
Hallo,
da befindest du dich in keiner Spalte.
DBGrid->Canvas->TextWidth("xxxx") ist eine allgemeine Funktion von TCanvas (Zeichenfläche), mit der ermittelt werden kann, wieviele Pixel ein bestimmter Text ("xxxx") bei der eingestellten Schrift zur Anzeige benötigt.Im DBGrind sind die Spalten von links nach rechts folgendermaßen angeordnet:
DBGrid->Columns->Items[0] = erste Spalte (links)
DBGrid->Columns->Items[1] = zweite Spalte
DBGrid->Columns->Items[2] = dritte SpalteÜber die Eigenschaften der Spalten (Items) kannst du das zugeordnete Datenbankfeld ermitteln und dann im Table oder Query über FindField() oder FieldByName() die Feldinhalte der Datensätze auslesen.
TField *Field = Table->FindField(DBGrid->Columns->Items[0]->FieldName);
Field->AsStringTable->FieldByName(DBGrid->Columns->Items[0]->FieldName)->AsString
Über das DBGrid kannst du die Zellen nur waagerecht durchgehen (Spalten/rows):
for(int i=0;i < DBGrid->Columns->Count;i++) {
DBGrid->Columns->Items[i]->Senkrecht geht es nur über das Table bzw. Query (Zeilen/cols):
Table->First();
for(;Table->Eof == false;Table->Next())
{...}Verwechsle ein DBGrid nicht mit einem StringGrid. Beim StringGrid hat jede einzelne Zelle einen Datencontainer. Das DBGrid ist ein Anzeigemodul, es hat keinen Datencontainer, die Daten kommen aus einem Table.
-
Moin,
ich habe das jetzt so gelöst:DataModule1->sql_kontrolle->SQL->Clear(); DataModule1->sql_kontrolle->SQL->Add(sql_select); DataModule1->sql_kontrolle->Open(); DBKundendaten->Canvas->Font = DBKundendaten->Font; DBKundendaten->DataSource->DataSet->First(); for(int i=0;i < DBKundendaten->Columns->Count;i++) { MaxLange = 20; DataModule1->sql_kontrolle->First(); for(int a = 0; a <= DataModule1->sql_kontrolle->RecordCount; a++) { ZellenText = DBKundendaten->Fields[a,i]->AsString; Lange = DBKundendaten->Canvas->TextWidth(ZellenText); Lange += 8; if(Lange > MaxLange) MaxLange = Lange; DataModule1->sql_kontrolle->Next(); } DBKundendaten->Columns->Items[i]->Width = StrToInt(MaxLange); }
Funktioniert soweit auch.
-
Hallo,
in deinem Programmcode gibt es ein paar Dinge, die mir fragwürdig erscheinen:
DataModule1->sql_kontrolle->RecordCount sollte man nicht in einer Schleife aufrufen. RecordCount ist keine Variable, sondern eine Eigenschaft, hinter der sich eine Funktion verbirgt. Bei jedem Aufruf wird die Anzahl Datensätze neu ermittelt, was je nach Datenbankgröße und Datenbanksystem einiges an Zeit kostet.
Ich würde das so lösen:
int iRecordCount = DataModule1->sql_kontrolle->RecordCount;
for(int a = 0; a <= iRecordCount; a++)DBKundendaten->Fields[a,i]->AsString;
Ich kenne DBGrid->Fields[i], aber DBGrid->Fields[a,i] habe ich noch nie gesehen und verstehe es auch nicht. In der TDBGrid-Klasse finde ich keinen Operator, der dies abdeckt.
Hier bevorzuge ich den direkten Zugriff auf das Table bzw. Query: DataModule1->sql_kontrolle->FieldByName(...)->AsStringDBKundendaten->Columns->Items[i]->Width = StrToInt(MaxLange);
Warum StrToInt()? MaxLange ist doch sicher eine int-Variable, dann kann es direkt zugewiesen werden.
DBKundendaten->Columns->Items[i]->Width = MaxLange;
Der Compiler macht sonst so etwas daraus: StrToInt(AnsiString(MaxLange))