Results 1 to 13 of 13

Thread: Bepaalde Items laden in TStringlist

  1. #1

    Bepaalde Items laden in TStringlist

    Wat ik in principe wil is een stringlist die bepaalde regels kan verbergen.
    Maar ik denk niet dat dat kan en het meer in het volgende moet zoeken:
    Is het mogelijk om alleen bepaalde regels te laden uit een tekstfile?

    Volgende opdracht laadt het hele bestand:
    Tekst.Lijst.Items.LoadFromFile('.\Ledenlijst.txt') ;

    Ik wil graag per regel / item lezen en dan bijv alleen als er 'abc' in staat.
    En alleen deze in de Lijst zetten.
    -------------------------------------------------------------------------
    (Items tellen, wissen, bewerken etc. = allemaal geen probleem dus daar gaat de vraag niet over!)

  2. #2
    Je kunt natuurlijk op de oude manier regels lezen en deze toevoegen indien nodig aan de stringlist.

    Maar ik denk dat het efficiënter is een loadfromfile te doen en dan de regels die voldoen te kopiëren naar een nieuwe stringlist (of de regels die niet voldoen te verwijderen maar dat hangt van de snelheid af).

  3. #3
    Daar gaat het nu juist om ... Hoe Filter ik die regels die ik wel wil eruit?
    Voor ik ze in het programma toon. (want het gaat niet om het bewaren)...

  4. #4
    Je kan een TStringList maken die je als buffertje gebruikt. Je laadt de inhoud van de file in die stringlist, filtert de ongewenste items eruit, en kent het resultaat toe aan een Doel-TStrings, zoals TListBox.Items.

    Delphi Code:
    1. var
    2.   Bron: TStringList;
    3.   i: Integer;
    4. begin
    5.   Bron := TStringList.Create;
    6.   try
    7.     Bron.LoadFromFile('C:\ff\test.txt');
    8.     // Items wegfilteren uit Bron
    9.     for i := Bron.Count - 1 downto 0 do
    10.       if Pos('abc', Bron[i]) = then
    11.         Bron.Delete(i);
    12.  
    13.     // Daarna toekennen aan Doel.
    14.     Doel.Assign(Bron);
    15.   finally
    16.     Bron.Free;
    17.   end;
    18. end;

    Wat misschien beter is, is om Bron onveranderd te laten na het inladen, en alleen de items die je wilt hebben naar Doel te kopieren:

    Delphi Code:
    1. var
    2.   Bron: TStringList;
    3.   i: Integer;
    4. begin
    5.   Bron := TStringList.Create;
    6.   try
    7.     Bron.LoadFromFile('C:\ff\test.txt');
    8.  
    9.     // Gewenste items kopieren naar Doel. Bron blijft onveranderd.
    10.     Doel.BeginUpdate;
    11.     try
    12.       for i := 1 to Bron.Count do
    13.         if Pos('abc', Bron[i]) > 0 then
    14.           Doel.Add(Bron[i]);
    15.     finally
    16.       Doel.EndUpdate;
    17.     end;
    18.   finally
    19.     Bron.Free;
    20.   end;
    21. end;

    Het voordeel hiervan is dat je makkelijk kan blijven filteren, zonder dat je opnieuw het bestand hoeft te laden. Dat kan bijvoorbeeld handig zijn als je snel wilt kunnen filteren in een tamelijk grote tekst. Je laadt 1 keer het bestand in, en daarna hoef je alleen maar in-memory te filteren wat super snel is.
    Voorbeeldje in de bijlage.

    filterdemo.zip
    Last edited by GolezTrol; 04-Nov-18 at 22:37.
    1+1=b

  5. #5
    Bedankt - ik ga ermee aan de slag! - (het is niet altijd even eenvoudig....)
    De lijst wordt in een apart venster getoond en een keuze heeft een gevolg.
    Alleen staan er twee soorten items in en het leek me gebruikersvriendelijker
    om die items die niet van toepassing waren te filteren.
    (Andere optie was 2 lijsten maken natuurlijk maar wilde ze ook weer bij elkaar).
    Last edited by Marieke; 03-Nov-18 at 23:05.

  6. #6
    Het is gelukt - Ik had eigenlijk 3 lijsten nodig.
    Er waren 3 mogelijkheden, het ene tonen, het andere of alles.
    Ik heb het zo opgelost:
    Code:
      Bron:= TStringList.Create;
      Doel2:= TStringList.Create;
      Doel1:= TStringList.Create;
      try
        Bron.LoadFromFile('.\OrgineleBron.txt');
        for i := OrigineleBron.Count - 1 downto 1 do 
          if Pos('ABC, Bron[i]) >0 then
          Doel2.Add(Bron[i])
          else
          Doel1.Add(Bron[i]);         
      finally
      end;
      If (Form.chbBox1.Checked) AND NOT (Form.chbBox2.Checked) then
         begin
         Form.lbxLijst.Items.Assign(Doel1);
         Doel1.Free;
         Doel2.Free;
         Bron.Free;
         end;
    // etc.. 
    ...
    Code is wat aangepast t.b.v. het forum.
    In de rest van de procedure worden de Stringlisten free gemaakt
    en staat de code voor de 2 checkboxjes die ik in het form heb gezet.

  7. #7
    De volgende regel behoeft nog een verandering:

    for i := OrigineleBron.Count - 1 downto 1 do

    Moet zijn

    for i := OrigineleBron.Count - 1 downto 0 do

  8. #8
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Waarom een downto en niet gewoon oplopend?
    Delphi is great. Lazarus is more powerfull

  9. #9
    Quote Originally Posted by jkuiper View Post
    Waarom een downto en niet gewoon oplopend?
    Ik heb het nooit eerder gebruikt maar dit lijkt mij de kortste weg.
    Als we de opdracht geven is het onbekend hoeveel regels er in de tekst staan.
    We weten wel het laagste getal, namelijk 0 want dat is het eerste index nummer in de Stringlist.
    Dus we kunnen niet oplopend tellen zonder extra code om erachter te komen wat dan het hoogste getal is.
    (Dat is tenminste mijn redenatie.)
    Code:
    Bron.LoadFromFile('.\OrgineleBron.txt');
    for i := OrigineleBron.Count - 1 downto 0 do

  10. #10
    Nee hoor, na de LoadFromFile zijn alle regels in het geheugen ingelezen (heel snel en sneller dan readlines). Dus je weet de totaal aantal regels, n.l. TStringList.Count.

    De praktijk van Count -1 downto 0 wordt meestal gebruikt als je de regels zelf weg gaat halen in de lijst. Want als je 0 to Count - 1 hebt en je haalt er een regel tussenuit dan sla je de huidige index over (omdat je I verwijdert, maar de for lus wel de I ook ophoogt).

    Dus...
    For I := 0 to ThisList.Count - 1 do AddToOtherList.Add(ThisList.String(I));
    (de huidige ThisList lijst wordt niet aangetast tijdens de loop dus het is geen probleem om 0 to count - 1 te doen)

    maar
    For I := ThisList.Count - 1 downto 0 do ThisList.Delete(I);
    (hier wordt de huidige lijst aangetast dus we willen van achter naar voren gaan)

    (code niet helemaal syntax correct maar je begrijpt het punt waarschijnlijk wel)

  11. #11
    Oké - Met deze optie komen de regels beter onder elkaar te staan (laatste onderaan).
    Iets versimpeld t.o.v. voorbeeld...
    Code:
        Bron.LoadFromFile('.\Mijntekst.txt');
        for i := 0 to Bron.Count -1  do   
          if Pos('ABC', Bron[i]) >0 then
          Doel2.Add(Bron[i])
          else
          Doel1.Add(Bron[i]);
    ....
    LEERZAAM! RVK
    Last edited by Marieke; 04-Nov-18 at 18:12.

  12. #12
    Yep, en als je bijvoorbeeld met dezelfde TStringList wilt blijven werken en regels die niet voldoen wilt verwijderen dan die je dus dit (en werk je wel van count - 1 downto 0.

    Delphi Code:
    1. Bron.LoadFromFile('.\Mijntekst.txt');
    2. for i := Bron.Count - 1 downto 0 do  
    3.   if Pos('ABC', Bron[i]) = 0 then
    4.     Bron.Delete(i);

    (Dan heb je geen Doel1 en Doel2 nodig. Werkt natuurlijk alleen als je de lijst wilt hebben met regels met ABC en geen lijst nodig hebt zonder.)

  13. #13
    Ik heb zelfs 3 lijsten nodig voor bij 3 verschillende vensters
    Bij Venster 1 met de oorspronkelijke bronlijst die je kan bewerken.
    Keuze is in te stellen via checkboxjes.
    Bij Venster 2 toont de lijst Doel 1 / Bewerken uitgeschakeld
    Bij Venster 3 toont de lijst Doel 2 / Bewerken uitgeschakeld
    Voorbeeld zoals bij venster 1 en 3:
    ..
    Click image for larger version. 

Name:	prglenormstudy7.jpg 
Views:	195 
Size:	57.1 KB 
ID:	7822
    ::
    (Form is in werkelijkheid hoger)

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •