Stringgrid - Nutzung der Picklist
Stringgrid - Nutzung der Picklist
Ich verwende ein Stringgrid zum Einlesen und Bearbeiten / Ergänzen von CSV-Daten vor der Übernahme in eine Datenbank.
Dabei kommen Checkboxen und Picklisten zum Einsatz.
Während die Inhalte der Checkboxen problemlos gesetzt und ausgelesen werden können, habe ich bei der Picklist ein Problem:
1. Wie kann ich zeilenweise einen Vorschlag für den Feldinhalt setzen?
und
2. Wie kann ich den Inhalt der Auswahl ( ItemIndex der Picklist ) zeilenweise wieder auslesen.
Momnetan hab ich die Vermutung, dass 1. gar nicht geht und 2. nur über den Umweg, den ausgewählten Text der Zelle wieder in einen Index umzuwandeln.
Hat jemand eine andere Möglichkeit / Lösung?
Danke
Dabei kommen Checkboxen und Picklisten zum Einsatz.
Während die Inhalte der Checkboxen problemlos gesetzt und ausgelesen werden können, habe ich bei der Picklist ein Problem:
1. Wie kann ich zeilenweise einen Vorschlag für den Feldinhalt setzen?
und
2. Wie kann ich den Inhalt der Auswahl ( ItemIndex der Picklist ) zeilenweise wieder auslesen.
Momnetan hab ich die Vermutung, dass 1. gar nicht geht und 2. nur über den Umweg, den ausgewählten Text der Zelle wieder in einen Index umzuwandeln.
Hat jemand eine andere Möglichkeit / Lösung?
Danke
Jeder macht Fehler - viele Fehler brauchen EDV!
Re: Stringgrid - Nutzung der Picklist
Doch, doch, das geht alles. Je nach Vorstellung variiert der Arbeitsumfang.
Wenn du Columns nutzt, diese zur Designzeit im Objetinspektor definierst, kannst du den ButtonStyle auf cbsPickList stellen und Einträge in das Property PickList eintragen und schon hast du eine Picklist, dessen ItemIndex sich nach dem Inhalt der Zelle richtet. Der in der PickList gewählte Eintrag wird automatisch in die Zelle übernommen.
Willst du den Automatismus nicht nutzen, kannst du das auch händisch erledigen. Der Einstieg wäre hier: http://wiki.freepascal.org/Grids_Refere ... _run_time.
Damit hast du eine TCustomComboBox, deren Index du mittels ItemIndex setzen kannst usw.
Man kann auch recht unkompliziert einen eigenen Editor schreiben, so nutze ich zum Beispiel einen, der im Editmodus eine Auswahl an Vorschlägen zur Verfügung stellt und je nach Eingabe des Textes diese Auswahl aktualisiert (ähnlich dem Suchfenster beim Firefox).
Wenn du gar nicht weiter kommst, zeige doch mal etwas Code, was du probiert hast oder lade hier ein Minimalbsp. ohne Executable und Libs hier hoch.
Wenn du Columns nutzt, diese zur Designzeit im Objetinspektor definierst, kannst du den ButtonStyle auf cbsPickList stellen und Einträge in das Property PickList eintragen und schon hast du eine Picklist, dessen ItemIndex sich nach dem Inhalt der Zelle richtet. Der in der PickList gewählte Eintrag wird automatisch in die Zelle übernommen.
Willst du den Automatismus nicht nutzen, kannst du das auch händisch erledigen. Der Einstieg wäre hier: http://wiki.freepascal.org/Grids_Refere ... _run_time.
Damit hast du eine TCustomComboBox, deren Index du mittels ItemIndex setzen kannst usw.
Man kann auch recht unkompliziert einen eigenen Editor schreiben, so nutze ich zum Beispiel einen, der im Editmodus eine Auswahl an Vorschlägen zur Verfügung stellt und je nach Eingabe des Textes diese Auswahl aktualisiert (ähnlich dem Suchfenster beim Firefox).
Wenn du gar nicht weiter kommst, zeige doch mal etwas Code, was du probiert hast oder lade hier ein Minimalbsp. ohne Executable und Libs hier hoch.
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Re: Stringgrid - Nutzung der Picklist
Also - das Erstellen der Picklist ist nicht mein Problem.
Die Picklist ist in Col 5 und in allen Rows gleich. Der Anwender wählt hier eine Zuordnung aus.
Beim Füllen des Grids soll die Picklist auf einen Vorschlag gesetzt werden, der sich am inhalt einer anderen Zelle orientiert - etwa so als startk vereinfachtes Beispiel:
Alternativ habe ich darüber nachgedacht, den "Text" direkt einzustellen (also "Affe").
Dies löst aber nicht das Problem des Rückgabewertes ausser ich frag auf eine leere Zelle ab.
Hoffe es ist verständlich.
Code: Alles auswählen
//Füllen der Kategorieauswahlfelder in Picklist
sgData.Columns[5].PickList.Clear;
for i := 0 to HIGH(aKat) do
begin
if aKat[i].KatUID <> 0 then pre := cStrich+cBlank else pre := cEmpty;
sgData.Columns[5].PickList.Add(pre + aKat[i].KBez);
end;
Beim Füllen des Grids soll die Picklist auf einen Vorschlag gesetzt werden, der sich am inhalt einer anderen Zelle orientiert - etwa so als startk vereinfachtes Beispiel:
Code: Alles auswählen
Function GetKatVorschlag(sText:string):integer;
begin
result := -1;
if sText = 'Affe' then result := 1;
...
if sText = 'Rose' then result := 4;
end;
PickList[5,iRow].ItemIndex := GetKatVorschlag(sgData.Cells[1,iRow]);
Dies löst aber nicht das Problem des Rückgabewertes ausser ich frag auf eine leere Zelle ab.
Hoffe es ist verständlich.
Jeder macht Fehler - viele Fehler brauchen EDV!
Re: Stringgrid - Nutzung der Picklist
Wie oben schon geschrieben:
Weitere Ereignisse identisch.
Michl hat geschrieben:Damit hast du eine TCustomComboBox, deren Index du mittels ItemIndex setzen kannst usw.
Sollte z.B. so funktionieren:RuhrPotto hat geschrieben:Beim Füllen des Grids soll die Picklist auf einen Vorschlag gesetzt werden, der sich am inhalt einer anderen Zelle orientiert
Code: Alles auswählen
TForm1 = class(TForm)
...
private
FcbxEditor: TCustomComboBox;
procedure FcbxEditorEnter(Sender: TObject);
end;
...
procedure TForm1.StringGrid1SelectEditor(Sender: TObject;
aCol, aRow: Integer; var Editor: TWinControl);
begin
if Editor is TCustomComboBox then begin
FcbxEditor := TCustomComboBox(Editor);
FcbxEditor.OnEnter := @FcbxEditorEnter;
end;
end;
procedure TForm1.FcbxEditorEnter(Sender: TObject);
begin
FcbxEditor.ItemIndex := GetKatVorschlag(...);
end;
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Re: Stringgrid - Nutzung der Picklist
@Michl : Danke für die Hilfe! Das Anzeigen eines Vorschlages funktioniert soweit.
Aber ich hab leider ein Brett vorm Kopf. Das Auslesen des ItemIndex bei der Prüfung krieg ich nicht hin.
Wenn alle Datenreihen bearbeitet wurden, dann sollen die Zellinhalte des Grids geprüft werden - in etwa so:
Die Prüfung der Datenreihe soll erst nach ButtonClick erfolgen.
Wie kann ich denn dann noch auf den Index zugreifen?
Aber ich hab leider ein Brett vorm Kopf. Das Auslesen des ItemIndex bei der Prüfung krieg ich nicht hin.
Wenn alle Datenreihen bearbeitet wurden, dann sollen die Zellinhalte des Grids geprüft werden - in etwa so:
Code: Alles auswählen
procedure TFrmMain.btCheckGridDataClick(Sender: TObject);
var
i : integer;
begin
for i := 1 to sgData.RowCount -1 do
begin
if sgData.Cells[0,i] = '0' then //cbsCheckboxColumn - false - keine Auswahl
begin
Memo1.Lines.Add('> Keine Übernahme für : ' + sgData.Cells[1,sgData.Row]);
Continue;
end;
if sgData.Cells[2,i] ItemIndex <= 0 then //cbsPickList
begin
Memo1.Lines.Add('> Auswahlfehler : ' + sgData.Cells[1,sgData.Row]);
Continue;
end;
//Übertrag in Ergebnismenge ....
end;
end;
Wie kann ich denn dann noch auf den Index zugreifen?
Jeder macht Fehler - viele Fehler brauchen EDV!
Re: Stringgrid - Nutzung der Picklist
Geht sicherlich auch anders, doch wenn der Editor schon wieder freigegeben wurde, müsstest du einfach die letzte Wahl in einer Variablen (Index oder Inhalt) speichern. Z.B. irgendwie so (ist nicht ganz sauber, funktioniert aber bei mir, da TComboBox nur die Properties von TCustomComboBox veröffentlicht, OnChange bei TCustomComboBox aber protected ist):
Wenn du es sauber haben willst, müsstest du das Ereignis für TCustomComboBox öffentlich machen.
Code: Alles auswählen
TForm1 = class(TForm)
...
private
FcbxEditor: TComboBox;
FcbxLastSelect: String;
procedure FcbxEditorChange(Sender: TObject);
end;
...
procedure TForm1.StringGrid1SelectEditor(Sender: TObject;
aCol, aRow: Integer; var Editor: TWinControl);
begin
if Editor is TCustomComboBox then begin //<-- das mit nächster Zeile
FcbxEditor := TComboBox(Editor); //<-- ist eigentlich verboten
FcbxEditor.OnChange := @FcbxEditorChange;
end;
end;
procedure TForm1.FcbxEditorChange(Sender: TObject);
begin
FcbxLastSelect := FcbxEditor.Items[FcbxEditor.ItemIndex];
end;
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Re: Stringgrid - Nutzung der Picklist
Danke Michl - hast mir den Tag gerettet!
Da ich das Grid am Ende vollständig durchlaufen muss und dieses mit verschiedenen Abhängigkeiten variabel biszu 15 Spalten hat, verwende ich ich eine Indextabelle zur Zwischenspeicherung.
Erscheint mir zum jeztigen Zeitpunkt die zweckmässigste Lösung:
Damit kann ich Prüfung in einer Schleife nunmehr problemlos handeln und ungültige / fehlerhafte Datenreihen rausfiltern.
Da ich das Grid am Ende vollständig durchlaufen muss und dieses mit verschiedenen Abhängigkeiten variabel biszu 15 Spalten hat, verwende ich ich eine Indextabelle zur Zwischenspeicherung.
Erscheint mir zum jeztigen Zeitpunkt die zweckmässigste Lösung:
Code: Alles auswählen
var
FcbxEditorSelections : array of integer;
...
//Länge analog Griddaten und vorbelegen mit keine Auswahl
SetLength(FcbxEditorSelections,sgData.RowCount-1);
for i := 0 to High(FcbxEditorSelections) do FcbxEditorSelections[i] := -1;
...
procedure TFrmMain.FcbxEditorEnter(Sender: TObject);
var
ind : integer;
begin
ind := GetKatVorschlag(sgData.Cells[1,sgData.Row]);
FcbxEditor.ItemIndex := ind;
FcbxEditorSelections[sgData.Row -1] := ind; //Vorauswahl zwischenspeichern
end;
...
procedure TFrmMain.FcbxEditorChange(Sender: TObject);
begin
FcbxEditorSelections[sgData.Row -1] := FcbxEditor.ItemIndex; //Auswahl durch Anwender geändert
end;
//Plausi der Griddaten
procedure TFrmMain.btCheckGridDataClick(Sender: TObject);
var
i : integer;
wfS : string;
begin
for i := 1 to sgData.RowCount -1 do
begin
...
if FcbxEditorSelections[i -1] <= 0 then
begin
Memo1.Lines.Add('> Keine Zuordnung für : ' + sgData.Cells[1,i]);
Continue;
end;
...
end;
end;
Jeder macht Fehler - viele Fehler brauchen EDV!