Das Forentreffen 2018 findet am 20./21. April in Dresden statt. Weitere Infos hier
Anmeldungen zum Forentreffen 2018 sind auf der Anmeldeseite möglich
Zur Homepage des Deutschsprachige Xbase-Entwickler e. V.
Xbase++-Wiki des Deutschsprachige Xbase-Entwickler e. V.

DBPOSITION ()

Zugriff, Engines, Konvertierung. Von ADS über DBF bis zu SQL.

Moderator: Moderatoren

Antworten
Statler
UDF-Programmierer
UDF-Programmierer
Beiträge: 57
Registriert: Di, 22. Jan 2008 9:49
Wohnort: Aachen

DBPOSITION ()

Beitrag von Statler » So, 12. Nov 2017 1:59

Hallo zusammen,

ich habe im Zuge des Xbase 2.0 Umstieges meine Browserklasse ueberarbeitet und speziell das Verhalten des Scrollbars optimiert. Ich bediene das Teil nun komplett selber, damit es sich so verhaelt, wie allgemein ueblich.

Bei Dateien ohne Index funktioniert alles, bei denen mit Index gibt es noch kleinere Probleme. Bei der Analyse habe ich mir die Funktion DBPOSITION () genauer angeschaut. Sie ist fehlerfaft.

Beim Hochscrollen treten negative Spruenge auf, z.B. 81 - 87 - 82. Die Prozentzahler entsprechen nicht der Satzposition. Der Algoithmus bei nicht indizierten Dateien ist auch ein wenig schraeg.

Datei mit 10 Saetzten: 0 - 20 - 30 - 40 ... 100

Bei nichtindizierten Dateien kann man das Problem selber loesen, gibt es einen Workaroend oder eine Alternative fuer indizierte Dateien ?

Gruss

Achim

georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1951
Registriert: Fr, 08. Feb 2008 21:29

Re: DBPOSITION ()

Beitrag von georg » So, 12. Nov 2017 5:10

Hallo, Achim -


schau Dir mal die Funktion ordKeyNo() an, die Du dürfte dem entsprechend, was Du suchst.
Liebe Grüsse aus der Eifel,

Georg

Statler
UDF-Programmierer
UDF-Programmierer
Beiträge: 57
Registriert: Di, 22. Jan 2008 9:49
Wohnort: Aachen

Re: DBPOSITION ()

Beitrag von Statler » Di, 14. Nov 2017 16:37

Hallo Georg,

das ist ganau das, was ich gesucht habe. Das haette ich auch selber drauf kommen koennen :D

Ich bin aktuell dabei, meine Browserklasse zu optimieren. Die nicht normgerechte Handhabung des Vertikalscrollbars hat mich schon immer gestoert. Da man unter 2.0 nun Zugriff auf das Scrollbarobjekt hat, kann man das Problem nun loesen, ohne direkt den ganzen Browser neu programmieren zu muessen.

Das eine uralte Funktion wie DBposition () fehlerhaft arbeitet, ist schon erstaunlich.

Gruss

Achim

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 10657
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: DBPOSITION ()

Beitrag von AUGE_OHR » Mi, 15. Nov 2017 6:28

Statler hat geschrieben:
So, 12. Nov 2017 1:59
... bei denen mit Index gibt es noch kleinere Probleme. Bei der Analyse habe ich mir die Funktion DBPOSITION() genauer angeschaut. Sie ist fehlerfaft.
hm ... :-k
was für ein Index Type ?
wie hast du deinen o:posBlock / o:goPosBlock bestückt ?

betr. OrdKeyNo()
DbPosition gibt ja "nur" einen Wert von 0-100 d.h. du müsste mit OrdKeyNo() die Position auf 100% berechnen.
leider gibt es kein OrdkeyCount() und schnell ist das ganze auch nicht.

wie schon gesagt ich kann das Problem mit CDX / TAG nicht feststellen. der vertikale Scrollbar läuft "ruhig" nur die RECNO() "springt"
gruss by OHR
Jimmy

Statler
UDF-Programmierer
UDF-Programmierer
Beiträge: 57
Registriert: Di, 22. Jan 2008 9:49
Wohnort: Aachen

Re: DBPOSITION ()

Beitrag von Statler » Mi, 15. Nov 2017 14:43

Hallo,

>was für ein Index Type ?
ntx

>wie hast du deinen o:posBlock / o:goPosBlock bestückt ?
DBPOSITION () ohne alles

wie gesagt, wenn ich eine Datei mit z.B. 1000 Saetzen durchsteppe, tretem hin und wieder Spruenge auf. Ein Reindex bringt nichts. Das ist reproduzierbar und tritt bei mehreren Dateien auf.

o:goPosBlock hat damit erst mal nichts zu tun. Der kommt nur zum tragen, wenn man die Scrollbox verschiebt.

Da ich nicht mit bedingter Indizierung arbeite, ist Reccount () fuer mich Ok, ansonsten koennte man mit DbGoBottom () und OrdKeyNo () die effektive dateigroesse berechnen, natuerlich nur gezielt bei Aenderungen

Gruss

PS: wenn ich meinen Kram fertig habe, werde ich die Erkenntnisse mal zusammenstellen und hier posten.

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 10657
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: DBPOSITION ()

Beitrag von AUGE_OHR » Mi, 15. Nov 2017 22:12

habe es nun mal mit NTX versucht und auch dort kann ich dein Problem NICHT nachvollziehen [-X
es gibt auch keine PDR ... also tippe ich darauf das mit deinen Callback Slots was nicht stimmt.

Code: Alles auswählen

   oBrowse:skipBlock     := { | n | DbSkipper( n ) }
   oBrowse:goTopBlock    := { | | DBGOTOP() }
   oBrowse:goBottomBlock := { | | DBGOBOTTOM() }
   oBrowse:phyPosBlock   := { | | RECNO() }

   oBrowse:posBlock      := { | | DbPosition() * 10 }
   oBrowse:goPosBlock    := { | n | DbGoPosition( n / 10 ) }
   oBrowse:lastPosBlock  := { | | 1000 }
   oBrowse:firstPosBlock := { | | 0 }
gruss by OHR
Jimmy

Statler
UDF-Programmierer
UDF-Programmierer
Beiträge: 57
Registriert: Di, 22. Jan 2008 9:49
Wohnort: Aachen

Re: DBPOSITION ()

Beitrag von Statler » Do, 16. Nov 2017 19:45

Hallo,

hier das ganze mal ohne Browser, ganz klar ein Fehler. Der Index ist sehr einfach, ein Feld. das tritt mehrfach in diversen Dateien auf, immer klar reproduzierbar.

Code: Alles auswählen

SK_XXXX->(DBGOTO (44))

FOR nCounter:= 1 TO 15
   DEBUGOUT (STR (SK_XXXX->(RECNO ()), 4)+" - "+STR (SK_XXXX->(DBPOSITION ()), 3)+"%")
   *
   SK_XXXX->(DBSKIP ())
NEXT nCounter
Dateianhänge
screenshot.gif
screenshot.gif (11.55 KiB) 116 mal betrachtet

Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 13811
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Kontaktdaten:

Re: DBPOSITION ()

Beitrag von brandelh » Fr, 17. Nov 2017 7:08

hier wäre es wichtig, die genaue Xbase++ Version anzugeben.
Ich meine es gab da einige PDR zu dem Thema.

Wenn man die Testdaten (gemischter Inhalt, 1000 Datensätze) mit PRG (ohne DLL bzw. EXE) als ZIP anhängen würde, könnte ich mit der aktuellen 1.90.355 und 2.00.840 testen.
Gruß
Hubert

Statler
UDF-Programmierer
UDF-Programmierer
Beiträge: 57
Registriert: Di, 22. Jan 2008 9:49
Wohnort: Aachen

Re: DBPOSITION ()

Beitrag von Statler » Fr, 17. Nov 2017 8:50

Hallo,

das ist bei 1.9 genaus so. Mich stoert das eigentlich schon ewig, das der Scrollbar nicht sauber mitgefuehrt wird, wenn man mit der Tastatur arbeitet ...

Als Programmcode kannst Du die 5 Zeilen aus dem Beispiel nehmen. In der Datei gibt es mehrere Stellen, an denen Spruenge auftreten

Gruss
Dateianhänge
TestDaten.zip
s_2017.dbf, SK_2017a.ntx
(32.48 KiB) 2-mal heruntergeladen

Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 13811
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Kontaktdaten:

Re: DBPOSITION ()

Beitrag von brandelh » Fr, 17. Nov 2017 9:26

Hallo,

ich habe deine Datei mit diesem Testprogramm mit 2.00.840 und 1.90.355 (inkl. aller Hotfix-Dateien) getestet.

Code: Alles auswählen

procedure main
   field SK
   local cXbaseVer := version(1)+"."+version(2)+"."+version(3)

   set alternate to ("test-"+cXbaseVer+".txt")
   set alternate on

   use SK_2017 exclusive

   ? "Testdatei geöffnet: ",used(),Alias(), "   LastRec(): ",lastrec()
   ?
   ? "Xbase++ Version",version(), "  ("+cXbaseVer+")"
   ?
   ? "DBPOSITION() ohne Index"
   ?
   dbGoTop()

   do while ! eof()
      ? field->SK, recno(), DbPosition()
      dbskip()
   enddo
   ? "-----------------------------------------------------------"
   ?
   ? "Index auf SK aufbauen ..."
   index on SK to (alias())

   ?
   ? "DBPOSITION() mit Index"
   ?

   dbGoTop()

   do while ! eof()
      ? field->SK, recno(), DbPosition()
      dbskip()
   enddo
   ? "-----------------------------------------------------------"

   DbSetOrder( 0 )

   ?
   ? "DBPOSITION() mit Index aber ohne Sortierung ! "
   ?

   dbGoTop()

   do while ! eof()
      ? field->SK, recno(), DbPosition()
      dbskip()
   enddo

   ?
   ? "Ende"
   ?

   set alternate to

   inkey(5)

return
und habe genau die Ergebnisse erhalten die ich erwartet habe !
ohne Index wird Recno() um 1 erhöht und dbPosition() läuft von 0.00 bis 100.00 % durch
mit aktivem Index springt Recno() wild herum, aber dbPosition() läuft immer noch von 0.00 bis 100.00 % durch !

Und genau das ist ja der Sinn von dbPosition() ... aktueller Datensatz in der Sortierung als Prozentwert von 0 bis 100 anzeigen.

Der einzige Unterschied zwischen der 1.90 und der 2.00 ist die Anzeige des Prozentwertes, 1.90 hat 2 Nachkommastellen, 2.00 hat derer 10 - vermutlich aber nur eine Änderung der Anzeige.
Für den Browser Verlaufbalken reichen beide Werte locker aus, dein Problem muss wo anders liegen.
Dateianhänge
TestDBPosition.zip
(100.7 KiB) 1-mal heruntergeladen
Gruß
Hubert

Statler
UDF-Programmierer
UDF-Programmierer
Beiträge: 57
Registriert: Di, 22. Jan 2008 9:49
Wohnort: Aachen

Re: DBPOSITION ()

Beitrag von Statler » Fr, 17. Nov 2017 10:08

Hallo,

ich habe nochmal eine kleine Testroutine direkt am Programmstart gesetzt. Dort wird der Index neu aufgebaut.

Code: Alles auswählen

USE SK_2017.dbf ALIAS SK_XXXX
INDEX ON SK TO ("sk_XXXX")
*
SK_XXXX->(DBGOTO (44))
FOR nCounter:= 1 TO 15
   DEBUGOUT (STR (SK_XXXX->(RECNO ()), 4)+" - "+STR (SK_XXXX->(DBPOSITION ()), 3)+"%")
   *
   SK_XXXX->(DBSKIP ())
NEXT nCounter

USE
Keinerlei Veraenderung, siehe Screenshot aus vorherigem Post. das kann also nur mit den globalen Einstellungen zu tun haben.

Gruss

Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 13811
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Kontaktdaten:

Re: DBPOSITION ()

Beitrag von brandelh » Fr, 17. Nov 2017 10:46

Ich bestätige, dass ein Satz in der Reihe (auch in meiner Datei) statt größer etwas kleiner wird, aber das sind nur 1 % ...

Wenn deine Variablen im Browser sauber eingestellt sind, dürfte dbGoPosition() lediglich mit Steuerung per Maus in der Scrollbar verwendet werden.
Mit dem Keyboard wird immer direkt auf dbSkip() über den skipblock zugegriffen.
Jimmy hat da ja code gezeigt oben, in der Hilfe steht das drinn:

Code: Alles auswählen

oBrowse := XbpBrowse():new( oParent,, aPos, aSize ):create()

      // Navigation code blocks for the browser   
      oBrowse:skipBlock     := {|n| DbSkipper(n) }
      oBrowse:goTopBlock    := {| | DbGoTop()    }
      oBrowse:goBottomBlock := {| | DbGoBottom() }
      oBrowse:phyPosBlock   := {| | Recno()      }
      oBrowse:goPhyPosBlock := {|n| DbGoto(n)    }

      // Navigation code blocks for the vertical scroll bar
      oBrowse:posBlock      := {| | DbPosition()    }
      oBrowse:goPosBlock    := {|n| DbGoPosition(n) }
      oBrowse:lastPosBlock  := {| | 100             }
      oBrowse:firstPosBlock := {| | 0               }
aber nochmal, oBrowse:goPosBlock := {|n| DbGoPosition(n) } wird nur verwendet wenn die Scrollbar verwendet wird.
Ich würde da auch keine * 10 und / 10 Operationen wie Jimmy verwenden, sondern gleich 0 bis 100
Gruß
Hubert

Statler
UDF-Programmierer
UDF-Programmierer
Beiträge: 57
Registriert: Di, 22. Jan 2008 9:49
Wohnort: Aachen

Re: DBPOSITION ()

Beitrag von Statler » Fr, 17. Nov 2017 11:41

Hallo,

>Ich bestätige, dass ein Satz in der Reihe (auch in meiner Datei) statt größer etwas kleiner wird, aber das sind nur 1 % ...
in meinem Beispiel waren es 2% Punkte ...

Damit steht alsoe fest, das DBposition () fehlerhaft ist.

>aber nochmal, oBrowse:goPosBlock := {|n| DbGoPosition(n) } wird nur verwendet wenn die Scrollbar verwendet wird.
hier geht es nicht um DbGoPosition(n) sondern um DbPosition(). Mit Dbposition wird die Position des ScrollBars in Abhaengigkeit des Satzeigers berechnet. Wenn dessen Werte springen, springt auch der Scrollbar.

Die Handhabung des ScrollBars ist bei den Default Browsern von Xbase meiner Meinung nach nicht korrekt:

So sollte es sein:

Die Groesse der Box sollte prozentual den Bereich repraesentieren, der Sichtbar ist bezogen auf die Datei.
Die Position Der Box sollte prozentual zu dem sichtbaren Ausschnit bezogen auf die Datei passen
sehe ich die komplette Datei im Ausschnitt, sollte die Box 100% belegen und damit unbeweglich sein.

Wenn ich also den Cursor innerhalb des sichtbaren Ausschnittes neu setzte, sollte sich die Box nicht bewegen, erst wenn Saetze nach oben bzw. unten rausgeschoben werden, sollte sich die Box wieder bewegen.

So machen das andere Windows Programme, Xbase hingegen nicht. Ich habe das mittlerweile fast hinbekommen, Voraussetzung ist aber, das DBposition() exacte Ergebnisse liefert. Das ist aktuell noch mein letztes Problem.

Meine Browser haben immer einen sichtbaren Cursor, man kann den Cursor nicht aus dem sichtbaren Bereich schieben. Ohne Cursor muesste man wissen, welcher Satz sich in der obersten bzw. der untersten Reihe des Browsers befindet. Nur so kann man die Position der Box bestimmen. Das laesst sich aber nicht so ohne weiteres herausfinden. Da ich aktuell keine Browser benoetige, die den Cursor aus dem sichtbaren Bereich schieben, stellt sich das Problem nicht.

Ist der Cursor verschwunden, geht ::rowPos auf 0 und ::rowPhyPos auf 1 bzw. ::rowCount, je nach Schieberichtung. Daraus liesse sich bestimmt was machen ...

Gruss

PS: das sieht jetzt alles nach ein wenig "Korinthenkackerei" aus, aber wenn ich solche elementaren Klassen, die nun schon ueber 10 Jahre laufen, anpacke, dann ziehe ich das bis zum bitteren Ende durch, das soll dann wieder 10 Jahre halten :D

Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2307
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin
Kontaktdaten:

Re: DBPOSITION ()

Beitrag von Wolfgang Ciriack » Fr, 17. Nov 2017 13:59

Wenn ich also den Cursor innerhalb des sichtbaren Ausschnittes neu setzte, sollte sich die Box nicht bewegen, erst wenn Saetze nach oben bzw. unten rausgeschoben werden, sollte sich die Box wieder bewegen.
Hast du das mal bei der 2.0 mit XBPBRW_NAVIGATION_SYSTEM probiert ? Sollte da eigentlich gegenüber 1.9, bei der XBPBRW_NAVIGATION_1XCOMPATIBLE Standard ist, so funktionieren.
Viele Grüße
Wolfgang

Statler
UDF-Programmierer
UDF-Programmierer
Beiträge: 57
Registriert: Di, 22. Jan 2008 9:49
Wohnort: Aachen

Re: DBPOSITION ()

Beitrag von Statler » Sa, 18. Nov 2017 20:13

Hallo zusammen,

Code: Alles auswählen

IF (::xDataLink)->(INDEXORD ()) == 0
   nPosition:= IIF (EVAL (::reccountBlock) < 2, 100 * EVAL (::reccountBlock ), 100 * ((::xDataLink)->(RECNO ())    - 1) / (EVAL (::reccountBlock) - 1))
ELSE
   nPosition:= IIF (EVAL (::reccountBlock) < 2, 100 * EVAL (::reccountBlock ), 100 * ((::xDataLink)->(ORDKEYNO ()) - 1) / (EVAL (::reccountBlock) - 1))
ENDIF
*
RETURN (nPosition)
Funktioniert natuerlich nur bei "normaler" Indizierung. Der Dbposition () hat am Anfang einen Sprung, Record 1 ergibt 0, danach geht es dann mit 2/reccount () weiter, was natuerlich streng genommen falsch ist.

record/DpPosition/korrekt
01 = 0 -> 0
02 = 20 -> 11,11
03 = 30 -> 22,22
04 = 40 -> 33,33
05 = 50 -> 44,44
06 = 60 -> 55,55
07 = 70 -> 66,66
08 = 80 -> 77,77
09 = 90 -> 88,88
10 = 100 -> 100

Mit dieser Funktion laeuft mein Scrollbar nun sauber

Bei Dateigroesse 1 wird 100% zurueckgegeben, bei Null 0, ansonsten 0 - 100%


Gruss

Antworten