ordkeyno() in einem Scope
Moderator: Moderatoren
-
- UDF-Programmierer
- Beiträge: 88
- Registriert: Fr, 29. Jun 2007 13:32
- Wohnort: 33330 Gütersloh
- Kontaktdaten:
ordkeyno() in einem Scope
Tach auch,
in Clipper ( zumindest mit dem Comix RDD ) hat cmxkeyno() immer die Satznummer im Index in Abhängigkeit vom Scope angezeigt
also wenn ich 10.000 Datensätze habe, setzte einen Scope auf z.B. eine Kundennummer, in diesem Scope befinden sich dann z.B. nur 100 Datensätze.
In Clipper gibt mir dann cmxkeyno() für den ersten Satz im Scope 1 zurück und für den letzten eben 100
Scheinbar kann man das so in XBASE nicht machen, zumindest wird immer die Nummer bezogen auf den gesamten Index zurück gegeben.
Habe ich etwas übersehen, oder gibt es da Möglichkeiten ?
Gruß Ecki
in Clipper ( zumindest mit dem Comix RDD ) hat cmxkeyno() immer die Satznummer im Index in Abhängigkeit vom Scope angezeigt
also wenn ich 10.000 Datensätze habe, setzte einen Scope auf z.B. eine Kundennummer, in diesem Scope befinden sich dann z.B. nur 100 Datensätze.
In Clipper gibt mir dann cmxkeyno() für den ersten Satz im Scope 1 zurück und für den letzten eben 100
Scheinbar kann man das so in XBASE nicht machen, zumindest wird immer die Nummer bezogen auf den gesamten Index zurück gegeben.
Habe ich etwas übersehen, oder gibt es da Möglichkeiten ?
Gruß Ecki
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: ordkeyno() in einem Scope
Hallo, Ecki.
Ja, OrdKeyNo() ist lediglich eine Alternative zu RecNo(), mit dem Unterschied, dass ersteres die Position basierend auf dem Index zurückgibt, wobei Scopes, Relationen usw. keine Rolle spielen. Du müsstest Dir also einen Workaround bauen, der beispielsweise nach dem Setzen des Scopes alle Datensatznummern der gescopten Sätze in ein Array packt. Wenn dieses Array dann beispielsweise 100 Einträge hätte, enthielte a[50] die Datensatznummer des fünfzigsten Datensatzes innerhalb des Scopes. Diese Vorgehensweise würde die Anzeige der Datensätze vermutlich etwas verringern, aber das hat die von Dir genannte Hilfsfunktion vermutlich auch getan.
Ergänzung: Nach dem Löschen/Hinzufügen/Editieren von Datensätzen müsste "aScopeArray" jeweils neu erzeugt werden!
Ja, OrdKeyNo() ist lediglich eine Alternative zu RecNo(), mit dem Unterschied, dass ersteres die Position basierend auf dem Index zurückgibt, wobei Scopes, Relationen usw. keine Rolle spielen. Du müsstest Dir also einen Workaround bauen, der beispielsweise nach dem Setzen des Scopes alle Datensatznummern der gescopten Sätze in ein Array packt. Wenn dieses Array dann beispielsweise 100 Einträge hätte, enthielte a[50] die Datensatznummer des fünfzigsten Datensatzes innerhalb des Scopes. Diese Vorgehensweise würde die Anzeige der Datensätze vermutlich etwas verringern, aber das hat die von Dir genannte Hilfsfunktion vermutlich auch getan.
Code: Alles auswählen
aScopeArray := MySetScope(...)
FUNCTION MySetScope(..)
LOCAL aScopeArray := {}
DbSetScope(..)
DbGoTop() // eigentlich nicht erforderlich
DO WHILE !Eof()
aAdd(aScopeArray,RecNo())
DbSkip(1)
ENDDO
DbGoTop() // hier IST es erforderlich
RETURN aScopeArray
Herzlich,
Tom
Tom
- AUGE_OHR
- Marvin
- Beiträge: 12913
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: ordkeyno() in einem Scope
Xbase++ ist Cl*pper v5.2 kompatible, die "abgespeckte" COMIX Version gab es IMHO erst für v5.3xEckhard Sallermann hat geschrieben:in Clipper ( zumindest mit dem Comix RDD ) hat cmxkeyno() immer die Satznummer im Index in Abhängigkeit vom Scope angezeigt
diese schönen Functionen gibt es unter Xbase++ nicht.ORDKEYNO()
Get the logical record number of the current record
ORDKEYGOTO()
Move to a record specified by its logical record number in the controlling
ORDKEYCOUNT()
Return the number of keys in an order
wenn es 1 - 100 ist stimmt das 1:1 mit DbPosition() überein was nun der Scrollbar nutzt.Eckhard Sallermann hat geschrieben:also wenn ich 10.000 Datensätze habe, setzte einen Scope auf z.B. eine Kundennummer, in diesem Scope befinden sich dann z.B. nur 100 Datensätze.
In Clipper gibt mir dann cmxkeyno() für den ersten Satz im Scope 1 zurück und für den letzten eben 100
wenn du aber 200 Records hast , was du erst mal "feststellen" musst, wären das immer noch 100%
nur die Schrittweite bei 1 Record wäre 0.5% ...
ja GUIEckhard Sallermann hat geschrieben:Scheinbar kann man das so in XBASE nicht machen, zumindest wird immer die Nummer bezogen auf den gesamten Index zurück gegeben.
Habe ich etwas übersehen, oder gibt es da Möglichkeiten ?
nein im Ernst wenn du es nicht, so wie Tom vorgeschlagen hat, machen willst bleibt dir nur der Scrollbar.
Code: Alles auswählen
oBrowse:posBlock := {| | DbPosition()}
oBrowse:goPosBlock := {| n | DbGoPosition(n)}
gruss by OHR
Jimmy
Jimmy
-
- UDF-Programmierer
- Beiträge: 88
- Registriert: Fr, 29. Jun 2007 13:32
- Wohnort: 33330 Gütersloh
- Kontaktdaten:
Re: ordkeyno() in einem Scope
Na ja, wenn es die Funktion DbPosition() gibt, dann sollte es doch für die Entwickler eigentlich kein Problem sein, so etwas
wie cmxkeyno() zu integrieren, müsste doch machbar sein ?
p.s. ORDKEYCOUNT() lässt sich ja leicht nachbilden
wie cmxkeyno() zu integrieren, müsste doch machbar sein ?
p.s. ORDKEYCOUNT() lässt sich ja leicht nachbilden
Zuletzt geändert von Eckhard Sallermann am Do, 24. Nov 2011 8:28, insgesamt 1-mal geändert.
-
- UDF-Programmierer
- Beiträge: 88
- Registriert: Fr, 29. Jun 2007 13:32
- Wohnort: 33330 Gütersloh
- Kontaktdaten:
-
- Rekursionen-Architekt
- Beiträge: 205
- Registriert: Mo, 07. Aug 2006 10:18
- Wohnort: Leipzig
- Danksagung erhalten: 11 Mal
Re: ordkeyno() in einem Scope
Hallo Ecki,
wie Jimmy schrieb, gibt es die Funktionen ORDKEYGOTO() und ORDKEYCOUNT() in Xbase++ nicht.
Die Funktion ORDKEYNO() existiert jedoch. Und die tut ja genau das, was Du suchst: die logische
Datensatz-Nr. einer indizierten DBF-Tabelle zurückgeben (wobei auch Scopes berücksichtigt werden).
Und hier noch eine Funktion die ORDKEYCOUNT() nachbildet:
Damit sollte es ein Leichtes sein, bei Bedarf auch die Funktion ORDKEYGOTO() nachzubauen.
Beste Grüße,
Sören
wie Jimmy schrieb, gibt es die Funktionen ORDKEYGOTO() und ORDKEYCOUNT() in Xbase++ nicht.
Die Funktion ORDKEYNO() existiert jedoch. Und die tut ja genau das, was Du suchst: die logische
Datensatz-Nr. einer indizierten DBF-Tabelle zurückgeben (wobei auch Scopes berücksichtigt werden).
Und hier noch eine Funktion die ORDKEYCOUNT() nachbildet:
Code: Alles auswählen
FUNCTION OrdRecCount( ncIndex )
LOCAL cCurrentTagName
LOCAL nRec := RecNo() // aktuellen DS retten
LOCAL nRecCount := 0, nFirstRec, nLastRec
// Index-Pos. o. TagName angegeben --> diesen als kontrollierend setzen u. gleichzeitig den
// alten Index retten, um ihn spaeter wieder herzustellen
if ! Empty( ncIndex )
cCurrentTagName := OrdSetFocus( ncIndex )
endif
dbGoTop() // auf ersten (logischen) DS gehen
if !Eof()
nFirstRec := OrdKeyNo() // relative DS-Nr. des 1. DS der indizierten DB feststellen
dbGoBottom() // auf letzten (logischen) DS gehen
nLastRec := OrdKeyNo() // relative DS-Nr. des letzten DS der indizierten DB feststellen
nRecCount := ( nLastRec - nFirstRec + 1 ) // Diffz. zw. 1. und letzten DS bilden
endif
// wurde der kontrollierende Index oben verstellt, wird er hier wieder hergestellt
if cCurrentTagName != NIL
OrdSetFocus( cCurrentTagName )
endif
dbGoTo( nRec ) // aktuellen DS wieder herstellen
RETURN nRecCount
Beste Grüße,
Sören
-
- UDF-Programmierer
- Beiträge: 88
- Registriert: Fr, 29. Jun 2007 13:32
- Wohnort: 33330 Gütersloh
- Kontaktdaten:
Re: ordkeyno() in einem Scope
Hi Sören,
sorry, ich weiß zwar nicht, wie du das machst, bei mir funktioniert das leider nicht
ORDKEYNO() gibt natürlich einen Wert zurück, dieser bezieht sich aber nicht auf den
Scope, sondern auf die gesamte Datei.
p.s. dann wäre es natürlich ein leichtes Orderkeycount() nachzubilden
sorry, ich weiß zwar nicht, wie du das machst, bei mir funktioniert das leider nicht
ORDKEYNO() gibt natürlich einen Wert zurück, dieser bezieht sich aber nicht auf den
Scope, sondern auf die gesamte Datei.
p.s. dann wäre es natürlich ein leichtes Orderkeycount() nachzubilden
Sören hat geschrieben:Hallo Ecki,
wie Jimmy schrieb, gibt es die Funktionen ORDKEYGOTO() und ORDKEYCOUNT() in Xbase++ nicht.
Die Funktion ORDKEYNO() existiert jedoch. Und die tut ja genau das, was Du suchst: die logische
Datensatz-Nr. einer indizierten DBF-Tabelle zurückgeben (wobei auch Scopes berücksichtigt werden).
Und hier noch eine Funktion die ORDKEYCOUNT() nachbildet:
Damit sollte es ein Leichtes sein, bei Bedarf auch die Funktion ORDKEYGOTO() nachzubauen.Code: Alles auswählen
FUNCTION OrdRecCount( ncIndex ) LOCAL cCurrentTagName LOCAL nRec := RecNo() // aktuellen DS retten LOCAL nRecCount := 0, nFirstRec, nLastRec // Index-Pos. o. TagName angegeben --> diesen als kontrollierend setzen u. gleichzeitig den // alten Index retten, um ihn spaeter wieder herzustellen if ! Empty( ncIndex ) cCurrentTagName := OrdSetFocus( ncIndex ) endif dbGoTop() // auf ersten (logischen) DS gehen if !Eof() nFirstRec := OrdKeyNo() // relative DS-Nr. des 1. DS der indizierten DB feststellen dbGoBottom() // auf letzten (logischen) DS gehen nLastRec := OrdKeyNo() // relative DS-Nr. des letzten DS der indizierten DB feststellen nRecCount := ( nLastRec - nFirstRec + 1 ) // Diffz. zw. 1. und letzten DS bilden endif // wurde der kontrollierende Index oben verstellt, wird er hier wieder hergestellt if cCurrentTagName != NIL OrdSetFocus( cCurrentTagName ) endif dbGoTo( nRec ) // aktuellen DS wieder herstellen RETURN nRecCount
Beste Grüße,
Sören
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: ordkeyno() in einem Scope
Diese von Sören skizzierte Funktion ermittelt nur die Anzahl der Datensätze im Scope. Das hilft wenig, wenn man zum - relativ - fünfzigsten Datensatz springen will. Und auch DbPosition hilft hier nicht, weil das zwar eine relative Position zurückreicht, aber keine Handhabe für die Navigation.
Herzlich,
Tom
Tom
- brandelh
- Foren-Moderator
- Beiträge: 15706
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 70 Mal
- Danksagung erhalten: 34 Mal
- Kontaktdaten:
Re: ordkeyno() in einem Scope
Hi,
der relativ 50. Datensatz, mit oder ohne Scope, Filter oder ähnliches ?
DBSkip(50)
der relativ 50. Datensatz, mit oder ohne Scope, Filter oder ähnliches ?
DBSkip(50)
Gruß
Hubert
Hubert
-
- Rekursionen-Architekt
- Beiträge: 205
- Registriert: Mo, 07. Aug 2006 10:18
- Wohnort: Leipzig
- Danksagung erhalten: 11 Mal
Re: ordkeyno() in einem Scope
Hallo Ecki,
das ist merkwürdig, denn es funktioniert bei mir.
Ich verwende allerdings die DBFNTX-DBE und ausschließlich DbSetScope( SCOPE_BOTH, ... ).
Vielleicht hat es ja damit zu tun.
Beste Grüße,
Sören
das ist merkwürdig, denn es funktioniert bei mir.
Ich verwende allerdings die DBFNTX-DBE und ausschließlich DbSetScope( SCOPE_BOTH, ... ).
Vielleicht hat es ja damit zu tun.
Tom hat geschrieben:Diese von Sören skizzierte Funktion ermittelt nur die Anzahl der Datensätze im Scope. Das hilft wenig, wenn man zum - relativ - fünfzigsten Datensatz springen will.
Genau!Hubert hat geschrieben:DBSkip(50)
Beste Grüße,
Sören
-
- UDF-Programmierer
- Beiträge: 88
- Registriert: Fr, 29. Jun 2007 13:32
- Wohnort: 33330 Gütersloh
- Kontaktdaten:
Re: ordkeyno() in einem Scope
Sören, ich habe SCOPE_TOP und auch SCOPE_BOTH probiert, kein Erfolg.
Natürlich kann ich auch folgendermaßen vorgehen:
Scope saetzen, dann
dbgobottom()
nLastRec := ordkeyno()
dbgotop()
nFirstRec := ordkeyno()
somit habe ich die Nummer des Ersten und die des Letzten
in meiner Routine kann ich dann wie folgt die aktuelle KeyNO ermitteln
nKeyno := ordkeyno() - nFirstRec + 1
Prinzipiell nicht schlecht, allerdings braucht XBASE bei großen Dateien sehr lange, um jede einzelne ORDKEYNO() zu ermitteln,
also ist das eher eine schlechtere Lösung.
Natürlich kann ich auch folgendermaßen vorgehen:
Scope saetzen, dann
dbgobottom()
nLastRec := ordkeyno()
dbgotop()
nFirstRec := ordkeyno()
somit habe ich die Nummer des Ersten und die des Letzten
in meiner Routine kann ich dann wie folgt die aktuelle KeyNO ermitteln
nKeyno := ordkeyno() - nFirstRec + 1
Prinzipiell nicht schlecht, allerdings braucht XBASE bei großen Dateien sehr lange, um jede einzelne ORDKEYNO() zu ermitteln,
also ist das eher eine schlechtere Lösung.
Sören hat geschrieben:Hallo Ecki,
das ist merkwürdig, denn es funktioniert bei mir.
Ich verwende allerdings die DBFNTX-DBE und ausschließlich DbSetScope( SCOPE_BOTH, ... ).
Vielleicht hat es ja damit zu tun.
Tom hat geschrieben:Diese von Sören skizzierte Funktion ermittelt nur die Anzahl der Datensätze im Scope. Das hilft wenig, wenn man zum - relativ - fünfzigsten Datensatz springen will.Genau!Hubert hat geschrieben:DBSkip(50)
Beste Grüße,
Sören
- Markus Walter
- Programmier-Gott
- Beiträge: 1018
- Registriert: Di, 24. Jan 2006 10:22
- Wohnort: Saarland
Re: ordkeyno() in einem Scope
Hi,
auch hier nochmal der Hinweis, dass lt. Aussage von Alaska die Funktion ORDKEYNO() bei CDX nicht verlässlich sei (Heuristik). Sie stimmt zwar meist, aber ich hatte in der Tat mal Datenkonstellationen, wo diese Funktion völlig falsche Werte lieferte...
auch hier nochmal der Hinweis, dass lt. Aussage von Alaska die Funktion ORDKEYNO() bei CDX nicht verlässlich sei (Heuristik). Sie stimmt zwar meist, aber ich hatte in der Tat mal Datenkonstellationen, wo diese Funktion völlig falsche Werte lieferte...
Gruß
Markus
Mitglied der XUG Saarland-Pfalz
Markus
Mitglied der XUG Saarland-Pfalz
-
- UDF-Programmierer
- Beiträge: 88
- Registriert: Fr, 29. Jun 2007 13:32
- Wohnort: 33330 Gütersloh
- Kontaktdaten:
Re: ordkeyno() in einem Scope
Alles schitte
Markus Walter hat geschrieben:Hi,
auch hier nochmal der Hinweis, dass lt. Aussage von Alaska die Funktion ORDKEYNO() bei CDX nicht verlässlich sei (Heuristik). Sie stimmt zwar meist, aber ich hatte in der Tat mal Datenkonstellationen, wo diese Funktion völlig falsche Werte lieferte...
- AUGE_OHR
- Marvin
- Beiträge: 12913
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 46 Mal
Re: ordkeyno() in einem Scope
hi,
ok scheinbar ist mein Hinweis nicht angekommen, also versuche ich es "anders".das wäre in einem Browse "normal" und wäre 100%damit hätte ich eine "feiner" Auflösung von 1 : 1000
nun habe ich aber in einem Scope meistens "weniger"und damit komme ich zu Sören´s Lösung für OrdKeyCount()das Ergebnis setzt sich ja aus "Bottom" - "Top" zusammen.
Du brauchst also im Prinzip deine eigene Browse Class wo du "Top" und "Bottom" selbst verwaltest
ok scheinbar ist mein Hinweis nicht angekommen, also versuche ich es "anders".
Code: Alles auswählen
oBrowse:posBlock := {| | DbPosition()}
oBrowse:goPosBlock := {| n | DbGoPosition(n)}
Code: Alles auswählen
oBrowse:posBlock := {| | DbPosition()*10 }
oBrowse:goPosBlock := {|n| DbGoPosition(n/10) }
oBrowse:lastPosBlock := {| | 1000 }
oBrowse:firstPosBlock := {| | 0 }
nun habe ich aber in einem Scope meistens "weniger"
Code: Alles auswählen
oXbp:phyPosBlock := {| | Recno() }
oXbp:posBlock := {| | OrdKeyNo() }
oXbp:lastPosBlock := {| | LastRec() }
oXbp:firstPosBlock := {| | 1 }
Code: Alles auswählen
RETURN nRecCount
Du brauchst also im Prinzip deine eigene Browse Class wo du "Top" und "Bottom" selbst verwaltest
Code: Alles auswählen
::XbpBrowse:phyPosBlock := {| | ::recNo}
::XbpBrowse:firstPosBlock := {| | ::TopOrdKey + ::PosMyTop}
::XbpBrowse:lastPosBlock := {| | (::BottomOrdKey - ::PosMyBottom - ::TopOrdKey) +1}
::XbpBrowse:posBlock := {| o | (::OrdKeyNo - (::TopOrdKey + ::PosMyTop)) +1}
::XbpBrowse:goPosBlock := {|n, o| ::MyGoPosBlock(n)}
gruss by OHR
Jimmy
Jimmy