XClass++: inkrementelle Suche bei dsBrowseSingleChoice

Moderator: Moderatoren

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

XClass++: inkrementelle Suche bei dsBrowseSingleChoice

Beitrag von Martin Altmann »

Hallo allerseits,
ich blicke da einfach nicht durch...
Kann mir da jemand die Augen öffnen?
Ich nutze die o.g. Funktion, um Daten in einem Array zur Auswahl anzubieten!
Das positionieren auf dem vorher ausgewählten Eintrag und das Übernehmen einer neuen Auswahl in das Feld funktioniert.
Ich habe jedoch die inkrementelle Suche eingeschaltet und die funktioniert partout nicht!
Bei jeder Taste, die ich drücke, sagt er, dass er was gefunden hat, aber er positioniert den Cursor nicht auf den entsprechenden Eintrag!

Code: Alles auswählen

::_plzBrowse:init()
::title := "Postleitzahlen editieren"
::lOk := True
::EnableChildResize := True

::Connect( select() )

::oBrowse:Connect( ::Connect() )          // assign Server to browse
::oBrowse:CursorMode := XBPBRW_CURSOR_CELL
::oBrowse:EnableAppend   := .t.
::oBrowse:EnableResize   := .t.
::oBrowse:QuickEdit      := .t.
::oBrowse:EnableSearch   := .t.
::oBrowse:QuickSearch    := .t.
::oBrowse:hitTopBlock    := {|| SetStatusMessage("Erste Postleitzahl...", GRA_CLR_RED, 200, .T. )}
::oBrowse:hitBottomBlock := {|| SetStatusMessage("Letzte Postleitzahl...", GRA_CLR_RED, 200, .T. )}
::oBrowse:PreAppendBlock := {|o, n| ::PreAppendCheck(o, n)}

aFields := { "NATIONAL", "PLZ", "ORT" }
aHead := { "Nationalität", "Postleitzahl", "Ort" }

aCol := ::oBrowse:addColumnDB(aHead, aFields)

aCol[1]:CellEditType( CELL_SLE )
aCol[1]:Picture := "@!"
aCol[1]:SelectBlock := {|o| SelectNat(self, o)}
aCol[1]:PostValidate := {|oB,oC,oE| V_CheckNat(self, oB, oC, oE)}

aCol[3]:CellEditType( CELL_SLE )
aCol[3]:Picture := "!XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

::BuildMenu()
Und genau bei der o.g. Prozedur SelectNat habe ich das Problem:

Code: Alles auswählen

Procedure SelectNat(oDlg, oCell) 
LOCAL nRec

nRec := Max( ascan( MEMVAR->alaender, { |a| a[ 1 ] == alltrim( oCell:getValue() ) } ), 1 )

nRec := dsBrowseSingleChoice(oDlg, MEMVAR->alaender, ;
                   {{2, "Land", "C", 60 }, {1, "Nat.", "C", 5 }}, nRec, .T., ;
                   , .T., 650 )
	
if nRec > 0
	oCell:setData( MEMVAR->alaender[ nRec, 1 ],, .T. )
	oCell:WriteData()
endif 

RETURN
Mein Array hat insgesamt 4 Spalten, ich browse aber nur über die zweite und die erste.
Es würde mir reichen, wenn ich über die zweite Spalte des Arrays (die ja die erste im Browse ist) suchen könnte - habe auch probiert, die Arrayparameter für die Suchorder-Spalten (in der Hilfe als aOrder angegeben) mit anzugeben - aber ich werde aus der Hilfe nicht schlau!

Hat das irgendjemand von Euch in Benutzung?
Was mache ich falsch?

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
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo Martin,

mit Xclass kenne ich mich zwar nicht aus, aber diese Zeile macht mich stutzig:

Code: Alles auswählen

