FoxPress – Noviembre 2000

 

Un Grid Buscador

http://www.fpress.com/                                   selector2.zip

 

Por Francisco San Pablo

         

Nota: para que el ejemplo funcione correctamente se tiene que adaptar el path que se encuentra en el programa inicio.prg

         

    

 

Hace dos meses publicamos una Clase Grid que te permitía volcar el resultado de cualquier select en ese Grid y haciendo doble click ir al registro señalado por el usuario.

 

     La ventaja de esa clase es su carácter genérico (vale para cualquier Select, con cualesquiera número de campos) y opcionalmente le podías decir si querías que te mostrara un campo o no.

 

     Los que miraron el código en detalle ya se apercibieron como una de las claves era el uso de una clase TextBox personalizada en el Grid.

 

     Una carencia, que algún lector nos comentó de ese Grid era la inexistencia de un ‘Buscador’: cuando el número de registros es pequeño, el usuario puede hacer un Scroll y localizar el registro que le interesa. Pero cuando el número de registros devuelto es muy grande entonces el usuario no puede ir uno a uno para localizar el registro que le interesa sino que tiene que tener algún tipo de opción que le permite de forma rápida acceder al registro que cumpla las características.

 

 

 

       La opción no sólo sería el poder acceder de forma rápida sino que también que fuera general de forma que sirva para cualquier Grid sin tener que tocar una sola línea de código y por ende que sirva para cualquier SELECT o consulta que uno haga.

 

     En los fuentes tienes el código de este artículo. Lo mejor, como siempre, es verlo funcionando y después de ver su utilidad mirar el código.

 

     Una vez ‘bajado’ y ejecutada la Select escribe directamente en el teclado cualquier palabra y verás que se te activará un buscador. Pero lo mejor es que ese buscador es para el campo que está seleccionado, por tanto te sirve para hacer búsquedas por campo.

 

       No pongo todo el código pues me parece que sería demasiado largo pero si te pongo las líneas que me parecen más interesantes:

 

  DO CASE

      *- Si pulsa botón delete ó retroceso

      CASE INLIST( nKeyCode, 7, 127 )

            NODEFAULT

 

      *- Si pulsa { ó CTRL+TAB, no hace nada

       CASE nKeyCode = 123 OR ;

  (nShiftAltCtrl = 2 AND nKeyCode = 148)

  

*- Si la tecla pulsada es una tecla válida para empezar

*- busqueda

       CASE BETWEEN(nKeyCode, 32, 255)

             NODEFAULT

 

LOCAL lcClaveBusca, lcOperador, lcNombreCampo,;

     lcTabla, nTiempoPasado

 

       *- Si no existe el objeto, es la primera vez que utiliza

*- la búsqueda

       IF TYPE('THIS.oFormBusq') <> 'O'

THIS.oFormBusq = CREATEOBJECT('dlgBusqueda', THIS.ControlSource, ;

                    'Buscador', .F.)

         ENDIF

       this.oFormBusq.mAsigValores(nKeyCode)

       this.oFormBusq.Show()

 

 

    *- F3

    CASE nKeyCode = -2 AND nShiftAltCtrl = 0

      IF TYPE('THIS.oFormBusq') = 'O'

        this.oFormBusq.mBuscaDeNuevo()

      ENDIF

                       ENDCASE

 

                 Este es un resumen del código que se debe poner en el método KeyPress de la clase TextBox para lanzar el buscador cuando el usuario pulse cualquier tecla pero con la salvedad de que si se pulsa Tabulador ó Escape o Retroceder, entonces el buscador no debe lanzarse.

 

            También el Buscador se guarda en una variable que hace que la segunda vez que se vuelva a instanciar ya no tenga que crearse sino que puede reutilizar el objeto. De esta forma la instanciación es más rápida.

 

            Otro pequeño truco para lograr más rápidas instanciaciones es en vez de borrar los objetos, esconderlos con un Thisform.Hide() de esta forma luego cuando tiene que volverlo a mostrar es mucho más rápido pues ya lo tiene presente aunque el usuario no lo ve.

 

            El resto del código pertenece ya propiamente al Buscador. Voy a trascribir unicamente el que construye la Select y permite realizar la búsqueda:

 

lcSelecEjec = [ SELECT recno() ;

FROM ] + lcDbf + ;

      [ WHERE ] + ;

      lcCampoSelec + [ lcExpBusq ] + ;

      THISFORM.cOldFilter + ;

      IIF(THISFORM.lActivoIndex,' ORDER BY ' + lcCampo + ;

      IIF( DESCENDING(TAGNO(lcCampo)), ' DESC ', ''), '' ) + ;

      [ INTO ARRAY THISFORM.ga___Busca ]

 

&lcSelecEjec

 

IF _TALLY > 0

   GO ( THISFORM.ga___Busca(THISFORM.nContRegis) ) IN (lcTabla)

ELSE

   lcMensaje = ""

   llEncontrado  = .F.

 

    DO CASE

        *- Si el tipo del campo es numérico

       CASE TYPE( 'lcExpBusqueda' ) $ "YNFBI"

          lcMensaje = PADR(lcExpBusqueda,20)

 

       CASE TYPE( 'lcExpBusqueda' ) $ "C"

          lcMensaje = ALLTRIM(lcExpBusqueda)

 

        CASE TYPE( 'lcExpBusqueda' ) $ "TD"

          lcMensaje = DTOC(lcExpBusqueda)

 

        CASE TYPE( 'lcExpBusqueda' ) $ "L"

          lcMensaje = ""

    ENDCASE

    IF SET("BELL")="ON"

      ?? CHR(7)

    ENDIF

  ENDIF

ENDIF

ENDIF

 

WAIT CLEAR

THISFORM.HIDE()

 

IF NOT llEncontrado

  MESSAGEBOX(" No se encontró : " + lcMensaje, 64, 'Aviso')

ENDIF

 

 

En este código se ve cómo la búsqueda es genérica y por tanto se adapta a cualquier necesidad y según el tipo de dato se comporta de forma diferente. Al final el Thisform.Hide() y la opción del Messagebox para el caso de que no se encuentre nada.

 

Creo que es mejor que al que le interese este tipo de funcionalidad se baje el código y lo mire. A mi me ha resuelto definitivamente las búsquedas en los Grids de una forma genérica y fácil que puedo incorporar a todas  mis aplicaciones sin tocar una sola línea de código.

 

 

 

 

FoxPress – Noviembre de 2000

© 2000 FoxPress. All rights reserved