Page 1 of 1

como se podrá identificar un numero X dentro un registro?

Posted: Sat Nov 17, 2012 12:32 am
by AIDA
Hola otra gran pregunta de la mas latosa y preguntona osea YO ! :mrgreen:

en unas DBF tienen registrados nombres de archivos como el siguiente: P_000000000001_vida_17_0064951A_0_00000000_05112012_754_607816_604971_F_05112012_1440471.pdf

como puedo leer el nombre de ese registro en una búsqueda incremental hasta que salga el que estoy tecleando por ejemplo 0064951A un numero que es parte del nombre de ese registro

Gracias por todo :)

Saluditos :wink:

Re: como se podrá identificar un numero X dentro un registro?

Posted: Sat Nov 17, 2012 3:38 am
by ricardog
Aida, buenas noches.

Este ejemplo lo saque de aquí del foro, no recuerdo quien es el autor.

(esta adaptado mi libreria, para manejar las tablas como objetos).

Espero te ayude.

OJO, OCUPAS UN INDICE EN LA TABLA, QUE ESTE ORDENADO POR _ (alfanumericos solamente), POR LOS CUALES
DESEAS HACER LA BUSQUEDA. (yo le llame "portodo", al bag del indice).

Code: Select all

/* --------------------------------------------------------------------------------------------------
       Funcion para hacer busquedas estilo LIKE de SQL
       -------------------------------------------------------------------------------------------------- */
 STATIC Function BuscaLike(t,m)
       local oDlg, oBtns[2], oSay[2], oGets[3], aGets[3], oBrw, xFind:='',;
           lContinuar:=.F.,aDatos:={{"","","","",0}}, n:=0

           aGets[1]:=Space(40)

         DEFINE DIALOG oDlg RESOURCE "BUSQUEDAS" TITLE "Busquedas de Articulos"
             oDlg:lHelpIcon:=.F.

             REDEFINE GET oGets[01]  VAR aGets[1]  ID 101 OF oDlg UPDATE ;
                               PICTURE "@!K" ;
                               ON CHANGE ( oGets[01]:Assign() ,;
                                           xFind:=Alltrim(aGets[1]),;
                                           aDatos:=SacaInf(t , SubStr( aGets[1],1,Len(xFind) ) ),;
                                           Eval(oBrw:bGotFocus),;
                                           oBrw:Refresh() )
                               oGets[01]:cToolTip := "Digite el Id, Código de barras, Nombre, Modelo"

             REDEFINE LISTBOX oBrw FIELDS ;
                                    aDatos[oBrw:nAt,01],;
                                    aDatos[oBrw:nAt,02],;
                                    aDatos[oBrw:nAt,03],;
                                    aDatos[oBrw:nAt,04] ;
                              HEADERS "Id","Nombre","RFC","Teléfono" ;
                              SIZES 60,230,100,90;
                              ID 300 OF oDlg UPDATE
                              oBrw:SetArray( aDatos )
                              oBrw:bGotFocus    := { || oBrw:SetArray( aDatos ),oBrw:Refresh() }
                              oBrw:nLineStyle   := 6
                              oBrw:aJustify:={.F.,.F.,.F.,.F. }

              REDEFINE BUTTON ID 400 OF oDlg CANCEL;
                       ACTION (lContinuar:=.T.,;
                               n:=aDatos[oBrw:nAt,5],oDlg:End() );
                       WHEN !Empty(aDatos[1,1])

              REDEFINE BUTTON ID 401 OF oDlg CANCEL;
                       ACTION (oDlg:End() )

         ACTIVATE DIALOG oDlg CENTERED

       If lContinuar
         If n>0
           (t:nArea)->(OrdSetFocus(2))
           (t:nArea)->(dbgoto(n))
           t:load()
           _mClientes(t,1,.T.,m)
         EndIf
       Endif

 Return Nil

 Static Function SacaInf(t,cCadena)
    local xDatos:={}, aTemp:={},xCadena:=Alltrim(cCadena), EmptyDatos:={{"","","","",0}}

    (t:cAlias)->(dbGoTop())
    (t:cAlias)->(OrdSetFocus("portodo"))


            WHILE (t:cAlias)->(OrdWildSeek("*"+(xCadena)+"*", .T.))
                t:Blank()
                t:Load()
                aTemp:={}
                Aadd(aTemp,t:Id)
                Aadd(aTemp,t:Nombre)
                Aadd(aTemp,t:Rfc)
                Aadd(aTemp,t:Telefono1)
                Aadd(aTemp,(t:cAlias)->(Recno()))
                Aadd(xDatos,aTemp)
            ENDDO

      If Len(xDatos) = 0
         Return EmptyDatos
      EndIf
 Return xDatos
El RC del dialogo que se utiliza, no supe como extrarelo de PellesC, pero te comento que tiene los siguientes controles.

UN get para digitar la busqueda.
UN browse, (xbrowse, twbrowse, tcbrowse), el que tu utilices.
DOS botones uno para abrir el registro, y el otro para salir de la consulta.



Saludos.
Ricardo E. Guardado Flores.
GDL. MEX

Re: como se podrá identificar un numero X dentro un registro?