nRec := Max( ascan( MEMVAR->alaender, { |a| a[ 1 ] == alltrim( oCell:getValue() ) } ), 1 ) 
wenn aLaender in der ersten Spalte z.b. 3 Zeichen hat und du - so habe ich das verstanden - in oCel:getValue() den Suchbegriff nach jedem Tastendruck abfragst, also z.B. A ... Ab ... Abc um zu suchen und die passenden anzuzeigen, dann darfst du doch nicht mit == vergleichen da ja die Suchbegriffe kürzer sein können oder ?

Andererseits wird diese Funktion durch das max( ... ,1) immer einen Satz finden.

Kann natürlich sein, dass du das absichtlich so willst und ich deine Frage nicht verstanden habe ;-)
Gruß
Hubert
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Hubert,
yup - scheint so 8)
SelectNat wird aufgerufen, wenn ich beim Browsen in der Datenbank sage, dass ich bei der Nationalität eine andere auswählen will.
In dieser Funktion suche ich erstmal in meinem Array den Eintrag, der dem momentan angegebenen entspricht, um die Auswahl auf den momentanen zu setzen - falls er ungültig ist, wird der erste Eintrag vorausgewählt.
Der eigentliche Aufruf der Auswahl kommt dann eine Zeile tiefer :)
Und da funktioniert das inkrementelle Suchen leider nicht...

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
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Moin Martin,
ich nutze zwar nicht "dsBrowseSingleChoice", aber für ein xBrowse-Objeckt wird die inkrementelle Suche über ::oBrowse:SearchBlock abgewickelt.

z,B.

Code: Alles auswählen

 
::oBrowse:SearchBlock := {|oBrowse, cSeek| MySearchhUdf(oBrowse, @cSeek  ) }
Viele Grüße
Olaf
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Olaf,
yup.

Aber wenn man den SearchBlock nicht angibt, wird die interne Suche genommen - das funktioniert bei mir auch (zumindest bei anderen dsXbrowse() - aber auch nicht bei diesem dem dsBrowseSingleChoice vorgeschalteten).
In meinem SearchBlock, den ich mal probiert hatte, ist oBrowse:Data leer - ich weiß nicht, warum...

Code: Alles auswählen

FUNC DoSearch(oBrowse, cSearch)
LOCAL nPos, lRet:=.F., cSeek
	cSeek := upper(cSearch)                      

	nPos := ascan(oBrowse:Data, {|e| FWrite(nHandle, var2char(e)+CRLF), upper(e[2]) = cSeek})
	if nPos > 0
		oBrowse:Recno  := nPos        // set browse to new record
		oBrowse:RefreshAll()
		lRet := True 
	endif 
RETURN lRet
Aber wie gesagt, das hat nichts mit der dsBrowseSingleChoice zu tun - da nutzt man ja "nur" die interne inkrementelle Suche...
Aber vielleicht hast Du ja auch eine Antwort auf mein o.g. anderes Problem?
Woran kann es liegen, dass oBrowse:Data ein leeres Array ist?
Der Browse zeigt korrekt einige Tausend Zeilen an...

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
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Nun Martin, was die Funktion "FWrite(nHandle, var2char(e)+CRLF)" für einen Sinn hat, erschließt sich mir im Zusammenhang mit der Suche nicht wirklich.

Zu welchem Ergebis kommst Du, wenn Du folgende Funktion nutzt?

Code: Alles auswählen

FUNC DoSearch(oBrowse, cSearch)
LOCAL nPos
Local lRet :=.F.
Local cSeek := upper(cSearch)

IF Valtype(oBrowse:Data) == "A"
   if len(oBrowse:Data) > 0                      
        nPos := ascan(oBrowse:Data, {|e|  upper(e[2]) = cSeek})
        if nPos > 0
             oBrowse:Goto( nPos )       // set browse to new record
            lRet := True
       endif
   else
       Msgbox( "::data ist leer" ) 
else
       msgbox(":data ist kein Array")
endif

RETURN lRet

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

Beitrag von Martin Altmann »

