Filtern von rel. grossen Datenmengen [erledigt]

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 484
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 94065 Waldkirchen
Hat sich bedankt: 14 Mal
Danksagung erhalten: 5 Mal

Filtern von rel. grossen Datenmengen [erledigt]

Beitrag von Wolfgang_B »

Hi,
bei einer meiner Kunden taucht folgendes Problem auf. Es gibt eine Tabelle mit ca. 50.000 Datensätzen (Rechnungen). Mit einem Filter
"set filter to ..." setze ich z.B. das Rechnungsjahr als Filter. Das Ergebnis sind ungefähr 10.000 Rechnungen. Das Fatale ist, daß das GO TOP nach der Filterdefinition ca. 10 Sek. dauert, dann startet erst die DO WHILE Schleife. Die gesamte Prozedur dauert ungefähr 30 Sek. Warum dauert das "GO TOP so lange?

Das Thema ist bis jetzt nicht aufgefallen, da die Tabelle noch wesentlich kleiner war.

Gibt es eine andere Methode als "SET FILTER TO... ", um eine gefilterte Menge von Datensätzen auszugeben?

Gruß Wolfgang
Zuletzt geändert von Wolfgang_B am Di, 03. Dez 2019 9:52, insgesamt 1-mal geändert.
Beste Grüße
Wolfgang

Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2824
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: Filtern von rel. grossen Datenmengen

Beitrag von georg »

Hallo, Wolfgang -


wen der Filter-Begriff als erster Schlüssel in einem Index verwendet wird, könntest Du mal dbSetScope() anschauen.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 484
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 94065 Waldkirchen
Hat sich bedankt: 14 Mal
Danksagung erhalten: 5 Mal

Re: Filtern von rel. grossen Datenmengen

Beitrag von Wolfgang_B »

Hallo Georg,

funktioniert das auch bei einem zusammengesetzen Index? Hier z.B. Rechnungsjahr+Rechnungsart+Kundennummer ..
Beste Grüße
Wolfgang

Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2824
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: Filtern von rel. grossen Datenmengen

Beitrag von georg »

Hallo, Wolfgang -


aus meiner Erfahrung: ja. Alaska empfiehlt in der Dokumentation, einen Schlüssel zu verwenden, der einen String ergibt. Dann arbeitet der dbSetScope() mit dem linken Teilstring. Einfach ausprobieren.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: Filtern von rel. grossen Datenmengen

Beitrag von AUGE_OHR »

Wolfgang_B hat geschrieben: So, 01. Dez 2019 19:56 funktioniert das auch bei einem zusammengesetzen Index? Hier z.B. Rechnungsjahr+Rechnungsart+Kundennummer ..
wenn der Index Ausdruck "so kurz" ist gibt es keine Probleme aber CDX hat z.B. eine Beschränkung auf 120 Zeichen.
bei 2 x Felder a 80 Zeichen könnten dann Probleme entstehen.

---

ich hatte es, bevor SCOPE kam, so gelöst.

Code: Alles auswählen

SEEK(cFilter)
IF FOUND()
    nRec := RECNO()
    SET FILTER TO &cFilter
    GOTO(nRec) 
gruss by OHR
Jimmy
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14651
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Filtern von rel. grossen Datenmengen

Beitrag von Jan »

Hallo Wolfgang,

Scopes sind so richtig schnell, ihc arbeite da viel mit. Nachteil gegenüber den Filtern: Die sind nicht so flexibel, oder manchmal nur mit Klimmzügen. Wenn Du nur das Rechnungsdatum brauchst, kannst Du den Index natürlich einfach auf Year(cAlias->rechnungsdatum) setzen. Wenn Du mehr brauchst mag es notwendig sein, das komplexer aufubauen. So werte ich dann z. B. den Feldinhalt aus, und setze das als .T. bzw. .F. in den Index ein. Einfach weil zwei Werte von - bis in einem Scope schlichtweg nicht gehen.

Manchmal arbeite ich auch mit SCOPE_TOP UND SCOPE_BOTTOM. Meistens mit SCOPE_BOTH, aber manchmal komme ich halt nur mit der Unterteilung weiter.

Es gibt übrigens den PDR 7226 vom 27.11.2019 der besagt, das DbSetcope() ein Memory-Leck hat. Leider hat es für November kein Update gegeben, ich hatte schon gehofft die würden das schnell fixen.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9357
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Filtern von rel. grossen Datenmengen

Beitrag von Tom »

Man kann Scopes und Filter aber auch kombinieren. Und damit kann man die meisten „unscharfen“ Situationen abdecken. 10 Sekunden bei nur 50.000 Datensätzen sind aber auch bei einem Filter zu viel. Das könnte an gelöschten Sätzen liegen. Da hilft ein gelegentliches DBPack().
Herzlich,
Tom
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14651
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Filtern von rel. grossen Datenmengen

Beitrag von Jan »

Tom,

das stimmt natürlich. Ich hatte das auch mal versucht, das hat mir aber nicht so wirklich den gewünschten Geschwindigkeitsvorteil gebracht. Deswegen bin ich dann auf die etwas komplexeren Scopes ausgewichen.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9357
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Filtern von rel. grossen Datenmengen

Beitrag von Tom »

Hallo, Jan.

Wenn man viel löscht, aber selten packt, sind konditionale Index zu empfehlen (FOR !Deleted()). Das hilft auch bei Filtern, wenn ein solcher Index führend bleibt. Scopes und Filter lassen sich sehr gut kombinieren, wenn die Scopes eine ausreichend präzise Vorauswahl treffen. Wenn ich alle Rechnungen suche, bei denen der Bemerkungentext ein bestimmtes Wort enthält, und die in einem Zeitraum zwischen x und y erzeugt worden sind, wird der Filter auf "c $ bemerkungen" nie deutlich langsamer als das Durchskippen aller Datensätze im Scope. Ein Filter auf "d >= x .and. d <= y .and. c $ bemerkungen" muss aber alle Datensätze bis zum ersten Treffer prüfen.
Ggf. kann auch SET SMARTFILTER ON ein bisschen helfen. Das bewirkt, dass sich Xbase++ die Treffer eines Filters merkt und nicht mehr auswerten muss. Manch ein Filter ist auch langsam, weil häufiger als nötig in der Tabelle navigiert wird, was dazu führt, dass die Filterausdrücke immer wieder evaluiert werden müssen. Mit Smartfilter geschieht das nur einmal, und das Workspace-Objekt merkt sich die Treffer - bis zum nächsten DbRefresh(). Funktioniert gut, und wenn nichts anderes als ein Filter geht, weil alle Anfragen zu unscharf sind oder die Benutzer ihre Abfragen völlig frei selbst bauen können, ist es das Hilfsmittel der Wahl.
Herzlich,
Tom
Benutzeravatar
Scarmo
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 188
Registriert: Di, 24. Jul 2007 9:17

Re: Filtern von rel. grossen Datenmengen

Beitrag von Scarmo »

Hallo Wolfgang

In Deinem Fall kannst Du den Filter ja einfach lassen wie er ist und statt des "GO TOP" ein "SEEK" ausführen. Aber allenfalls wäre ein sporadisches PACK wie von Tom vorgeschlagen auch eine gute Idee.

Gruss
Marco
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Filtern von rel. grossen Datenmengen

Beitrag von brandelh »

Ich habe mit dbScope() und Filter gute Erfahrungen gemacht, aber ab einer gewissen DBF Größe nudeln sich die alten Festplatten den Wolf ab.
Mit einer SSD wird es deutlich besser gehen !
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9357
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Filtern von rel. grossen Datenmengen

Beitrag von Tom »

@Marco: Ein DbSeek() vor einem DbGoTop() mit gesetztem Filter nutzt überhaupt nichts. DbGoTop() bei aktivem Filter sagt: Gehe zum Anfang der Tabelle und skippe so lange, bis die Filterbedingung zutrifft. Und zwar ganz egal, wo Du vorher stehst und ob da der Filter zufällig zutrifft oder nicht. Bei einem aktiven Scope ist das anders. Da führt ein DbGoTop() immer dazu, dass zum Anfang der Datensatzmenge gesprungen wird, auf die die Scope-Bedingung zutrifft. Wenn zusätzlich ein Filter aktiv ist, wird von dort aus weitergeskippt, bis der erste Datensatz gefunden ist, auf den außerdem die Filterbedingung zutrifft.
Herzlich,
Tom
Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 484
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 94065 Waldkirchen
Hat sich bedankt: 14 Mal
Danksagung erhalten: 5 Mal

Re: Filtern von rel. grossen Datenmengen

Beitrag von Wolfgang_B »

Erst mal danke für die Tipps ...
Was ich nach wie vor nicht verstehe ist die Tatsache, daß vom Setzen des Filters "SET FILTERS TO ..." bis zum Beginn der "DO WHILE" Schleife schon ca. 10 Sek. vergehen. Die "DO While" Schleife selber ist in 3 Sek. fertig. Nach meinem Verständnis wird doch der Filter erst in der DO WHILE-Schleife wirksam und nicht durch GO TOP??

Code: Alles auswählen

