DbSeek( , , , [<lLast>] )

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

Moderator: Moderatoren

Antworten
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

DbSeek( , , , [<lLast>] )

Beitrag von AUGE_OHR »

hi,

angenommen folgenden Artikel Nummern (ganze Blöcke von)

Code: Alles auswählen

SET EXACT ON
DbSeek( "6404", , , .T.  ) // seek last

FELD ist Type "C", 5
"6403 "
...
"6403E"
...
"6404 "
.1
.2
"6404E"
.3
.4
"6505 "
"6505E"
bei welcher "."-Nummer sagt er FOUND() ?

gruss by OHR
Jimmy
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1930
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Rolf Ramacher »

Hallo,

ich habe es jetzt nicht ausprobiert, aber er dürfte bei keinem Found melden.
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

so wie ich das verstehe sucht er den letzten Satz, der dem Suchbegriff entspricht (probiert habe ich es nicht):

1. Aaaaa
2. Abcaa
3. Abcab
4. Abcbc
5. Acaaa
6. Baaaa

Suche nach "A" -> found() 5. Satz
Suche nach "Ab" -> found() 4. Satz
Suche nach "Abc" -> found() 4. Satz
Suche nach "Abca" -> found() 3. Satz
Suche nach "Abcc" -> ! found() eof()

Allerdings sehe ich gerade, dass du EXACT ON hast.
Dann wird es nur .t. wenn der komplette Indexbegriff abgefragt wird oder irre ich mich da ...
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Beitrag von AUGE_OHR »

hi,

schon "verwirrt" ? Lösung gefunden ?
hier noch mal eine Cl*pper Version von "DbSeekLast" die sich genau so
verhält :

Code: Alles auswählen