Hallo Olaf,
sorry - den Teil hatte ich vergessen, vor dem Posten hier zu entfernen!
Ich hatte zum Debuggen (um den Fehler einzugrenzen) alles in eine Logdatei geschrieben...
Ich sehe erstmal keinen Unterschied zu meiner Funktion - kann es aber gerne gleich mal testen...

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: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Yup - wie bereits vermutet: Er gibt mir den Hinweis aus: "::data ist leer"

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
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Wenn Du mit oBrowse:connect( aDaten ) das Datenarray mit dem Bowse-Objekt verbindest, sollte eigentlich :oBrowse:data das Array "aDaten" zurückgeben.

Poste doch mal den Code für die Browse-Funktion.
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Olaf,
der Meinung war ich ja auch! Darum verstehe ich es ja auch nicht wirklich.
Den Code habe ich bereits gepostet - er steht am Anfang meines Auszuges oben.
Davor stehen nur noch (bezogen auf mein Browse) diese Zeilen:

Code: Alles auswählen

::oBrowse  := dsXBrowse():new( ::drawingArea, , {5,44}, {400,470} )
::oBrowse:caption := ""
::oBrowse:EnableFocusFrame( .f. )
::oBrowse:clipSiblings := .T.
::oBrowse:type := XBPSTATIC_TYPE_GROUPBOX
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
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Moment... Dein Browse-Objekt verbindest Du mit einer Datenbank. Dein Search-Objekt sucht jedoch in einem Datenarray. Wie paßt das zusammen?

Mit oBrowse:data erhälst Du Zugriff auf eine Array-Datenquelle, nicht auf eine Datenbank!
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Olaf,
nein! Mein Hauptbrowse geht auf eine Datenbank! Wenn ich nicht den SearchBlock angebe, wird ja (angeblich) die interne inkrementelle Suche genutzt - das funktioniert bei mir jedoch auch nicht!
Bei anderen dsXBrowse()-Aufrufen geht das - dort habe ich jedoch den Cursortype auf ROW, hier, wo es nicht geht, auf CELL!
Nehme ich den SearchBlock, geht es auch nicht!
Das Array nehme ich nur in dem Browse, der aus meinem Hauptbrowse über die Funktion dsBrowseSingleChoice() aufgerufen wird! Und dort funktioniert das Suchen auch nicht - das war meine erste Hauptfrage in diesem Thread.

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
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Die standard-inkementelle Suche funktioniert nur dann, wenn das xBrowse-Objekt mit einer Datenbank verbunden ist und berücksichtigt dabei den aktiven Index.

Wenn ich es richtig verstehe, listet dein oben gepostetes Browse-Objekt alle Einträge einer PLZ-Datenbank. Der Anwender soll die Möglichkeit haben, über die Eingabe von PLZ-(Teilnummern) auf den ersten entsprechenden Datensatz zu springen.

Dafür wäre unter oBrowse:Searchblock eine Funktion anzgeben, wenn der aktive Index nicht auf der PLZ liegt.

Mit aCol[1]:Selectblock soll mit der Auswahl einer Zelle aus der Spalte "Nationaltät" ein weitere Bowse-Objekt angezeigt werden, aus dem die Nationaltät zu einer PLZ ausgewählt werden kann.

Wenn Du nun für Dein dsBrowseSingleChoice-Objekt eine inkrementelle Suche haben möchtest, so mußt Du innerhalb von [uIncSeek] ein Such-Codeblock angeben, da die Standard-inkrementelle Suche nicht für eine Array-Datenquelle funktioniert.
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Olaf,
danke für den Hinweis mit dem Index bei der inkrementellen Suche auf der Datenbank - hatte ich gar nicht dran gedacht!
Habe mal geprüft: Mein Datenbank-Browse hat drei Spalten (National, Plz, Ort) und der Index geht auf national+plz+ort - also alle drei zusammen!
Da scheint das dann nicht zu funktionieren mit der internen, inkrementellen Suche - oder?
Wenn ich ein d eingebe, findet er nichts - obwohl es natürlich massig Einträge mit DE gibt...