IF !net_use2("vwrech_n4",.F.,5,"Y","n1")   										
 		  MsgBox("Rechnungstabelle N1 gesperrt")
 		  DBCLOSEALL()
 		  RETURN(NIL)
	ENDIF
	SET DELETED ON
	SET INDEX TO vwremat4, vwrenr4																														 

	SET FILTER TO n1->rech_jahr == aXbp[3]:getData() .AND. ALLTRIM(n1->rech_her)	

	MsgBox("286 - LISTE_220_AUSGABE() -> Filter: "+aXbp[6]:getData() )							// TEST

  GO TOP

	oXbpSU := XbpStatic():new(oDlg:drawingArea, ,{30,90}, {500,620}   )							// Eieruhr
	oXbpSU:caption := ""
	oXbpSU:create()
	oXbpSU:setPointer(, XBPSTATIC_SYSICON_WAIT, XBPWINDOW_POINTERTYPE_SYSPOINTER)
       
	DO WHILE !EOF()
@JAN - die Eieruhr (oXbpSU) kriege ich auch nicht zum Laufen (siehe Code). Ist da was falsch oder muß ich noch was einbinden. Es tut sich jedenfalls nichts ..
Beste Grüße
Wolfgang

Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9357
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Filtern von rel. grossen Datenmengen

Beitrag von Tom »

SET FILTER (oder DbSetFilter()) macht überhaupt nichts; es wird nur die Bedingung für die Workarea etabliert. Aber fast alle Navigationsfunktionen - DbGoTop(), DbSkip(), DbGoBottom() usw. - prüfen, ob eine Filterbedingung etabliert ist und evaluieren diese. Ein Filter wird erst mit dem ersten DbGoTop() wirksam. Wenn Du in Deine DO WHILE-Schleife kommst, bist Du schon innerhalb des Filters.
Herzlich,
Tom
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2824
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: Filtern von rel. grossen Datenmengen

Beitrag von georg »

Hallo, Wolfgang -


wegen des Pointers: was gibt die Methode denn zurück? Wenn der Pointer geändert werden konnte, gibt sie .T. zurück - wenn .F. kommt, stimmt was nicht bei den Parametern, würde ich mal vermuten.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 484
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 94065 Waldkirchen
Hat sich bedankt: 14 Mal
Danksagung erhalten: 5 Mal

Re: Filtern von rel. grossen Datenmengen

Beitrag von Wolfgang_B »

hm, ich traue mich ja kaum zu fragen ... :oops:

wie frage ich denn ab was eine Methode (speziell hier) zurück gibt?
Beste Grüße
Wolfgang

Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2824
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: Filtern von rel. grossen Datenmengen

Beitrag von georg »

lSuccess := oXbp:SetPointer(...)

So würde ich das versuchen. Eine Methode ist quasi eine Funktion, die an ein Objekt gebunden ist.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9357
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Filtern von rel. grossen Datenmengen

Beitrag von Tom »

Und die Rückgabewerte von Methoden, die zu Xbase++-Klassen gehören, stehen in der Doku.

Noch einmal, damit es ankommt. Man setzt einen Filter und es passiert überhaupt nichts - die Workarea merkt sich den Filter, mehr ist nicht. Der Datensatzzeiger wird nicht bewegt, selbst wenn der aktuelle Datensatz nicht der Filterbedingung entspricht. Aber einige Kommandos bzw. Funktionen zum Navigieren prüfen bei ihrer Ausführung, ob ein Filter aktiv ist: GO TOP (DbGoTop()), SKIP (DbSkip()), GO BOTTOM (DbGoBottom())). Und die bewegen den Satzzeiger immer wieder in die jeweilige Richtung, wenn sie auf Datensätze treffen, die nicht dem Filter entsprechen. DbGoTop() also lässt den Filter aktiv werden. Der Zeiger wird auf Satz 1 gesetzt und so lange inkrementiert, bis ein Datensatz kommt, der der Bedingung entspricht. Vorher passiert nichts.

Bei SEEK (DbSeek()) oder bei GO (DbGoto()) werden Filter nicht berücksichtigt. Mit DbGoto() können nicht der Filterbedingung und auch gelöschte Datensätze angesprungen werden. Und DbSeek() ignoriert Filter ebenfalls. SET SCOPE/DbSetScope() wiederum berücksichtigt Filter - und führt implizit ein DbGoTop() aus, anders als SET FILTER/DbSetFilter()!
Herzlich,
Tom
Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 484
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 94065 Waldkirchen
Hat sich bedankt: 14 Mal
Danksagung erhalten: 5 Mal

Re: Filtern von rel. grossen Datenmengen

Beitrag von Wolfgang_B »

Tom
heißt das, dass die eigentliche Selektion schon vor "Do While" und nach "GO TOP" stattfindet?

