Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem Delphi - TTable - filter

Chcel by som nastaviť v TTable takýto filter:
1. "case sensitive"
2. možnosť zadania aj textu zo stredu položky
3. kontrola všetkých položiek

Je takáto možnosť? Ja mám teraz nastavený takýto a ďalej sa neviem pohnúť:
1. možnosť zadania len od začiatku položky
2. kontrola všetkých položiek

Tu je "zdroják" filtra:

procedure TCllientsForm.edSearchChange(Sender: TObject);
var
  s: String;
begin
  Table.Filtered := False;
  s := edSearch.Text + '*';
  if s <> '' then
    begin
      Table.Filter := '([0] = ' + QuotedStr(s) +
       ') or ([1] = ' + QuotedStr(s) +
       ') or ([2] = ' + QuotedStr(s) +
       ') or ([3] = ' + QuotedStr(s) +
       ') or ([4] = ' + QuotedStr(s) +
       ') or ([5] = ' + QuotedStr(s) +
       ') or ([6] = ' + QuotedStr(s) + ')';
      Table.Filtered := True;
    end;
end;
Předmět Autor Datum
Na zadani filtru podle zacatku obsahu polozky by mela slouzit property FilterOptions: TFilterOption…
Jan Fiala 27.06.2006 09:37
Jan Fiala
Bez hviezdičky to berie iba položky s obsahom, ktorý sa zhoduje so zadaným textom. Vyskúšam čo píšet…
msx. 27.06.2006 09:45
msx.
Nepozná TTable.FilterOption.:.( Edit: Trošku som sa s tým pohral a zistil som, že to je: TTable.Fil…
msx. 27.06.2006 09:48
msx.
Dobre mám "case sensitive", ale stále to nehľadá uprostred položky, iba od začiatku. Čo teraz? V hel…
msx. 27.06.2006 10:00
msx.
Na toto sa pouzivaju standartne "zoliky" ? - nahradny znak * - vsetko Ked chces najst nieco v strede…
MatoZ 27.06.2006 10:09
MatoZ
Ale ja tam chcem partial. *jan* som skúšal. Inak by som sa to nepýtal. Hviezvička funguje ako v DOSe…
msx. 27.06.2006 10:50
msx.
Neviem o aku tabulku ide , /databazovy system/ ... Ani % nefunguje?
MatoZ 27.06.2006 11:00
MatoZ
Ak nejde priamo cez filter da sa to urobit aj cez udalost Table1 table1filterrecord(Dataset:Tdataset…
MatoZ 27.06.2006 11:13
MatoZ
Muzes si to resit sam v udalosti OnFilterRecord (aspon tak se to tusim jmenuje)
Jan Fiala 27.06.2006 11:11
Jan Fiala
Přesně tak. Zde nabízím (moji vlastní) rutinu, na porovnání řetězce s žolíky: {--------------------…
Rce 28.06.2006 00:06
Rce
Uvnitře je použita tato funkce (možno jí nacpat dovnitř). {------------ Pascalské POS optimalizovan…
Rce 28.06.2006 00:11
Rce
Nezkousel jsi pouzit funkci MatchesMask() z unity Masks ?
Jan Fiala 28.06.2006 00:14
Jan Fiala
To moje je podstatně rychlejší.;-):-p
Rce 28.06.2006 00:16
Rce
Mas pravdu, je to asi 4x rychlejsi. Na 100000 porovnani tva pulsekunda oproti 2s funkce MatchesMasks…
Jan Fiala 28.06.2006 00:41
Jan Fiala
Já to právě třeba používám v OnFiltered. Mám ve vyhledávacích oknech (třeba adresářů) takovou funkci…
Rce 28.06.2006 00:47
Rce
Áno, áno, presne to robím aj ja.;-) Edit: Tú procedúru teda len zaradím k udalosti OnFilterRecord?
msx. 28.06.2006 14:55
msx.
Nechceš poslat někam celý program s tou tabulkou, jak to řeším já?
Rce 28.06.2006 23:39
Rce
Ja žew som ťa nahneval som si myslel v prvej chvíli.:-) Môžeš a pozriem saa naň.. Ďakujem. Myslím, ž…
msx. 29.06.2006 14:34
msx.
Proč bych se měl hněvat? ::):-) Zde máš inspiraci: HF.zip
Rce 29.06.2006 22:54
Rce
Veľmi pekne ďakujem.:beer:
msx. 29.06.2006 23:15
msx.
[cyrilic.gif] poslední
Rce 29.06.2006 23:22
Rce
Tento havo vyzerá zo všetkých najlepšie navrhujem ponechať.:-) A keď nie, tak mám lepší nápad: Vloži…
msx. 28.06.2006 00:27
msx.
Nechni ani domejšlet, co to má za vobláček na vocáskem... :))
Remca 28.06.2006 00:33
Remca
Aspoň vieme, že je načase vyvetrať.:-D
msx. 28.06.2006 00:38
msx.
@Kulovy:XOR EAX, EAX; { EAX := 0 --> že se našlo prd } Škoda, že niečo takéto sa nedá nájsť v resou…
msx. 28.06.2006 00:25
msx.
Kdybys viděl moje komentáře k assemblerským programům pro sálové počítače (tam je třeba komentovat s…
Rce 28.06.2006 00:29
Rce
Aspoň je človeku pri tom veselo, keď niečo programuje. Kamoš mi dal zdroják na dokončenie v Delphi.…
msx. 28.06.2006 00:37
msx.
Kdybys videl moje promenne :-D radsi nekomentovat.
virus 28.06.2006 02:27
virus

Na zadani filtru podle zacatku obsahu polozky by mela slouzit property FilterOptions:
TFilterOption = (foCaseInsensitive, foNoPartialCompare);
Takze pokud nic nevyplnis, nemel by byt filtr zavisly na velikosti pismen a mel by automaticky brat (i bez hvezdicky) zacatek retezce

Přesně tak. Zde nabízím (moji vlastní) rutinu, na porovnání řetězce s žolíky:

{-------------------------------- Porovná masku se znaky * a ? se stringem ---------------------------------------}
function StrLike (AMaska, AString: string; const ACaseSensitive: boolean = false): boolean;
{	AMaska		:= Porovnávací maska se znaky * a ?. }
{	AString		:= String k porovnání.  }
{	ACaseSensitive	:= true - pak je citlivé k velikosti písmen, false nebo nic není citlivé na velikost písmen. }
{Vrací: true jestli je shoda, false jestli není }

var	iStringu, iMasky, iKonceStringu, iKonceMasky, i, j: integer; TempString, TempMask: string;
{------------------------------------ Aby to bylo co nejrychlejší }
{$IFOPT Q+} {$DEFINE JeOwerflowCheck} {$OVERFLOWCHECKS OFF} {$ENDIF}
{$IFOPT R+} {$DEFINE JeRangeChecks}   {$RANGECHECKS OFF}    {$ENDIF}
begin
	{------------------------------- Jestli to nemá být case sensitive, tak to převést na velký písmena }
	if not ACaseSensitive then begin AString := AnsiUppercase (AString); AMaska := AnsiUppercase (AMaska) end;

	{----------------------------------- Jedeme tak dlouho, dokud není některý řetěz vyčerpán }
	iStringu := 1; iKonceStringu := length (AString); iMasky := 1; iKonceMasky := length (AMaska);
	while (iStringu <= iKonceStringu) and (iMasky <= iKonceMasky) do begin
		{------------------------ Rozskok podle znaků masky }
		case AMaska [iMasky] of
			{-------------------- Při '?' přeskočit znak stringu i masky, protože srovnání je vždy Ok }
			'?': begin inc (iStringu); inc (iMasky) end;

			{-------------------- Při '*' přeskočit '*' a najít shodu }
			'*': begin
						inc (iMasky);
						{------------- Když maska končí *, končíme taky a je to porovnané Ok... }
						if iMasky > iKonceMasky then
							iStringu := iKonceStringu + 1
						{------------- ... jinak hledat shodu }
						else begin
							TempString	:= copy (AString, iStringu, MaxInt); TempMask := copy (AMaska, iMasky, MaxInt);
							i		:= PosChar ('*', TempMask); if i = 0 then i := MaxInt; j := PosChar ('?', TempMask);
							if (j <> 0) and (j < i) then i := j;
							TempMask	:= copy (TempMask, 1, i - 1); i := pos (TempMask, TempString); if (i = 0) and (TempMask <> '') then break;
							if i <> 0 then begin inc (iStringu, i + length (TempMask) - 1); inc (iMasky, length (TempMask)) end;
						end
					 end
		{---------------------- Cokoliv jiného se musí srovnat celé a při prvním rozdílu končíme }
		else
			if AString [iStringu] = AMaska [iMasky] then begin inc (iStringu); inc (iMasky) end else break;
		end { case }
	end; { while }

	{-------------- Ok srovnání je když se to oboje stejně vyčerpalo stejně a nebo v masce zbyla '*'}
	Result := ((iStringu > iKonceStringu) and (iMasky > iKonceMasky)) or (copy (AMaska, iMasky, MaxInt) = '*');
end;
{$IFDEF JeOwerflowCheck} {$OVERFLOWCHECKS ON} {$ENDIF}
{$IFDEF JeRangeChecks}   {$RANGECHECKS ON}    {$ENDIF}

Uvnitře je použita tato funkce (možno jí nacpat dovnitř).

{------------ Pascalské POS optimalizované pro hledání 1 znaku  ---------------------}
function PosChar (const c: char; const s: string): LongInt; register; assembler;
{	c	:= Znak co hledáme }
{	s	:= Kde to hledáme  }
{Vrací (v EAX): Pozici v s (index znaku), nenalezne-li se c v s, vrací 0 }
asm
	PUSH	EDI

	MOV	EDI, s;		{ Point EDI to s       }
	CMP	EDI, 0;
	JZ	@Kulovy;	{ Řetěz je NIL, to jest prázdný }

	MOV	AL, c;		{ AL znak co hledáme   }
	MOV	ECX, -4 (EDI);	{ Délka řetězu do ECX }
	MOV	EDX, EDI;	{ Úschova ad. začátku řetězu }

	CLD;			{ SCASB pojede nahoru }
	REPNE	SCASB;
	JNE	@Kulovy;	{ Nenašlo se to }

	MOV	EAX, EDI;	{ EAX kde to skončilo + 1 }
	SUB	EAX, EDX;	{ EAX je pozice v řetězu }
	JMP	@Finish;

@Kulovy:XOR	EAX, EAX;	{ EAX := 0 --> že se našlo prd }

@Finish:POP	EDI;
end;

Já to právě třeba používám v OnFiltered. Mám ve vyhledávacích oknech (třeba adresářů) takovou funkci, že píšeš do políčka a ono to vyhledá text ať je v kterémkoliv sloupečku a kdekoliv. Filtruje to současně za psaní. Třeba víš kus jména firmy, ulici a nevíš přesně jak to v tom adresáři je. Pak se musí tato funkce použít v OnFiltered na všechny sloupce tabulky krát počet řádků. Tam je pak to pak každá instrukce navíc znát (aby to při pasní nezadrhávalo a plynule filtrovalo). Samozřejmě, když to použiješ v programu "jen občas", tak je to putna, jak je to rychlé.
//Edit: BTW tu funkci jsem dělal v době kamenné Delphi, kdy tam ještě nebyla od přírody.8-)

@Kulovy:XOR	EAX, EAX;	{ EAX := 0 --> že se našlo prd }

Škoda, že niečo takéto sa nedá nájsť v resource.:)) To by bolo dobré.:-D Spomenul som si, ako raz dávali v telke dokument, kde ukazovali chlapíkov, ktorí nerobili nič iné, len rozoberali čipy a hľadali na nich kresby. V čipe kalkulačky bol nakreslený nejaký mimozemšťan a podobne.:-)

Kdybys viděl moje komentáře k assemblerským programům pro sálové počítače (tam je třeba komentovat skoro každou instrukci, nebo se v tom nikdo za měsíc už nevyzná - třeba kompilátor Cobolu měl cca 80 000 řádek)... Když jsem odcházel na vlastní nohu, tak při předávce se místo kontroly všichni nezřízeně chechtali...

Aspoň je človeku pri tom veselo, keď niečo programuje. Kamoš mi dal zdroják na dokončenie v Delphi. Až po čase som si všimol, že tam popisoval výpočet súradníc TImage a na konci toho komentáru napísal: prije*aná matematika. Skoro som pustil od smiechu. Bolo to samozrejme bez hviezdičky.:-D

Zpět do poradny Odpovědět na původní otázku Nahoru