FUNCTION DBSEEKLAST( cString )
LOCAL cIndexKey, cIndexVal, nLen

   cIndexKey  := IndexKey(0)
   IF Empty( cIndexKey )                        // Kein Index aktiv
      RETURN .F.                                // *** RETURN  ***
   ENDIF

   nLen    := Len( cString )                    // Letzten Chr() um 1
   DbSeek( Left(cString,nLen-1) + ;             // erh”hen f
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Beitrag von AUGE_OHR »

hi,

da noch keiner dahinter gekommen ist hir nun eine Demo :

Code: Alles auswählen

PROCEDURE MAIN
LOCAL cSeek := "0050"

   CLS

   IF !FILE("TEST.DBF")
      C_TEST("TEST.DBF")
   ENDIF

   USE TEST
   INDEX ON TESTNR TO TESTNR

*1
   SET EXACT OFF
   DBSEEK(cSeek)
   ? RECNO()
*2
   SET EXACT ON
   DBSEEK(cSeek)
   ? RECNO()
*3
   SET EXACT OFF
   DBSEEK(cSeek,,,.T.)
   ? RECNO()
*4
   SET EXACT ON
   DBSEEK(cSeek,,,.T.)
   ? RECNO()
*5
   SET EXACT OFF
   DBSEEKLAST( cSeek )
   ? RECNO()
*6
   SET EXACT ON
   DBSEEKLAST( cSeek )
   ? RECNO()

   WAIT

RETURN

FUNCTION C_TEST(datei,alias,id)
LOCAL p,field_list:={}
LOCAL i

  IF VALTYPE(datei)!="C"
    datei="TEST.DBF"
  ENDIF
  IF VALTYPE(alias)!="C"
    p=at(".",datei)
    alias=if(p>0,substr(datei,1,p-1),datei)
  ENDIF
  IF VALTYPE(id)!="N"
    id=0
  ENDIF
  SELECT (id)
  IF !FILE(datei)
    AADD(field_list,{"TESTNR","C",5,0})
    DBCREATE(datei,field_list)
  ENDIF

  USE TEST
  FOR i = 1 TO 100
      APPEND BLANK
      REPLACE TESTNR WITH STRZERO(i,4)

      APPEND BLANK
      REPLACE TESTNR WITH STRZERO(i,4)+"E"
  NEXT
  CLOSE

RETURN(.t.)

FUNCTION DBSEEKLAST( cString )
LOCAL cIndexKey, cIndexVal, nLen

   cIndexKey  := IndexKey(0)
   IF Empty( cIndexKey )                        // Kein Index aktiv
      RETURN .F.                                // *** RETURN  ***
   ENDIF

   nLen    := Len( cString )                    // Letzten Chr() um 1
   DbSeek( Left(cString,nLen-1) + ;             // erh”hen f
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Jimmy,
AUGE_OHR hat geschrieben:mit verwunderlichen und IMHO falschen Ergebniss ?!
wie kommst Du darauf??
Du hast einen Indexschlüssel von 5 Zeichen Länge, suchst aber nur nach 4 Zeichen - was erwartest Du?
Gib Dir mal zusätzlich jeweils das Ergebnis von Found() mit aus - da siehst Du dann vielleicht ein wenig klarer...

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Deine Verwirrung kommt vielleicht daher, dass Du meinst, SET EXACT würde auch beim Seek Verwendung finden - dem ist aber latürnich nicht so!
EXACT kommt nur beim Vergleich von Zeichenketten zum Tragen - Du meinst sicherlich SOFTSEEK!

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

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

Beitrag von AUGE_OHR »

HI;
Martin Altmann hat geschrieben:
AUGE_OHR hat geschrieben:mit verwunderlichen und IMHO falschen Ergebniss ?!
wie kommst Du darauf??
Du hast einen Indexschlüssel von 5 Zeichen Länge, suchst aber nur nach 4 Zeichen - was erwartest Du?
Gib Dir mal zusätzlich jeweils das Ergebnis von Found() mit aus - da siehst Du dann vielleicht ein wenig klarer...
ok ich hätte den Bereicht um 0050 weiter spreizen sollen damit es noch
besser sichtbar wird wenn man das Demo laufen lässt.

Wie du richtig sagst hat cSeek 4 Zeichen. Damit ist klar das bei allen
immer FOUND() ein .T. rauskommt, oder ?!
Martin Altmann hat geschrieben: Deine Verwirrung kommt vielleicht daher, dass Du meinst, SET EXACT würde auch beim Seek Verwendung finden - dem ist aber latürnich nicht so!
EXACT kommt nur beim Vergleich von Zeichenketten zum Tragen - Du meinst sicherlich SOFTSEEK!
das EXACT hab ich eigendlich wegen des Cl*pper Code wo ich ja einen
String Vergleich habe. Das ich es überall jeweils mit ON/OFF getestet
habe diente nur der klarstellung das es nicht daran liegt. (kein Unterschied)

den SOFTSEEK hab ich hier bewust nicht verwendet um nicht noch einen
Faktor im Demo zu haben.

was ich erwartet habe : da die "0050" so nur ein mal in der DBF steht
hatte ich immer die selbe RECNO() erwartet.

gruss by OHR
Jimmy
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Beitrag von AUGE_OHR »

hi,

ich hatte noch vergessen zu sagen: bitte Demo auch mit Cl*pper vergleichen !

gruss by OHR
Jimmy
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Jimmy,
da hast Du falsch erwartet - es steht keine "0050" in der Datenbank, sondern eine "0050 "!
Mit Softseek geht es wie gewünscht.

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

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

Beitrag von AUGE_OHR »

hi,
Martin Altmann hat geschrieben: da hast Du falsch erwartet - es steht keine "0050" in der Datenbank, sondern eine "0050 "!
ja du hast Recht, aber für ein (DB)SEEK ist das völlig egal weil .T.

wenn ich einen Namen hätte mit Index und "MEI" eingeben würde
und einen "MEIer" hätte würde bei (DB)SEEK ja auch ein FOUND() = .T.
zurück geben.
Martin Altmann hat geschrieben: Mit Softseek geht es wie gewünscht.
nope es bringt keinen Unterschied in dem Beispiel.

ich habe den Bereich um "50" erweitert so das man es besserer "sehen"
kann.

Code: Alles auswählen

PROCEDURE MAIN
LOCAL cSeek := "0050"

   CLS

   IF !FILE("TEST.DBF")
      C_TEST("TEST.DBF")
   ENDIF

   USE TEST
   INDEX ON TESTNR TO TESTNR

   SET EXACT OFF
   DBSEEK(cSeek)
   ? RECNO()

   SET EXACT ON
   DBSEEK(cSeek)
   ? RECNO()

   SET EXACT OFF
   DBSEEK(cSeek,,,.T.)
   ? RECNO()

   SET EXACT ON
   DBSEEK(cSeek,,,.T.)
   ? RECNO()

   SET SOFTSEEK ON
   DBSEEK(cSeek)
   ? RECNO()

   SET SOFTSEEK OFF
   DBSEEK(cSeek)
   ? RECNO()

   SET SOFTSEEK ON
   DBSEEK(cSeek,,,.T.)
   ? RECNO()

   SET SOFTSEEK OFF
   DBSEEK(cSeek,,,.T.)
   ? RECNO()
   SET EXACT OFF
   DBSEEKLAST( cSeek )
   ? RECNO()

   SET EXACT ON
   DBSEEKLAST( cSeek )
   ? RECNO()

   SET EXACT ON
   SEEKLAST( cSeek )
   ? RECNO()

   SET EXACT OFF
   SEEKLAST( cSeek )
   ? RECNO()

   WAIT

RETURN

FUNCTION C_TEST(datei,alias,id)
LOCAL p,field_list:={}
LOCAL i

  IF VALTYPE(datei)!="C"
    datei="TEST.DBF"
  ENDIF
  IF VALTYPE(alias)!="C"
    p=at(".",datei)
    alias=if(p>0,substr(datei,1,p-1),datei)
  ENDIF
  IF VALTYPE(id)!="N"
    id=0
  ENDIF
  SELECT (id)
  IF !FILE(datei)
    AADD(field_list,{"TESTNR","C",5,0})
    DBCREATE(datei,field_list)
  ENDIF

  USE TEST
  FOR i = 1 TO 100
      APPEND BLANK
      REPLACE TESTNR WITH STRZERO(50,4)

      APPEND BLANK
      REPLACE TESTNR WITH STRZERO(50,4)+"E"
  NEXT
  CLOSE

RETURN(.t.)

FUNCTION DBSEEKLAST( cString )
LOCAL cIndexKey, cIndexVal, nLen

   cIndexKey  := IndexKey(0)
   IF Empty( cIndexKey )                        // Kein Index aktiv
      RETURN .F.                                // *** RETURN  ***
   ENDIF

   nLen    := Len( cString )                    // Letzten Chr() um 1
   DbSeek( Left(cString,nLen-1) + ;             // erh”hen f
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hi Jimmy,
AUGE_OHR hat geschrieben:was ich gerne als Ergebniss hätte wäre RECNO() = 199 (-> letzter "0050 ")
dann solltest Du auch nach "0050 " suchen und nicht nach "0050"!
Dann passt das auch.

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Koverhage »

oder PADR(cSeek,5)
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1930
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Rolf Ramacher »

Hallo,

so wie klaus das mit padr - ist richtig. du mußt beim dbseek genau identisch sein, ansonsten wenn er dann den nächsten finden soll, ist
softseek der richtige Weg
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Beitrag von AUGE_OHR »

hi,

zu den letzten 3 Beiträgen : Ja ihr habt Recht das ich so an die 199 ran
komme, aber leider nützt es mir nichts weil danach dann der SCOPE
kommt der auch die "E" anzeigen soll.

Erklärung : "4001 " ist ein 50Kg Sack Reis, "4001E" ist jetzt 1Kg Reis.
Wenn ich also 10Kg Reis verkauft habe schaue ich auf den Bestand ob
ich 10 Kg habe, wenn nein mache ich eine 50Kg Sack "4001 " auf und
entnehme 10Kg und buche 40Kg auf "4001E"

Deshalb ist mein SCOPE "4001" damit ich beides im SCOPE habe.

Nun suche ich mit DBSEEK((cSeek+chr(32)),,,.T.) bzw. DBSEEK(PADR
(cSeek,5),,,.T.) um den "letzten" 50Kg Sack Reis zu finden.

danke nochmal,
gruss by OHR
Jimmy
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Jimmy,
dann arbeite doch mit SCOPE! Den Anfang setzt Du auf "4001 " und das Ende auf "4001E"...

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Antworten