Set filter to Array
Moderator: Moderatoren
Set filter to Array
Guten Tag,
gibt es eine Möglichkeit eines set filter to für ein Array?
mfg
Wolfgang
gibt es eine Möglichkeit eines set filter to für ein Array?
mfg
Wolfgang
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2823
- Registriert: Fr, 08. Feb 2008 21:29
- Hat sich bedankt: 95 Mal
- Danksagung erhalten: 13 Mal
Re: Set filter to Array
Hallo, Wolfgang -
SET FILTER ist eine Anweisung, die sich auf Select()-Bereiche auswirkt.
Wenn Du beschreibst, was Du machen willst, kann man vielleicht einen workaround vorschlagen.
Gruss,
Georg
SET FILTER ist eine Anweisung, die sich auf Select()-Bereiche auswirkt.
Wenn Du beschreibst, was Du machen willst, kann man vielleicht einen workaround vorschlagen.
Gruss,
Georg
Liebe Grüsse aus der Eifel,
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Re: Set filter to Array
Ich habe ein mehrdimensionales Array und möchte da die nicht benötigten Daten löschen. Das habe ich bisher so gelöst:
das dauert bei 40000 Eintragungen ca. 4 Sekunden. Falls einen Filter für Arrays gibt geht es vielleicht schneller?
mfg
Wolfgang
Code: Alles auswählen
nlastrec=len(aArray)
for i = 1 to nlastrec
if !alltrim(mfilter)$aArray[i,2]
aRemove(aArray,i)
nlastrec=nlastrec-1
i=i-1
endif
next
mfg
Wolfgang
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2823
- Registriert: Fr, 08. Feb 2008 21:29
- Hat sich bedankt: 95 Mal
- Danksagung erhalten: 13 Mal
Re: Set filter to Array
Hallo, Wolfgang -
aus dem hohlen Bauch heraus könnte ich mir vorstellen, dass das Erzeugen eines neuen Arrays schneller gehen könnte (!) als die wiederholten aRemove(), eventuell in Verbindung mit einem AEval() (hierzu solltest Du mal in die Dokumentation reinschauen).
Gruss,
Georg
aus dem hohlen Bauch heraus könnte ich mir vorstellen, dass das Erzeugen eines neuen Arrays schneller gehen könnte (!) als die wiederholten aRemove(), eventuell in Verbindung mit einem AEval() (hierzu solltest Du mal in die Dokumentation reinschauen).
Gruss,
Georg
Liebe Grüsse aus der Eifel,
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
- AUGE_OHR
- Marvin
- Beiträge: 12903
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 44 Mal
Re: Set filter to Array
YUP ... einen "Index" verwenden für die "gelöschten"saul hat geschrieben:Ich habe ein mehrdimensionales Array und möchte da die nicht benötigten Daten löschen.
das dauert bei 40000 Eintragungen ca. 4 Sekunden. Falls einen Filter für Arrays gibt geht es vielleicht schneller?
das ist übrigens beim C:\ALASKA\XPPW32\Source\samples\basics\GuiBrow\FBROWSE.prg Demo das 5th Element.
der "Index" sortiert nun die Array Einträge und damit liegen dann die Daten in gewünschten Reihenfolge vor.
da du wohl auf aArray[i,2] aus bist (?) würde ich die 2nd Spalte so vor-sortieren
Code: Alles auswählen
// 2. Spalte absteigend sortieren
ASort( aArray,,, {|aX,aY| aX[2] > aY[2] }
Code: Alles auswählen
for i = nlastrec TO 1 STEP -1
if !alltrim(mfilter)$aArray[i,2]
aRemove(aArray,i)
nlastrec=nlastrec-1
i=i-1
ELSE
EXIT // hier kommt nichts mehr !!!
endif
next
gruss by OHR
Jimmy
Jimmy
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9345
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 100 Mal
- Danksagung erhalten: 359 Mal
- Kontaktdaten:
Re: Set filter to Array
Oder, falls das Array in einem Browse angezeigt werden soll, die Navi-Codeblöcke entsprechend ausstatten. Das ist zwar nicht faktisch schneller, kommt dem Anwender aber schneller vor.
Herzlich,
Tom
Tom
Re: Set filter to Array
Hallo,
genau das mache ich mit dem Array. Ich hatte bisher immer das Problem. dass sie Set Filter Funktion in Verbindung mit browse() im Netzwerk recht langsam ist, wenn 2 Filter gesetzt werden nunzumutbar.
Daher hatte ich, wie Du wahrscheinlich auch, eine Array anzeigen lassen. Das ging immer Ratz Fatz.
Nun habe ich eine Anwendung mit doch ca. 35000 bis 40000 Datensätzen. Da ist selbst das Array "langsam".
Das mit den Naviblöcken habe ich allerdings nicht verstanden. Jetzt nutze ich:
mfg
Wolfgang
genau das mache ich mit dem Array. Ich hatte bisher immer das Problem. dass sie Set Filter Funktion in Verbindung mit browse() im Netzwerk recht langsam ist, wenn 2 Filter gesetzt werden nunzumutbar.
Daher hatte ich, wie Du wahrscheinlich auch, eine Array anzeigen lassen. Das ging immer Ratz Fatz.
Nun habe ich eine Anwendung mit doch ca. 35000 bis 40000 Datensätzen. Da ist selbst das Array "langsam".
Das mit den Naviblöcken habe ich allerdings nicht verstanden. Jetzt nutze ich:
Code: Alles auswählen
// Navigationscodeblöcke für den Browser
oBrowseA:skipBlock := {|nSkip,oBrowseA| MySkip(nSkip,oBrowseA))
oBrowseA:goTopBlock := {| | nRecno := 1
oBrowseA:goBottomBlock := {| | nRecno := LEN(aArray) }
oBrowseA:phyPosBlock := {| | nRecno }
// Navigationscodeblöcke für den vertikalen Scrollbar
oBrowseA:posBlock := {| | nrecno }
oBrowseA:goPosBlock := {|n| DbGoPosition(n) }
* oBrowseA:goPosBlock := {|n| 50 }
oBrowseA:lastPosBlock := {| | nlastrec }
oBrowseA:firstPosBlock := {| | 1 }
FUNCTION MySkip( nSkip )
LOCAL nCanSkip
IF nRecno + nSkip < 1 // "BoF"
nCanSkip := 1 - nRecno
ELSEIF nRecno + nSkip > nLastRec // "EoF"
nCanSkip := nLastRec - nRecno
ELSE
nCanSkip := nSkip
ENDIF
nRecno += nCanSkip
RETURN nCanSkip
Wolfgang
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9345
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 100 Mal
- Danksagung erhalten: 359 Mal
- Kontaktdaten:
Re: Set filter to Array
Hallo, Wolfgang.
Das hier:
brauchst Du bei Arraybrowse-Codeblöcken nicht. Es ist ohnehin falsch, weil es "DbGoPosition" bei Arrays nicht gibt.
Um zu "filtern", musst Du einfach in Deiner Funktion "MySkip" abfangen, ob ein Array-Eintrag, zu dem "geskippt" werden soll, gemäß Filter gültig ist oder nicht. Wenn nicht, skippst Du so lange weiter, bis entweder ein solcher Eintrag erreicht wird oder eine Abbruchbedingung eintritt. In "firstPosBlock" musst Du das natürlich auch abfangen (falls der erste Eintrag ein ungültiger ist), dito bei der Bestückung von "nLastRec". Feddisch.
Das hier:
Code: Alles auswählen
oBrowseA:goPosBlock := {|n| DbGoPosition(n) }
Um zu "filtern", musst Du einfach in Deiner Funktion "MySkip" abfangen, ob ein Array-Eintrag, zu dem "geskippt" werden soll, gemäß Filter gültig ist oder nicht. Wenn nicht, skippst Du so lange weiter, bis entweder ein solcher Eintrag erreicht wird oder eine Abbruchbedingung eintritt. In "firstPosBlock" musst Du das natürlich auch abfangen (falls der erste Eintrag ein ungültiger ist), dito bei der Bestückung von "nLastRec". Feddisch.
Herzlich,
Tom
Tom
Re: Set filter to Array
Nun sitz ich ich hier ich armer Thor.
Mein Problem ist mal wieder, dass ich verstehe was da passiert. An die Funktion MySkip werden durch obrowse:skipblock 2 Variablen übergeben nSkip und ObrowseA. In der Funktion kommt aber nur eine "nSkip" an. Um jetzt dort zu filtern würde das ja bedeuten, dass alle Datensätze in der Funktion berührt werden. Bei Cursor rauf und runter kann ich mir das vorstellen, aber welchen Wert nimmt nSkip bei einem Pgdn an und wie will ich da filtern?
Was macht nRecno in diesem Zusammenhang?
Was Auge_Ohr geschrieben hat verstehe ich auch nicht ganz. Sortieren o.K., aber warum absteigend?
ASort( aArray,,, {|aX,aY| aX[2] > aY[2] } Das Beispiel habe ich auch in der Hilfe gefunden, aber was ist aX oder aY?
Weil ich das alles nicht erkenne ich es für mich sehr schwierig bestimmte Beispiele nachzuvollziehen.
Wolfgang
Code: Alles auswählen
// Navigationscodeblöcke für den Browser
oBrowseA:skipBlock := {|nSkip,oBrowseA| MySkip(nSkip,oBrowseA))
FUNCTION MySkip( nSkip )
LOCAL nCanSkip
IF nRecno + nSkip < 1 // "BoF"
nCanSkip := 1 - nRecno
TONE ( 1000 )
ELSEIF nRecno + nSkip > nLastRec // "EoF"
nCanSkip := nLastRec - nRecno
TONE ( 500 )
ELSE
nCanSkip := nSkip
ENDIF
nRecno += nCanSkip
RETURN nCanSkip
Was macht nRecno in diesem Zusammenhang?
Was Auge_Ohr geschrieben hat verstehe ich auch nicht ganz. Sortieren o.K., aber warum absteigend?
ASort( aArray,,, {|aX,aY| aX[2] > aY[2] } Das Beispiel habe ich auch in der Hilfe gefunden, aber was ist aX oder aY?
Weil ich das alles nicht erkenne ich es für mich sehr schwierig bestimmte Beispiele nachzuvollziehen.
Wolfgang
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9345
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 100 Mal
- Danksagung erhalten: 359 Mal
- Kontaktdaten:
Re: Set filter to Array
Hallo, Wolfgang.
Okay, eins nach dem anderen.
1. Auf das Browse-Objekt kannst Du in der Funktion zugreifen, indem Du dort einfach den ohnehin übergebenen Parameter nachträgst:
Damit steht "oBrowse" als Referenz auf "oBrowseA" zur Verfügung, kann manipuliert und verwendet werden. Wozu auch immer.
2. In der Funktion kommt "nSkip" an, das ist der (nominale) Wert, um den das Browse skippen will. Er ist 1, wenn zum Beispiel <Pfeil-abwärts> betätigt wird, bei <Pfeil-aufwärts> ist er
-1. Bei <Bild-auf-/abwärts> hängt es von der Größe des Browses ab, dito beim Scrollbalken. Bei einem Klick ist es die Differenz aus der alten und der neuen Browserzeile (von Zeile 5 kommend zu Zeile 2: -3). Die Funktion soll also jetzt dem Browse sagen, auf welchen Wert "nRecno" wechselt. Dafür gibt es zwei Begrenzer: 1. Den als "BoF" markierten Wert 1, der möglicherweise nicht stimmt, weil der erste Eintrag im Array nicht dem "Filter" genügt. Und "nLastRec", das den letzten Eintrag markiert, zu dem gesprungen werden darf. Du musst also die "1" für "BoF" abfangen und "nLastRec" entsprechend bestücken. Schwierig wird es jetzt bei Sprüngen ungleich eins, auch hinter der "nLastRec"-Abfrage, hauptsächlich aber beim Inkrementieren, wenn Anfangs- und Endbedingung nicht zutreffen. All das musst Du auf Deine Filterbedingung prüfen, weil der jeweilige Zieleintrag ja möglicherweise nicht passt.
3. ASort() ist eine Funktion, die ein Array bekommt ("aArray") und dieses sortiert. Hierfür werden laufend zwei Teilarrays gebildet, in diesem Fall "aX" und "aY", aber man könnte sie auch beliebig anders benennen. Sie repräsentierten jeweils eine "Zeile" im Originalarray. Für jeden Sortierungsschritt werden diese verglichen, und die Bedingung entscheidet, wie sortiert werden soll. Im vorigen Fall soll die zweite Spalte des oberen Teilarrays größer als die zweite Spalte des unteren Teilarrays sein. Einfach gesagt: Es wird nach Spalte zwei absteigend sortiert.
Ich fürchte allerdings, dass Dir all diese Erklärungen auch nicht helfen werden, schnell zu einer Lösung zu kommen.
Okay, eins nach dem anderen.
1. Auf das Browse-Objekt kannst Du in der Funktion zugreifen, indem Du dort einfach den ohnehin übergebenen Parameter nachträgst:
Code: Alles auswählen
FUNCTION MySkip( nSkip, oBrowse )
2. In der Funktion kommt "nSkip" an, das ist der (nominale) Wert, um den das Browse skippen will. Er ist 1, wenn zum Beispiel <Pfeil-abwärts> betätigt wird, bei <Pfeil-aufwärts> ist er
-1. Bei <Bild-auf-/abwärts> hängt es von der Größe des Browses ab, dito beim Scrollbalken. Bei einem Klick ist es die Differenz aus der alten und der neuen Browserzeile (von Zeile 5 kommend zu Zeile 2: -3). Die Funktion soll also jetzt dem Browse sagen, auf welchen Wert "nRecno" wechselt. Dafür gibt es zwei Begrenzer: 1. Den als "BoF" markierten Wert 1, der möglicherweise nicht stimmt, weil der erste Eintrag im Array nicht dem "Filter" genügt. Und "nLastRec", das den letzten Eintrag markiert, zu dem gesprungen werden darf. Du musst also die "1" für "BoF" abfangen und "nLastRec" entsprechend bestücken. Schwierig wird es jetzt bei Sprüngen ungleich eins, auch hinter der "nLastRec"-Abfrage, hauptsächlich aber beim Inkrementieren, wenn Anfangs- und Endbedingung nicht zutreffen. All das musst Du auf Deine Filterbedingung prüfen, weil der jeweilige Zieleintrag ja möglicherweise nicht passt.
3. ASort() ist eine Funktion, die ein Array bekommt ("aArray") und dieses sortiert. Hierfür werden laufend zwei Teilarrays gebildet, in diesem Fall "aX" und "aY", aber man könnte sie auch beliebig anders benennen. Sie repräsentierten jeweils eine "Zeile" im Originalarray. Für jeden Sortierungsschritt werden diese verglichen, und die Bedingung entscheidet, wie sortiert werden soll. Im vorigen Fall soll die zweite Spalte des oberen Teilarrays größer als die zweite Spalte des unteren Teilarrays sein. Einfach gesagt: Es wird nach Spalte zwei absteigend sortiert.
Ich fürchte allerdings, dass Dir all diese Erklärungen auch nicht helfen werden, schnell zu einer Lösung zu kommen.
Herzlich,
Tom
Tom
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9345
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 100 Mal
- Danksagung erhalten: 359 Mal
- Kontaktdaten:
Re: Set filter to Array
Ach.
Also: Du schreibst eine Funktion, die für einen Arrayeintrag prüft, ob er der "Filterbedinung" genügt. Nehmen wir an, die Bedingung sei, dass Spalte 1 eine gerade Zahl enthalten muss.
Die folgenden Ausführungen enthalten keinen besonders eleganten Code, dafür ist er vielleicht verständlich.
Vor dem Aufbau des Browses musst Du nLastRec richtig bestücken:
Außerdem musst Du eine Variable "nFirstRec" einführen und mit ihr das gleiche tun:
Damit hast Du schon drei Voraussetzungen für Deine Navigation. Die ändern wir jetzt wie folgt:
Nicht besonders schick (und ins Blaue getippt, also ungetestet), die Datenquelle ("aArray") muss PRIVATE sein, sollte aber halbwegs funktionieren. Das Array sollte allerdings mindestens einen Eintrag enthalten, der dem Filter genügt, sonst hängt das ganze in einer Endlosschleife.
Kann man, wie gesagt, alles verbessern und viel, viel eleganter machen. Geht ums Verständnis.
Also: Du schreibst eine Funktion, die für einen Arrayeintrag prüft, ob er der "Filterbedinung" genügt. Nehmen wir an, die Bedingung sei, dass Spalte 1 eine gerade Zahl enthalten muss.
Code: Alles auswählen
FUNCTION CheckArrayFilter(a)
IF Int(a[1]/2) = a[1]/2 // Spalte eins enthält eine gerade Zahl
RETURN .T.
ENDIF
RETURN .F.
Vor dem Aufbau des Browses musst Du nLastRec richtig bestücken:
Code: Alles auswählen
nLastRec := Len(aArray)
FOR n := Len(aArray) TO 1 STEP -1
IF CheckArrayFilter(aArray[n])
nLastRec := n
EXIT
ENDIF
NEXT
Code: Alles auswählen
nFirstRec := 1
FOR n := 1 TO Len(aArray)
IF CheckArrayFilter(aArray[n])
nLastRec := n
EXIT
ENDIF
NEXT
Code: Alles auswählen
FUNCTION MySkip( nSkip )
LOCAL nCanSkip
IF nRecno + nSkip < nFirstRec // "BoF"
nCanSkip := 1 - nRecno
* prüfen, ob die Filterbedingung erfüllt wird:
DO WHILE !CheckArrayFilter(aArray[nRecNo+nCanSkip))
nCanSkip ++
ENDDO
TONE ( 1000 )
ELSEIF nRecno + nSkip > nLastRec // "EoF"
nCanSkip := nLastRec - nRecno
* Filter prüfen:
DO WHILE !CheckArrayFilter(aArray[nRecNo+nCanSkip))
nCanSkip --
ENDDO
TONE ( 500 )
ELSE
nCanSkip := nSkip
IF nSkip < 0
DO WHILE !CheckArrayFilter(aArray[nRecNo+nCanSkip))
nCanSkip ++
ENDDO
ELSE
DO WHILE !CheckArrayFilter(aArray[nRecNo+nCanSkip))
nCanSkip --
ENDDO
ENDIF
ENDIF
nRecno += nCanSkip
RETURN nCanSkip
Kann man, wie gesagt, alles verbessern und viel, viel eleganter machen. Geht ums Verständnis.
Herzlich,
Tom
Tom
Re: Set filter to Array
Das ist richtig, schnell geht das nicht. Irgend wann werde ich mich ja umstellen müssen. Da ist es nicht schlecht wen man versteht was man tut.
Ich werde das alles morgen Abend mal nachvollziehen. Muß jetzt leider zur Arbeit.
mfg
Wolfgang
Ich werde das alles morgen Abend mal nachvollziehen. Muß jetzt leider zur Arbeit.
mfg
Wolfgang
Re: Set filter to Array
Guten Morgen,
es hat mir keine Ruhe gelassen und ich habe mich sofort nach meiner Arbeit wieder an den Rechner gesetzt. Im Do while Befehl hattest Du statt ]) )) gesetzt. Das gabe einen Laufzeitenfehler, den ich gefunden habe (Ich war so stolz auf mich). Da ich ein mehrdimensionales Array bearbeite, habe ich Deinen Code wenig umgebaut und eingesetzt.Diese Funktion funktioniert bei mir.
Anfang und Ende setzen funktioniert auch. Es gibt 40296 Arrayelemente
Nur mit der neuen Funktion "myskip" gibt es eine Fehlermeldung wenn ich das Programm starte, mit der alten nicht. Der Fehler muß also in dieser Funktion liegen. Daher habe ich mir die Funktion mit einigen Anzeigen erweitert. Die Ergebnisse habe ich jeweils dahintergeschrieben.Dann gibt es die Fehlermeldung. Das verstehe ich nicht, da sowohl nRecno und auch nCanskip in einem Bereich liegt, in dem es ein Arrayelement gibt.
Was bedeutet Operation "eval". Da habe ich doch keine oder?
Wo habe ich den Denkfehler?
Wolfgang
es hat mir keine Ruhe gelassen und ich habe mich sofort nach meiner Arbeit wieder an den Rechner gesetzt. Im Do while Befehl hattest Du statt ]) )) gesetzt. Das gabe einen Laufzeitenfehler, den ich gefunden habe (Ich war so stolz auf mich). Da ich ein mehrdimensionales Array bearbeite, habe ich Deinen Code wenig umgebaut und eingesetzt.
Code: Alles auswählen
FUNCTION CheckAF(FSuche,inSuche)
IF FSuche$insuche
RETURN .T.
ENDIF
RETURN .F.
Code: Alles auswählen
Suche="SB"
nFirstRec := 1 // Erster Datensatz mit der Filterbedingung bestimmen
FOR Zeilearray := 1 TO Len(aArray)
IF CheckAF(Suche,aArray[Zeilearray,2])
nFirstrec := Zeilearray
EXIT
ENDIF
NEXT
?Suche
?aArray[Zeilearray,2]
wait"1"
nLastRec := Len(aArray) // Lezten Datensatz mit der Filterbedingung bestimmen
FOR Zeilearray := Len(aArray) TO 1 STEP -1
IF CheckAF(Suche,aArray[Zeilearray,2])
nLastRec := Zeilearray
EXIT
ENDIF
NEXT
?Suche
?aArray[Zeilearray,2]
wait"2"
Nur mit der neuen Funktion "myskip" gibt es eine Fehlermeldung wenn ich das Programm starte, mit der alten nicht. Der Fehler muß also in dieser Funktion liegen. Daher habe ich mir die Funktion mit einigen Anzeigen erweitert. Die Ergebnisse habe ich jeweils dahintergeschrieben.
Code: Alles auswählen
FUNCTION MySkip( nSkip )
LOCAL nCanSkip
?nFirstrec // ist mit 22 belegt und stimmt mit dem ersten zutreffenden Arrayelement überein
wait"3"
IF nRecno + nSkip < nFirstRec // "BoF" nRecno ist der Satz auf dem der Cursor steht nSkip kann je nach Tastendruck verschiedene Werte annehmen
nCanSkip := 1 - nRecno
* prüfen, ob die Filterbedingung erfüllt wird:
?suche // Ist weiterhin die richtige Filtervariable
?nRecNo // ist 1 und für mich in Ordnung, da ich ja browse erst starte und das ganze auf dem ersten Arrayelement steht
?nCanSkip // ist 0 und für mich auch in Ordnung, da ich ja zu Anfang nicht sofort skippen will
?aArray[nRecNo+nCanSkip,2] // ist für micht o.k, zeigt mir das erste Arrayelement an, welches nicht mit dem Filter übereinstimmt
wait"4"
DO WHILE !CheckAF(Suche,aArray[nRecNo+nCanSkip,2])
nCanSkip ++
ENDDO
?nCanskip // steht auf 21, wäre richtig, da ja 22 das erste element ist welches mit dem Filter übereinstimmt
?nRecno + nCanSkip //steht auf 22, wäre ja richtig, da 22 das erste element ist welches mit dem Filter übereinstimmt
?aArray[nRecNo+nCanSkip,2] // zeigt mir das Element an, welches mit dem Filter übereinstimmt
wait"4a" // springt dann auf das Ende
TONE ( 1000 )
ELSEIF nRecno + nSkip > nLastRec // "EoF"
wait"5"
nCanSkip := nLastRec - nRecno
* Filter prüfen:
DO WHILE !CheckAF(Suche,aArray[nRecNo+nCanSkip,2])
nCanSkip --
ENDDO
TONE ( 500 )
ELSE
wait"6"
nCanSkip := nSkip
IF nSkip < 0
DO WHILE !CheckAF(Suche,aArray[nRecNo+nCanSkip,2])
* DO WHILE !CheckAF(aArray[nRecNo+nCanSkip])
nCanSkip ++
ENDDO
ELSE
DO WHILE !CheckAF(Suche,aArray[nRecNo+nCanSkip,2])
* DO WHILE !CheckAF(aArray[nRecNo+nCanSkip])
nCanSkip --
ENDDO
ENDIF
ENDIF
nRecno += nCanSkip
?nRecno // zeigt 22 an
?nCanskip // zeigt 21 an
wait"Ende"
RETURN nCanSkip
Was bedeutet Operation "eval". Da habe ich doch keine oder?
Wo habe ich den Denkfehler?
Wolfgang
- Dateianhänge
-
- Fehler.jpg (24.38 KiB) 6405 mal betrachtet
- AUGE_OHR
- Marvin
- Beiträge: 12903
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 44 Mal
Re: Set filter to Array
hi,
ich sehe viele DO WHILE Schleifen ... und das im "Skipper" ... hm ...
für ein TBrowse habe ich das mal mit einem Codeblock gemacht.es wird immer nur 1 Satz bearbeitet und danach muss er "raus" um das nächste "GoNext()" ausführen !
du darfst also nicht im "Skipper" wie wild "hin-und-her" springen sondern musst "einzeln" jede Row abarbeiten die er anzeigen soll bis der Bildschirm "voll" ist.
das kommt dann wenn er der Browser aufbauen will ... und wenn was nicht stimmt knallt er oft beim "forcestable" raus.
ich hatte ja schon mal einen "Index" vorgeschlagen wie er in C:\ALASKA\XPPW32\Source\samples\basics\GuiBrow\FBROWSE.prg zu finden ist.
du nimmst also noch ein Element in deine n-Dim Array auf für die "Sortierung" sodass "zwischendurch" keine Daten für den "Skipper" auftreten die er "nicht verwenden" kann. mit ASORT() kannst du deine Daten so "vor-sortieren" das der "Skipper" möglichst wenig Arbeit hat und das macht ihn dann "schnell".
ich sehe viele DO WHILE Schleifen ... und das im "Skipper" ... hm ...
für ein TBrowse habe ich das mal mit einem Codeblock gemacht.
Code: Alles auswählen
oTBrowse:skipBlock := { | x | GoNext( x, { || myKDNR == SOKUN->SKDNR } ) }
oTBrowse:goTopBlock := { || GoTop( { || myKDNR == SOKUN->SKDNR } ) }
oTBrowse:goBottomBlock := { || GoBottom( { || myKDNR == SOKUN->SKDNR } ) }
FUNCTION GoNext( nToSkip, bWhileCond )
LOCAL nSkipped := 0, nDirection
nDirection := IIF( nToSkip > 0, 1, - 1 )
IF LASTREC() = 0
RETURN 0
ENDIF
DO WHILE nSkipped != nToSkip .AND. EVAL( bWhileCond ) .AND. ;
! EOF() .AND. !BOF()
SKIP nDirection
nSkipped += nDirection
ENDDO
IF EOF() .OR. RECNO() == LASTREC() + 1
SKIP - 1
nSkipped --
ELSEIF BOF()
GOTO RECNO()
nSkipped ++
ELSEIF !EVAL( bWhileCond )
SKIP - nDirection
nSkipped += - nDirection
ENDIF
RETURN nSkipped
du darfst also nicht im "Skipper" wie wild "hin-und-her" springen sondern musst "einzeln" jede Row abarbeiten die er anzeigen soll bis der Bildschirm "voll" ist.
das ist in "Forcestable"Was bedeutet Operation "eval". Da habe ich doch keine oder?
das kommt dann wenn er der Browser aufbauen will ... und wenn was nicht stimmt knallt er oft beim "forcestable" raus.
ich hatte ja schon mal einen "Index" vorgeschlagen wie er in C:\ALASKA\XPPW32\Source\samples\basics\GuiBrow\FBROWSE.prg zu finden ist.
du nimmst also noch ein Element in deine n-Dim Array auf für die "Sortierung" sodass "zwischendurch" keine Daten für den "Skipper" auftreten die er "nicht verwenden" kann. mit ASORT() kannst du deine Daten so "vor-sortieren" das der "Skipper" möglichst wenig Arbeit hat und das macht ihn dann "schnell".
gruss by OHR
Jimmy
Jimmy
Re: Set filter to Array
Hallo Auge_Ohr,
Dein Vorschlag ist nicht vergessen. Ich werde den auf jeden Fall auch testen wollen. Leider habe ich nicht immer so viel Zeit wie ich zum Programmieren gern hätte. Tom hatte den Code für einen Neuling wie mich (ich kenne bisher nur Clipper, transferiert nach xbase++ in CRT FEnster ohne Objekte usw.) aufbereitet, wofür ich sehr dankbar bin. Da kann ich wenigsten vestehen warum ich was mache bzw. das Programm macht und vermeide dann beim nächsten Mal wieder Fehler.
Ich weiß, dass ein Profile das so nicht schreiben würde. Sehe es ihm bitte nach.
Sobald ich den jetzigen Versuch zum Laufen gebracht habe werde ich Deine Idee aufgreifen und diese auch mal nachvollziehen.
mfg
Wolfgang
Dein Vorschlag ist nicht vergessen. Ich werde den auf jeden Fall auch testen wollen. Leider habe ich nicht immer so viel Zeit wie ich zum Programmieren gern hätte. Tom hatte den Code für einen Neuling wie mich (ich kenne bisher nur Clipper, transferiert nach xbase++ in CRT FEnster ohne Objekte usw.) aufbereitet, wofür ich sehr dankbar bin. Da kann ich wenigsten vestehen warum ich was mache bzw. das Programm macht und vermeide dann beim nächsten Mal wieder Fehler.
Ich weiß, dass ein Profile das so nicht schreiben würde. Sehe es ihm bitte nach.
Sobald ich den jetzigen Versuch zum Laufen gebracht habe werde ich Deine Idee aufgreifen und diese auch mal nachvollziehen.
mfg
Wolfgang
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9345
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 100 Mal
- Danksagung erhalten: 359 Mal
- Kontaktdaten:
Re: Set filter to Array
Hallo, Wolfgang.
Ich würde auch nicht so programmieren; ich habe das nur gemacht, um Dir zu zeigen, was geschieht. Dieser Code lässt sich fraglos optimieren, eleganter umsetzen usw. Hatte ich ja angemerkt. Und getestet habe ich diesen Code auch nicht, sondern hier "live" geschrieben.
Der Fehler, den Du bekommst, weist darauf hin, dass letztlich in der Skip-Funktion zu einem Arrayeintrag gesprungen wird, der nicht existiert. Grundsätzlich aber sollte das so oder ähnlich funktionieren.
Ich würde auch nicht so programmieren; ich habe das nur gemacht, um Dir zu zeigen, was geschieht. Dieser Code lässt sich fraglos optimieren, eleganter umsetzen usw. Hatte ich ja angemerkt. Und getestet habe ich diesen Code auch nicht, sondern hier "live" geschrieben.
Der Fehler, den Du bekommst, weist darauf hin, dass letztlich in der Skip-Funktion zu einem Arrayeintrag gesprungen wird, der nicht existiert. Grundsätzlich aber sollte das so oder ähnlich funktionieren.
Herzlich,
Tom
Tom
Re: Set filter to Array
Hallo Tom,
genau dieser einfache Code war genau das richtige für mich. Ich werde mal weiter forschen
mfg
Wolfgang
genau dieser einfache Code war genau das richtige für mich. Ich werde mal weiter forschen
mfg
Wolfgang