Und zum "eigentlichen" Problem mit dem dsBrowseSingleChoice - hast Du da ein Beispiel?

Vielen Dank,
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
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »


Da scheint das dann nicht zu funktionieren mit der internen, inkrementellen Suche - oder?
In Deinem Fall (Standard inkrementelle Suche) nur über die Eingabe eines Nationalitäts-Buchstabens aber nicht über die PLZ.


Ein Beispiel für die dsBrowseSingleChoice-Funktion habe nicht, da ich - wie gesagt- diese Funktion nicht nutze.

Auf Basis der Funktion: dsBrowseSingleChoice([oParent], nDbf, aColumn, [nDefSelect], [uIncSeek], [aOrder], [lResize], [uSize], [cHelpKey], [aText], [bSet] )

würde ich es wie folgt machen:

Code: Alles auswählen


Procedure SelectNat(oDlg, oCell)
LOCAL nRec
Local nDbf := MEMVAR->alaender
Local aColumn := {{2, "Land", "C", 60 }, {1, "Nat.", "C", 5 }}
Local nDefSelect := Max( ascan( MEMVAR->alaender, { |a| a[ 1 ] == alltrim( oCell:getValue() ) } ), 1 )
Local uIncSeek := {{ |o, c | MySearch(o, @c) }, NIL }


nRec := dsBrowseSingleChoice(oDlg, nDbf, aColumn, nDefSelect, uIncSeek, NIL, .T., 650 )

   oCell:setData( MEMVAR->alaender[ nRec, 1 ],, .T. )
   oCell:WriteData()
endif

RETURN


FUNC MySearch(oBrowse, cSearch)
LOCAL nPos
Local lRet :=.F.
Local cSeek := upper(cSearch)

IF Valtype(oBrowse:Data) == "A"
        nPos := ascan(oBrowse:Data, {|e|  upper(e[2]) = cSeek})
        if nPos > 0
             oBrowse:Goto( nPos )       // set browse to new record
            lRet := True
       endif
endif

RETURN lRet 
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Olaf,
vielen Dank für Deine massive Unterstützung!!
Lewi hat geschrieben:In Deinem Fall (Standard inkrementelle Suche) nur über die Eingabe eines Nationalitäts-Buchstabens aber nicht über die PLZ.
nun - ich tippe ein d und die Nationalität für Deutschland (=DE) fängt auch mit D an - es wird aber nichts gefunden!
Und zum zweiten Teil: Habe ich auch probiert, klappt aber nicht!
Wahrscheinlich liegt es aber daran, dass ich mit SET EXACT ON arbeite!
Aber warum klappt dann die interne inkrementelle Suche bei einem dsXbrowse auf eine Datenbank mit einem einfachen Index (und SET EXACT ON) und im vorliegenden Fall (zusammengesetzter Index) nicht?
Wegen der Suche im Array mit der dsBrowseSingleChoice werde ich mal in der Richtung mit SET EXACT ON... was versuchen...

Vielen Dank,
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: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Olaf,
ich könnte Dich knutschen - vielen Dank!!!
Mein erstes Problem ist gelöst - so muss die MySearch() aussehen:

Code: Alles auswählen

FUNC MySearch(oBrowse, cSearch)
LOCAL nPos, lRet:=.F., cSeek, nLen
	cSeek := upper(cSearch)
	nLen := len( cSeek )
	nPos := ascan(oBrowse:Data, {|e| left( upper(e[2]), nLen ) == cSeek})
	if nPos > 0
		oBrowse:Goto( nPos )
		lRet := True 
	endif 