Übrigens, bei der Tabelle sind keine gelöschten Sätze vorhanden..
Beste Grüße
Wolfgang

Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9357
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Filtern von rel. grossen Datenmengen

Beitrag von Tom »

Das "GO TOP" ist die erste Zeile, die etwas bezogen auf den Filter macht. Statt nur zum ersten Satz in der Tabelle (Ordinalposition) zu gehen, wird dort hingegangen und dann geprüft, ob der Datensatz der Filterbedingung genügt. Und dann wird so lange DbSkip(1) (oder SKIP) ausgeführt, bis ein Datensatz gefunden wird, auf den der Filter zutrifft. SET FILTER macht selbst nichts, was den Satzzeiger betrifft. Siehe Aufzählung von weiter oben. Wenn Du ein SET FILTER TO mit einer komplexen Textsuche auf einer Tabelle machst, die Milliarden von Datensätzen enthält, und erst der letzte Datensatz entspricht dem Filter, dann löst SET FILTER TO selbst trotzdem überhaupt keine Verzögerung aus. Erst DbGoTop() bewirkt das.
Herzlich,
Tom
Benutzeravatar
Scarmo
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 188
Registriert: Di, 24. Jul 2007 9:17

Re: Filtern von rel. grossen Datenmengen

Beitrag von Scarmo »

@Tom
Deshalb meinte ich SEEK statt GO TOP. So wie es aussieht werden ja z.B. alle Rechnungen eines Jahres gesucht. Und falls der Index auf das Datum bereits existiert wäre ein SEEK (dbSeek()) eben die einfachste Lösung. Ich gebe Dir aber Recht, dass unter Umständen die Scope-Variante schneller und eleganter wäre (dazu müsste man aber wissen, ob es unterschiedliche Kriterien für den Filter gibt oder immer nur einen Datums-Bereich eingegrenzt wird).
Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 484
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 94065 Waldkirchen
Hat sich bedankt: 14 Mal
Danksagung erhalten: 5 Mal

Re: Filtern von rel. grossen Datenmengen

Beitrag von Wolfgang_B »

@scarmo
Es gibt mehrere Varianten des Filters. Das Jahr war nur ein Beispiel. Es gibt z.B. den Filter Rechnungsjahr+Rechnungsart+user usw.

@Tom
Danke für die Erklärung. Ich glaube ich habe es jetzt verstanden.

@Georg
Die Methode lSuccess := oXbp:SetPointer(...) gibt .T. zurück.

Ich versuche mal DBSetScope().

Nochmal danke an alle ...
Beste Grüße
Wolfgang

Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Benutzeravatar
Wolfgang_B
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 484
Registriert: Do, 14. Jun 2007 18:22
Wohnort: 94065 Waldkirchen
Hat sich bedankt: 14 Mal
Danksagung erhalten: 5 Mal

Re: Filtern von rel. grossen Datenmengen

Beitrag von Wolfgang_B »

nochmal setpointer ...

Funktioniert doch!!! Es ist bei WIN10 nur keine Eieruhr mehr sondern ein Kringel :banghead:
Beste Grüße
Wolfgang

Mitglied des Deutschsprachigen Xbase-Entwickler e. V.
Mitglied der XUG Osnabrück
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: Filtern von rel. grossen Datenmengen

Beitrag von AUGE_OHR »

interessant was hier alles geschrieben wird.

@Wolfgang : "wo" führst du SET FILTER durch :?:

wenn ich einen FILTER in DBU (Xbase++ Version) setze steht er unter v1.9x auf dem ersten "Treffer" OHNE ein GOTOP :!:
gruss by OHR
Jimmy
Benutzeravatar
HaPe
1000 working lines a day
1000 working lines a day
Beiträge: 996
Registriert: So, 15. Nov 2015 17:44
Wohnort: 71665 Vaihingen-Enz
Hat sich bedankt: 17 Mal
Danksagung erhalten: 15 Mal

Re: Filtern von rel. grossen Datenmengen

Beitrag von HaPe »

Hallo Jimmy !
wenn ich einen FILTER in DBU (Xbase++ Version) setze steht er unter v1.9x auf dem ersten "Treffer" OHNE ein GOTOP
In der 1.9er Hilfe steht zu SET FILTER:
Nachdem eine Filterbedingung mit SET FILTER definiert worden ist, muß der Datensatzzeiger mindestens einmal bewegt werden, um sicherzustellen, daß der aktuelle Datensatz der Filterbedingung entspricht. ...
Und in der 2.0er Hilfe das Ganze in Englisch.

Das ist genau das was Tom oben schon gesagt hat; und das ist Standard bei den xbase-Sprachen wie Clipper, dBase, Xbase++, Visual Foxpro, ... =D>
--
Hans-Peter
Antworten