DBSEEK - Problemas con la busqueda alfabetica

HMG en Español

Moderator: Rathinagiri

User avatar
SALINETAS24
Posts: 395
Joined: Tue Feb 27, 2018 3:06 am
DBs Used: DBF
Has thanked: 31 times
Been thanked: 29 times

DBSEEK - Problemas con la busqueda alfabetica

Post by SALINETAS24 »

Hola a todos.
Tengo un fichero con la siguiente extructura

Code: Select all


        FIELD "CUENTA"   TYPE C LEN 10
        FIELD "TITULO"   TYPE C LEN 40

y con dos indices para los dos campos.

En el MAIN tengo estas clausulas y he probado varias combinaciones.

Code: Select all

SET EXACT ON
SET SOFTSEEK OFF/ON

El caso es que cuando quiero buscar un registro hago una llamada a una función que es algo así

Code: Select all

/// ------> Busqueda del registro
nRet:=Fichero-> BuscaReg(xClave)
msgbox(nRet)

// -----------------------------------------
// Funcion para buscar registro
// -----------------------------------------

FUNC BuscaReg(cValor)
	IF !empty(cValor)
		DbSeek(cValor)
		IF FOUND()
			lRet:=1
			ELSE
			lRet:=2
		ENDIF	
	ENDIF
RETURN lRet	


Bueno, pues cuando la clave es "NUMERICA" no hay ningún problema, pero cuando es alfabética si que lo hay
Imaginaros estos registros

Reg 1 :"10 " - "EL ULTIMO DE LA FILA"
Reg 2 :"1000" - "MARIA DE LAS MERCEDES"
Reg 3 :"2 "- "DONDE VAS ALFONSO XIII"

Si hago
xClave:="129"
msgbox(BuscaReg(xClave))
Me devuelve el numero 2.., por lo que es correcto.
?? 2 // no existe..., ¡¡correcto!!

Pero el problema es cuando pongo la clave
xClave:="100"
msgbox(BuscaReg(xClave))
?? 1 // EXISTE.. ¡¡NO CORRECTO!!
Es como si funcionara por aproximación

¿Alguien ha experimentado problemas de esta índole con el DBSeek..?

Gracias y vamos con una cervecita
Como dijo el gran pensador Hommer Simpson..., - En este mundo solo hay 3 tipos de personas, los que saben contar y los que no. :shock:

franco
Posts: 404
Joined: Sat Nov 02, 2013 5:42 am
DBs Used: DBF
Been thanked: 14 times

Post by franco »

The length of xClave has to be the same length as the indexed field.
You will have to know the length of the indexed field the do some do some math in the function .
Or send xClave with padded spaces like xCalve := "100 " //+ seven spaces in the quotes.
I remember long time ago I would index on alltrim(CUENTA) this may work for you. I think the indexed lenth is now correct for set exact on.
All of the above is my old memory, I did not try.
All The Best,
Franco Bushie
Canada

User avatar
SALINETAS24
Posts: 395
Joined: Tue Feb 27, 2018 3:06 am
DBs Used: DBF
Has thanked: 31 times
Been thanked: 29 times

Post by SALINETAS24 »

Hola Franco muchas gracias, tienes razón la diferencia en la longitud puede causar errores no deseados, ya lo tenia controlado, pero he revisado el código y creo que he detectado lo que puede ser un BUG... o no .. :?:
franco wrote:
Thu Jan 23, 2020 10:54 pm
The length of xClave has to be the same length as the indexed field.
....
Estas son las líneas en cuestión de mi .prg, por si le pasa a alguien....

Code: Select all

	@ 80 ,405 TEXTBOX GET_1 WIDTH 105 VALUE aField[1] MAXLENGTH 10 FONT gFont SIZE gSize ;
		ON ENTER (aField[1]:=This.value, ;
		aField[1]:= aField[1]+SPACE(10-LEN( aField[1])) , ;
		Win_MACU.Get_1.Value:=aField[1] , ;
		nRet:=Cuentas->(BuscaReg("WIN_MaCu", This.Name,This.value,2, {1,2}, {80,300})),nil), ;
		......
Como puedes ver es un TEXTBOX que pide una cadena, una vez se pulsa ENTER se le asigna el valor introducido a un Array y este se completa hasta la longitud de 10. Después el valor de ese mismo array se devuelve al TEXTBOX y por ultimo se realiza la búsqueda con el valor introducido......, el valor del TEXTBOX a traves de "This.Value"

El problema que he detectado es que al asignar

Code: Select all

Win_MACU.Get_1.Value:=aField[1]
, se pierden todos los SPACES de la derecha :geek: Con lo cual no se pueden asignar caracteres en blanco a un TEXTBOX..., Si intercalamos

Code: Select all

aField[1]:="20",;
aField[1]:= aField[1]+SPACE(10-LEN( aField[1])) , ;
MSGBOX(LEN(aField[1]),;
Win_MACU.Get_1.Value:=aField[1] , ;
MSGBOX(LEN(Win_MACU.Get_1.Value))
El resultado que se mostrará en la pantalla MSGBOX será 10 y 2 respectivamente

la solución..., he cambiado la variable a buscar

Code: Select all

......
nRet:=Cuentas->(BuscaReg("WIN_MaCu", This.Name,aField[1],2, {1,2}, {80,300})),nil), ;
......
Osease, que cuidadin con realizar búsquedas alfabéticas sobre valores directos del TEXTBOX, se puede alterar el resultado por el tema de la longitud de la cadena.

