@Bruno(M) - słabo opisałeś problem, ale mniej więcej rozumiem co chcesz zrobić; Jeśli chodzi Ci o to, że w danej liście łańcuchów oddzielonych liniami wyszukujesz daną wartość, to jeśli w danej sekcji znajduje się szukana wartość, to kopiujesz całą sekcję razem z liniami; Pomijane są te sekcje, które szukanej wartości nie zawierają;
Czyli dla przykładu mająt takie wejście:
--------------------
1
2
--------------------
4
5
--------------------
1
2
--------------------
7
8
--------------------
i szukając wartości np. 1
, na wyjściu dostaniemy:
--------------------
1
2
--------------------
1
2
--------------------
czyli sekcję pierwszą i trzecią, tak?
Masz tutaj prosty algorytm realizujący Twoje założenia (pod warunkiem, że dobrze zrozumiałem co dokładnie chcesz zrobić):
const
BREAK_LINE_CHAR = '-';
BREAK_LINE = '--------------------';
var
slInput, slOutput: TStrings;
intSecBgnIdx, intSecEndIdx, I, J: Integer;
ansiNumber: AnsiString;
begin
{ tymczasowe listy wejścia i wyjścia }
slInput := TStringList.Create();
{ pobranie z komponentu szukanej wartości }
slOutput := TStringList.Create();
try
{ skopiowanie listy wejścia do listy tymczasowej }
slInput.Assign(memInput.Lines);
ansiNumber := edtNumberToFind.Text;
{ sprawdzenie ilości linii w liście wejścia }
if slInput.Count > 0 then
begin
I := 0;
{ dopóki licznik pętli jest mniejszy lub równy ilości linii w liście }
while I < slInput.Count do
{ jeśli aktualna linia zawiera szukaną liczbę }
if slInput[I] = ansiNumber then
begin
{ ustawienie początkowych ideksów sekcji }
intSecBgnIdx := I;
intSecEndIdx := I;
{ szukanie początku sekcji razem z linią separatora }
repeat
Dec(intSecBgnIdx);
until slInput[intSecBgnIdx][1] = BREAK_LINE_CHAR;
{ szukanie końca sekcji bez linii separatora }
while slInput[intSecEndIdx + 1][1] <> BREAK_LINE_CHAR do
Inc(intSecEndIdx);
{ skopiowanie linii sekcji bez końcowej linii separatora }
for J := intSecBgnIdx to intSecEndIdx do
slOutput.Add(slInput[J]);
{ ustawienie licznika pętli na indeks linii końca sekcji + 1 }
I := intSecEndIdx + 1;
end
else
{ jeśli aktualna linia nie zawiera szukanej liczby - zwiększenie licznika pętli }
Inc(I);
{ jeśli lista wyjścia nie jest pusta - dodanie końcowej linii separatora }
if slOutput.Count > 0 then
slOutput.Add(BREAK_LINE);
{ przepisanie listy tymczasowej do komponentu wyjścia }
lbOutput.Items.Assign(slOutput);
end;
finally
slInput.Free();
slOutput.Free();
end;
end;
Ten kod podpiąłem pod zdarzenie przycisku w aplikacji testującej i działa elegancko pod warunkiem, że format danych wejściowych jest poprawny; Algorytm możesz sobie zabezpieczyć, jeśli wejście może być błędnego formatu; Tak poza tym jest dobrze - sprawdziłem m.in. dane podane przez Ciebie w poście wyżej - wyjście dokładnie takie samo;
Sprawdzanie czy linia jest separatorem odbywa się nieco inaczej, bo wystarczy sprawdzić, czy pierwszy znak linii to znak -
i jeśli tak - jest separatorem; Jeśli liczby mogą być ujemne - trzeba to będzie zabezpieczyć, ale to już pozostawiam Tobie;
W załączniku dodaję aplikację testującą (skopilowany exe
) i pliki projektu, jednak napisanego w Lazarusie - kod i tak powinien być w pełni kompatybilny z różnymi wersjami Delphi, ponieważ nie zawiera jakichś sztuczek;