12. november 2008 - 10:15Der er
9 kommentarer og 2 løsninger
søge i stringlist
Er det muligt at søge data i en stringlist på en måde så det ikke er alle data i stringlisten der sendes videre ???
Ex:
Jeg har en fil med to kolonner, der indlæses i en stringlist. H1; Et eller andet H1; Noget tredje H1; Noget fjerde H2; Noget femte H2; Noget sjette H3; Noget syvne
Der er så en ComboBox1 hvor hvis der vælges "H2" skal der i onchange indsættes 2 valgmuligheder i ComboBox2 hvor der så i dette tilfælde efterfølgende ville være følg. valgmuligheder
Nej ikke helt... CB1 er blevet defineret.. men indholdet i CB2 skal ske udfra valget i CB1 Hvis jeg vælger "H1" i CB1 skal CB2 have added strings fra kolonne 2 i CSV-filen således at der er følg. valg i CB2: Et eller andet Noget tredje Noget fjerde
Da disse står ud for værdien H1 som blev valgt i CB1... Håber jeg fik klarlagt det mere forståeligt :-)
Så vidt jeg kan se svarede du ja til mit spørgsmål... Jeg lave en liste der indeholder en liste af TMyStringList. Hvert TMyStringList hægter jeg på linjerne i Combobox1 og når der vælges en der kan jeg kopiere alle forekomster af kolonne2 over i combobox.
- Først unitten:
unit UMyList;
interface
uses SysUtils, Classes, ContNrs;
type TMyStringList = class(TStringList) private fName: string; public constructor Create(const aName: string); property Name: string read fName; end;
TMyList = class(TObjectList) private function GetItems(const aIndex: integer): TMyStringList; public function IndexOf(aName: string): integer; procedure LoadFromFile(const aFilename: string); property Items[const aIndex: integer]: TMyStringList read GetItems; procedure FillList(aStrings: TStrings); end;
procedure TMyList.FillList(aStrings: TStrings); var i: integer; begin aStrings.BeginUpdate; try aStrings.Clear; for i := 0 to Count - 1 do aStrings.AddObject(Items[i].Name,Items[i]); finally aStrings.EndUpdate; end; end;
function TMyList.GetItems(const aIndex: integer): TMyStringList; begin result := inherited Items[aIndex] as TMyStringList; end;
function TMyList.IndexOf(aName: string): integer; var i : integer; Found : boolean; begin result := -1; i := -1; Found := false; while (i < Count - 1) and not Found do begin inc(i); Found := AnsiSameText(aName,Items[i].Name); end; if Found then result := i; end;
procedure TMyList.LoadFromFile(const aFilename: string); var List: TStringList; st, Col1, Col2: string; i, p, Index: integer; MyStringList: TMyStringList; begin List := TStringList.Create; try Clear; List.LoadFromFile(aFilename); for i := 0 to List.Count - 1 do begin st := List[i]; p := pos(';',st); if p > 0 then begin Col1 := trim(copy(st,1,p-1)); Col2 := trim(copy(st,p+1,maxint)); Index := IndexOf(Col1); if Index < 0 then MyStringList := TMyStringList.Create(Col1) else MyStringList := Items[i]; MyStringList.Add(Col2) end; end; finally List.Free; end; end;
procedure TfrmMain.cbCombo1Change(Sender: TObject); var MyStringList: TMyStringList; begin with (Sender as TComboBox) do if ItemIndex >= 0 then begin MyStringList := Items.Objects[ItemIndex] as TMyStringList; MyStringList.Assign(cbCombo2.Items); end else cbCombo2.Items.Clear; end;
procedure TfrmMain.FormCreate(Sender: TObject); begin fMyList := TMyList.Create; fMyList.LoadFromFile('data.txt'); fMyList.FillList(cbCombo1.Items); end;
procedure TfrmMain.FormDestroy(Sender: TObject); begin fMyList.Free; end;
Bemærk. Det er et skoleeksempel som er helt stringent og færdigt. Det fylder lidt mere, men jeg mener det er en god løsning. Eneste ulempe jeg kan se er den sekventielle søgning i IndexOf. Den burde måske være indekseret.
Der kan tilføjes sortering på kolonne 1 og kolonne2 efter behag.
Jeg bruger TClientDataSet meget men ikke noget med nedarvinger.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.