Lo dicho.. muchas gracias y vamos con una cervecita
Como dijo el gran pensador Hommer Simpson..., - En este mundo solo hay 3 tipos de personas, los que saben contar y los que no. :shock:

franco
Posts: 404
Joined: Sat Nov 02, 2013 5:42 am
DBs Used: DBF
Been thanked: 14 times

Post by franco »

Do you know if there is a built in function in hmg to find the field the index is indexed on so later in the program you could find
the field name of the index.
Like
set index to something
cFld := getindexfield()
Now you would know the field and it`s length.
All The Best,
Franco Bushie
Canada

User avatar
AUGE_OHR
Posts: 712
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany
Has thanked: 89 times
Been thanked: 169 times

Post by AUGE_OHR »

franco wrote:
Fri Jan 24, 2020 5:36 pm
Do you know if there is a built in function in hmg to find the field the index is indexed on so later in the program you could find
the field name of the index.
Like
set index to something
cFld := getindexfield()
Now you would know the field and it`s length.
that is easy

Code: Select all

INDEXKEY()
have fun
Jimmy

User avatar
AUGE_OHR
Posts: 712
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany
Has thanked: 89 times
Been thanked: 169 times

Post by AUGE_OHR »

hi,

i´m not sure want you try to do.
if i have a INDEXKEY() over more tha 1 FIELD than these are only to "sort more"
so i only SEEK on 1st FIELD and i use TRIM()

if you want to search for something within the INDEXKEY() than i use OrdWildSeek()
you have to search for it in Forum as it seems not Part of harbour / HMG

Tip for Number in a String : i use STRZERO() instead of STR() while i can "see 0" better that " "
have fun
Jimmy

franco
Posts: 404
Joined: Sat Nov 02, 2013 5:42 am
DBs Used: DBF
Been thanked: 14 times

Post by franco »

I have used
xClave: = "100"
seek xClave
if len(alltrim(indexkey())) == len(xClave )
All The Best,
Franco Bushie
Canada

User avatar
AUGE_OHR
Posts: 712
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany
Has thanked: 89 times
Been thanked: 169 times

Post by AUGE_OHR »

franco wrote:
Sat Jan 25, 2020 5:05 pm
I have used
xClave: = "100"
seek xClave
if len(alltrim(indexkey())) == len(xClave )
so what do you want to tell me :roll:

using INDEXKEY() you get the Expression how it was create.
that include FIELD Name and ALIAS()

so what have LEN(xClave) to do with SEEK(xClave) :?:

Question : "where" do you want to use SEEK :?:

when search for a Customer Number you need "full Number" and e.g. InputBox to find him
when it is a FIELD Type "C" your "Input" must match (CASE sensitive) "left-align".

if SEEK() do not found anything it is at EOF()
when use SOFTSEEK ON it will stop after "last Match"

Code: Select all

AAA
ABC
BBB
CCC

Code: Select all

SEEK("A") -> found
SEEK("AA") -> NOT found -> EOF()

SET SOFTSEEK ON
SEEK("AA") -> NOT found but stay on -> ABC
does it help :idea:
have fun
Jimmy

franco
Posts: 404
Joined: Sat Nov 02, 2013 5:42 am
DBs Used: DBF
Been thanked: 14 times

Post by franco »

What I am saying there is no way to seek complete variable = complete field name without using if statement
fieldname = Name (character ,30) value TOM SMITH
variable = n := 'TOM'
SEEK N // I want exact but seek stops at TOM SMITH
For exact I need to add if n == alltrim(name)
could use locate but slow on large files
locate for alltrim(name) == n
WHERE YOU NEED THIS IS IN A STORE SELLING ITEMS WITH A BARCODE READER YOU NEED EXACT MATCH WE CAN NOT GET WITHOUT IF STATEMENT.
Last edited by franco on Mon Jan 27, 2020 4:57 am, edited 1 time in total.
All The Best,
Franco Bushie
Canada

User avatar
AUGE_OHR
Posts: 712
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany
Has thanked: 89 times
Been thanked: 169 times

Post by AUGE_OHR »

hi,

i begin to understand your Problem but you try to "fix" it on wrong place

you have to VALID your Entry before send it to SEEK()
you can try to use a PICTURE and test its LEN() or empty Space

---

when SEEK you can use SET EXACT ON

Code: Select all

PROCEDURE Main 

   SET EXACT OFF 

   ? "Abc"   = "Abcde"           // .F. 
   ? "Abcde" = "Abc"             // .T. 
   ? "Abc"   = ""                // .T. 
   ? ""      = "Abc"             // .F. 
   ? "Abc"   = "Abc  "           // .F. 

   SET EXACT ON 

   ? "Abc"   = "Abcde"           // .F. 
   ? "Abcde" = "Abc"             // .F. 
   ? "Abc"   = ""                // .F. 
   ? ""      = "Abc"             // .F. 
   ? "Abc"   = "Abc  "           // .T. 

                                 // using ==
   ? "Abc"  == "Abc  "           // .F. 

RETURN
as you see you still can get .T. if you don´t VALID your Entry before.
have fun
Jimmy

Post Reply