RETURN lRet
Jetzt klappt nur leider das interne inkrementelle Suchen beim zusammengesetzten Index noch immer nicht...

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
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Maile mir doch mal Deine PLZ-Datenbank samt INDEX-Files. Ich versuche mich dann mal an einer Lösung.

Ich habe mal probeweise aus einer Anwendung Search-Block deaktivert so das die Standardsuche greift. Das funktioniert bei mir auch über zusammendgesetzte Indizes!
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Martin Altmann hat geschrieben: nLen := len( cSeek )
nPos := ascan(oBrowse:Data, {|e| left( upper(e[2]), nLen ) == cSeek})
Hallo Martin,

das ist jetzt aber doppelt gemoppelt.

im Vergleich kürzt du auf gleiche Länge und nimmst ==
Die Arbeit mit nLen ermitteln und Kürzen könntest du dir sparen, wenn du mit = vergleichen würdest - auch wenn die Anzahl der Suchdurchläufe kaum bremsen wird. ;-)
Gruß
Hubert
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Olaf,
eine Indexdatei habe ich nicht vorliegen - die wird jedesmal neu aufgebaut und nach dem Beenden des Browse wieder gelöscht.

Code: Alles auswählen

oProgress := AppStatusbar():GetItem("ProgressBar")
oProgress:ProgressFunc := { || NIL }
oProgress:Range(1, lastrec())
oProgress:Start()
OrdCreate( quellpfad + "xxx", , "national + plz + ort", {|| iif( ( recno() % 10 ) == 0, oProgress:Advance(10), NIL), national + plz + ort })
oProgress:Stop()
Die DBF habe ich gerade an Deinen gmx-Account gemailt...

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: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Hubert,
brandelh hat geschrieben:das ist jetzt aber doppelt gemoppelt.
leider eben nicht!
Ich habe systemweit SET EXACT ON definiert (das entspricht dem ==) und somit wird ein THAILAND = T immer false liefern...

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
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Prima!


Das Problem der inkremetellen Suche für die PLZ würde ich wie folgt angehen:
1. Einen 2.ten Index auf PLZ anlegen
2. ::oBrowse:SearchBlock := {|o, c| SearchPLZUdf(o, @c) }

3:

Code: Alles auswählen

Func SearchPlzUdf( oBrowse, c)
LOCAL nRec
Local lRet:=.T.
Local nIndex := 2 // auf PLZ

if oBrowse:server:seek( c, .F., .F. @nRec, nIndex )
   oBrowse:Server:Goto( nRec )
   lRet := .T
endif
Return ( lRet )

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

Beitrag von Martin Altmann »

Hmm.
Müßte ich dann nicht zwischendurch auch einen refresh des Browses verhindern?
Wenn ich den Index wechsel, dann würden die Sätze doch in einer anderen Reihenfolge angezeigt - oder geschieht das Wechseln im Hintergrund?
Ich werde es mal versuchen...

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
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Ein Refresh ist nicht erforderlich, da mit dem 3.ten Parameter der Satzzeiger nicht bewegt wird, Die Rückgabe des entsprechenden Datensatzes erfolgt über @nRec. Die Seek-Funktion ist so aufgebaut, dass auch bei einer Suche über einen anderen als den aktiven Index keine Mitteilung an das oBrowse:server Objekt erfolgt.
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Bei 2 Indizes würde ich die inkrementelle Suche noch eleganter machen:

Code: Alles auswählen

Func SearchPlzUdf( oBrowse, c)
LOCAL nRec
Local lRet:=.T.
Local nIndex := 1 // Index für Nationaltät

if Val( c ) > 0  // Der Anwender tippt eine Zahl für eine PLZ ein
  nIndex := 2  // suche im Index PLZ 
else
  c := upper( c)  // Der Anwender tippt einen Buchstaben für ein Nationlität ein
endif
if oBrowse:server:seek( c, .F., .F. @nRec, nIndex )
   oBrowse:Server:Goto( nRec )
   lRet := .T
endif
Return ( lRet ) 
Antworten