W podanym przeze mnie kodzie, nie da się zastosować rozwiązania podanego przez
polymorphism, gdyż komunikat byłby wyświetlany przed każdym rozpoczęciem wyszukiwania, podczas gdy założenie kodu jest takie: szukaj tekstu w komórka rozpoczynając wyszukiwanie od ostatnio zapamiętanej komórki, jeżeli nic nie znajdziesz zadaj pytanie czy wyszukiwać od początku, jeżeli znajdziesz zaznacz komórkę ze znalezionym tekstem i przerwij wyszukiwanie. Nie da się tego tak zrobić z pętlą while.
Kod zawierał błędy podaję działający.
- Kod: Zaznacz cały
void __fastcall Szukaj(String findText, TStringGrid *Tabela)
{
static int x = 1;
static int y = 1;
static String memText = "";
if(memText.Trim().LowerCase() != findText.Trim().LowerCase())
{
x = 1;
y = 1;
}
LAB_1:
for(int i = y; i < Tabela->RowCount; i++)
{
for(int j = x; j < Tabela->ColCount; j++)
{
String tekst = Tabela->Cells[i][j].Trim();
Tabela->Col = j;
Tabela->Row = i;
if(tekst.LowerCase() == findText.Trim().LowerCase())
{
Tabela->Col = j;
Tabela->Row = i;
if(j < Tabela->ColCount) x = j + 1; else x = 1;
if(i < Tabela->RowCount) y = i; else y = 1;
memText = findText;
return;
}
}
x = 1;
}
int idx = Application->MessageBox( ("W tabeli ie odnaleziono tekstu \"" + findText + "\". Czy chcesz przeszukać tabelę od początku?").c_str(),
"Wyszukiwanie", MB_YESNO | MB_ICONQUESTION);
x = 1;
y = 1;
if(idx == ID_YES) goto LAB_1;// Szukaj(findText, Tabela);
}
//-----------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
String fText = "poszukiwany tekst";
Szukaj(fText, StringGrid1);
}
//------------------------------------------------------------------------
pętli while nie da się tutaj zastosować, gdyż komunikat może być wyświetlany tylko w sytuacji, gdy zostanie przeszukana cała tabela i nie znajdzie już więcej poszukiwanego tekstu.
Zasada działania:
Po zleceniu wyszukania nowego tekstu funkcja Szukaj rozpoczyna wyszukiwanie od pierwszej komórki Tabeli, jeżeli znajdzie tekst zaznacza znalezioną komórkę
(by zaznaczenie działało właściwość Options goAlvaysShowEditor musi mieć wartość false) i zapamiętuje w zmiennych (x, y) numer komórki, gdy ponownie zlecimy wyszukiwanie tego samego tekstu
(może się zdarzyć, że tekst powtarza się w komórkach) funkcja rozpocznie poszukiwanie tekstu od ostatniej zapamiętanej pozycji, a nie od początku. Gdy wyszukiwanie dojdzie do końca Tabeli, funkcja zada pytanie (tylko w tej sytuacji), czy rozpocząć wyszukiwanie od początku, jeżeli TAK, funkcja powróci do do początku poprzez funkcję goto
(zamiast goto można użyć wywołania rekurencyjnego, ja jednak lubię posługiwać się goto, chociaż jest potencjalnie niebezpieczna, w tym kodzie jednak sprawdza się w 100%). Jeżeli odpowiedź na pytanie brzmi NIE, funkcja przerywa wyszukiwanie i ustawia się na pierwszą komórkę tabeli. Jeżeli funkcja wykryje, że poszukiwany tekst się zmieni to funkcja rozpoczyna wyszukiwanie od początku.
Przykład z wywołaniem rekurencyjnym:
- Kod: Zaznacz cały
//---------------------------------------------------------------------------
void __fastcall Szukaj(String findText, TStringGrid *Tabela)
{
static int x = 1;
static int y = 1;
static String memText = "";
if(memText.Trim().LowerCase() != findText.Trim().LowerCase())
{
x = 1;
y = 1;
}
for(int i = y; i < Tabela->RowCount; i++)
{
for(int j = x; j < Tabela->ColCount; j++)
{
String tekst = Tabela->Cells[j][i].Trim();
Tabela->Col = j;
Tabela->Row = i;
if(tekst.LowerCase() == findText.Trim().LowerCase())
{
Tabela->Col = j;
Tabela->Row = i;
if(j < Tabela->ColCount) x = j + 1; else x = 1;
if(i < Tabela->RowCount) y = i; else y = 1;
memText = findText;
return;
}
}
x = 1;
}
int idx = Application->MessageBox( ("W tabeli ie odnaleziono tekstu \"" + findText + "\". Czy chcesz przeszukać tabelę od początku?").c_str(),
"Wyszukiwanie", MB_YESNO | MB_ICONQUESTION);
x = 1;
y = 1;
if(idx == ID_YES) Szukaj(findText, Tabela);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
String fText = Edit1->Text;
Szukaj(fText, StringGrid1);
}
//---------------------------------------------------------------------------
Zmieniłem zakres wyszukiwania z 0,0 na 1,1 by ominąć komórki nagłówka. Jeżeli nagłówki mają tylko kolumny, a wiersze nie maja nagłówka to wszędzie tam gdzie y = 1; zmieniasz na y = 0;
Z pętlą
while nie będzie działał prawidłowo, sam zdecyduj co wolisz przestarzała i niezalecaną funkcję
goto, czy też wywołanie rekurencyjne.