Posted: Sat Nov 17, 2012 3:48 am
by rolando
Hola,

Podrías usar la función AT().

Code: Select all

LOCAL cString := "xHarbour"

      ? At( "Ha", cString )            // result: 2
 
En tu caso:

Code: Select all

if at("0064951A",cstring) > 0
msginfo("Encontrado")  // o lo que quieras hacer cuando lo encuentra
endif
Uso siempre el at() para buscar dentro de campos memo y de caracteres.

Saludos

Rolando :D

Re: como se podrá identificar un numero X dentro un registro?

Posted: Sun Nov 18, 2012 8:24 am
by Manuel Aranda
Hola Aída:

Esto que te voy a poner no es exáctamente una búsqueda incremental, pero tal vez pueda servirte o adaptarlo a tus necesidades. Se trata de una función que te hace un filtrado en un listbox de los registros que contienen la cadena tecleada, independientemente de la posición que ocupe en el campo:

Code: Select all


................

REDEFINE GET oGet VAR cFilTexto  ID 112 OF oDlg ;
    PICTURE "@!" VALID FilTexto(cFilTexto,"CLIENTES",oDlg,oLbx)
...............
**********************************************************
static FUNCTION FilTexto(cFiltro,cFile,oDlg,oLbx)
**********************************************************
cFiltro := ALLTRIM(cFiltro)
//
IF ! EMPTY(cFiltro)
   (cFile)->(DBSETFILTER({|| AT(UPPER(cFiltro), UPPER((cFile)->Texto)) > 0 },"AT(UPPER(cFiltro), UPPER((cFile)->Texto)) > 0" ))
ELSE
   (cFile)->(DBCLEARFILTER())
ENDIF
//
(cFile)->(DBGOTOP())
oLbx:Refresh()
oDlg:Update()
RETURN(.T.)
 

Re: como se podrá identificar un numero X dentro un registro?

Posted: Sun Nov 18, 2012 8:21 pm
by Manuel Aranda
Hola de nuevo Aída, pues sí que lo tengo implimentado también para búsqueda incremental. Este es el código:

Code: Select all


Local cTecla:=""
Local oSay2
..........

 oLbx:bkeydown:={|nKey|DOKEYCHECK(nKey,oLbx,oSay2,oDlg,@cTecla)}
................
 REDEFINE SAY oSay2   ID 800 OF oDlg

*********************************************************************************
STATIC FUNCTION DOKEYCHECK(nKey,oLbx,oSay2,oDlg,cTecla)
********************************************************************************
*------SINGLE CHARACTER BROWSE SEARCHER----------------------
  && Note ASCII values: 65-90  are Capital A through Z.
   &&                  : 97-122 are lowercase a through z.
   &&                  : 48-57  are numbers 0-9.
   &&                  : 13     used below is for a RETURN key hit.
//
IF nKEY>=65 .AND. nKEY<=90 .OR. nKEY>=97 .AND. nKEY<=122 .OR. nKEY >=48 .AND. nKEY<=57 .OR. nKey = VK_SPACE
      //
      //cKey:=cKey+UPPER(CHR(nKEY))
      cTecla:=cTecla+UPPER(CHR(nKEY))
      //
      oSay2:SetText(cTecla)
      oSay2:Refresh()
      FilTexto(cTecla,"AGENDA",oDlg,oLbx)
      oLbx:refresh()              
      RETURN( NIL )   
 ENDIF
   //

   DO CASE
     */
      CASE nKEY == VK_BACK
           //
           cTecla=substr(cTecla,1,len(cTecla)-1)
           FilTexto(cTecla,"AGENDA",oDlg,oLbx)
           oSay2:SetText(cTecla)
           oSay2:Refresh()
      
      CASE nKEY == VK_DELETE
           //
           cTEcla=""
           FilTexto(cTecla,"AGENDA",oDlg,oLbx)
           oSay2:SetText(cTecla)
           oSay2:Refresh()
 
      CASE nKEY == VK_RETURN
                     //
      CASE nKEY == VK_INSERT
                      //
      CASE ( nKey == Asc( "F" ) .OR. nKey == Asc( "f" ) ) .AND. GetKeyState( VK_CONTROL )

  ENDCASE
       //
RETURN( NIL )

 
Obviamente, como el fichero tenga miles de registros, la lentitud será desesperante. Para ficheros poco voluminosos va muy bien.

Re: como se podrá identificar un numero X dentro un registro?

Posted: Mon Nov 19, 2012 9:53 am
by Mike Serra
Hola Aida, Si la cadena que quieres buscas siempre comienza en la misma posición y termina en la misma posición, por probar, prueba a crear un indice de la siguiente manera:

index on substr(<nombre_campo>,PosicionInicial,PosicionFinal) to prueba

Un Saludo,

Re: como se podrá identificar un numero X dentro un registro?

Posted: Mon Nov 19, 2012 6:07 pm
by AIDA
Hola :)

Muchísimas gracias a todos por sus ejemplos
y por sus ayuda me pondré a analizarlos me gusta comprender como funcionan :mrgreen:

no solo copiar y pegar :oops:


Todos son muy amables y muy lindos
que tengan una super semana

Saluditos :wink: