Mysql & Busqueda Incremental xBrowse

Post Reply
User avatar
Mauricio
Posts: 199
Joined: Thu Oct 06, 2005 9:07 pm
Location: San Diego, CA

Mysql & Busqueda Incremental xBrowse

Post by Mauricio »

:D
Hola

estoy intentando hacerme una busqueda incremental con TMySql y xBrowse, capturo la tecla con bKeydown, pero no encuentro como refrescar el browse que origino la busqueda, despues de hacerle un filtro a la tabla con los datos que estaba buscando.

Code: Select all

#include "fiveWin.ch"
#include "xbrowse.ch"

static oBrw, cBuscador
/*******************************************************************/
function Departamentos()
   local oCol, cQuery, oDatos, oDlg
   LOCAL aBtn := array( 8 )
   local oBoton1, oBoton2
    local oDeptos, oFont1
    local oEsperar := Esperar("Cargando departamentos ..... espere por favor ...")

   cBuscador := ''

   IF oMysql:netErr()
      MSGINFO( cMensajeSql, cProgram )
      RETURN NIL
   ENDIF


   DEFINE FONT oFont1 NAME 'MS Sans Serif'   SIZE 0,-10 BOLD

   oDeptos := oMysql:Query( "SELECT * FROM departamentos ORDER BY nombre ")

   IF oDeptos:netErr()
      MSGINFO( cMensajeSql + ' [departamentos]', cProgram )
      RETURN NIL
   ENDIF


    oEsperar:end()
   DEFINE DIALOG oDlg RESOURCE "DEPTO0" TITLE "Catalogo de Departamentos"
   oDlg:lHelpIcon := (.f.)


   oBrw := TxBrowse():New(oDlg)
   SetMyBrwSql( oBrw, oDeptos )



   oCol := oBrw:AddCol()
   oCol:bStrData      := { || strzero(MyCampo(oDeptos,"codigo"),3) }
   oCol:cHeader       := "Código"


   oCol := oBrw:AddCol()
   oCol:bStrData      := { || MyCampo(oDeptos,"nombre") }
   oCol:cHeader       := "Descripción"


   oCol := oBrw:AddCol()
   oCol:bStrData      := { || transform(MyCampo(oDeptos,"descuento"),'999%') }
   oCol:cHeader       := "% descuento"
    oCol:nDataStrAlign := AL_RIGHT
   oCol:oDataFont     := oFont1



   oBrw:CreateFromResource(101)


   oBrw:bKeyDown     := { | nKey | MisTeclas( nKey, oBrw, oDeptos ) }

   oBrw:aCols[ 03 ]:bClrStd := {|| { iif( oDeptos:fieldGet('descuento') > 0, CLR_RED,  CLR_WHITE), CLR_WHITE } }  // nombre


   oBrw:bClrHeader := { || {CLR_MAGENTA,CLR_WHITE }}
   oBrw:bClrFooter := { || {CLR_GREEN,CLR_WHITE } }
   oBrw:bClrSel    := { || {CLR_CYAN,CLR_WHITE } }


    ACTIVATE DIALOG oDlg CENTER ON INIT CreaBarra(oDlg, oDeptos)
    oDeptos:end()
    oDeptos := NIL
   oFont1:end()
  RETURN NIL

static function CreaBarra(oDlg, oDeptos)
 return nil



/*******************************************************************/


static function MisTeclas( cSeek, oBrw, oDeptos )
    local cTecla := chr(cSeek)
    local cChar := upper(cTecla)
    local oDlg, oFont, oGet1

    cBuscador := cBuscador + cChar

    local oBuscar :=   oMysql:Query( "SELECT * FROM departamentos ORDER BY nombre WHERE nombre LIKE '" + cBuscador + "'%'")

    oBrw:Refresh()
    oDeptos:refresh()

        // en esta parte de aqui, es donde deberia asignarle la nueva data al browse, pero no doy con bola

return nil
 
Saludos,
Mauricio :mrgreen:
User avatar
wmormar
Posts: 1050
Joined: Fri Oct 07, 2005 10:41 pm
Location: México
Contact:

Re: Mysql & Busqueda Incremental xBrowse

Post by wmormar »

Mau,

contestado desde el messenger...
William, Morales
Saludos

méxico.sureste
User avatar
Mauricio
Posts: 199
Joined: Thu Oct 06, 2005 9:07 pm
Location: San Diego, CA

Re: Mysql & Busqueda Incremental xBrowse

Post by Mauricio »

Don Willians gracias.

lo anoto para que los demas vean la solucion, si pasan por lo mismo.

Code: Select all

static function MisTeclas( cSeek, oBrw, oTabla, oSay )
    local cTecla := chr(cSeek)
    local cChar := upper(cTecla)

    IF cSeek == VK_BACK .OR. cSeek == VK_ESCAPE
        cBuscador := ''
           oSay:setText(cBuscador)
          oTabla:cQuery := "SELECT * FROM vendedores ORDER BY nombre"
               oTabla:refresh()
             oBrw:refresh(.t.)
        return nil
    ENDIF

    IF cSeek == VK_RETURN  // Edicion del vendedor
        cBuscador := ''
           oSay:setText(cBuscador)
        AddDeptos(.f., oTabla)
        oTabla:refresh()
        oBrw:refresh()
    ENDIF
    IF cSeek == VK_INSERT         // agregar vendedor
        cBuscador := ''
            oSay:setText(cBuscador)
        AddDeptos(.t., oTabla)
    ENDIF
    IF cSeek == VK_DELETE            // borrar vendedor
        cBuscador := ''
            oSay:setText(cBuscador)
        deleteVendedor(oTabla)
    ENDIF


    if cSeek >= 30 .AND. cSeek <= 132
         cBuscador := cBuscador + cChar
    else
         return nil
        endif
    
        oSay:setText(cBuscador)

       // aqui esta el truco =====, pueden usar LIKE   con % al inicio y final,     si lo ponemos al inicio y final es como
       // contenido en $ de Clipper, si lo ponemos solo al inicio ira tomando _ al inicio
       // tambien se puede usar LEFT( nChar)
    oTabla:cQuery := "SELECT * FROM vendedores WHERE nombre LIKE '%" + cBuscador + "%'"

    oTabla:gotop()
   oTabla:refresh()
   oBrw:refresh(.t.)

return nil

 
Saludos
Mauricio :mrgreen:
User avatar
Biel EA6DD
Posts: 680
Joined: Tue Feb 14, 2006 9:48 am
Location: Mallorca
Contact:

Re: Mysql & Busqueda Incremental xBrowse

Post by Biel EA6DD »

Hola Mauricio, un poco tarde llega mi respuesta porque veo que ya lo tienes solucionado. De todas formas si quieres darle un vistazo, aqui tienes una alternativa, usando el metodo Find del recordset (evita el trafico al servidor que genera las sentencias Select), y usando los metodos própios de la clase xBrowse para busquedas incrmentales.

http://bielsys.blogspot.com/2008/04/usa ... o-y-2.html

Code: Select all

...
   oBrw:bSeek        := { | c | Busca(c,oRs) }
   oBrw:oSeek        := oSay
   oBrw:SetAdo(oRs)
   ...
//---------------------------------
STATIC FUNCTION Busca(cBuscar,oRs)
   LOCAL nLen:=Len(cBuscar)
   STATIC nLenAnt
   DEFAULT nLenAnt:=0
   IF Len(cBuscar)>1
      IF(nLenAnt>nLen,oRs:MoveFirst(),)
      oRs:Find( "CliDes LIKE '"+cBuscar+"*'",,1)
   ELSE
      oRs:MoveFirst()
      IF !Empty(cBuscar)
         oRs:Find( "CliDes LIKE '"+cBuscar+"*'",,1)
      ENDIF
   ENDIF
   nLenAnt:=nLen
RETURN !(oRs:Eof.OR.oRs:Bof)
 
Saludos desde Mallorca
Biel Maimó
http://bielsys.blogspot.com/
User avatar
Armando
Posts: 2479
Joined: Fri Oct 07, 2005 8:20 pm
Location: Toluca, México
Contact:

Re: Mysql & Busqueda Incremental xBrowse

Post by Armando »

Biel:

Excelente solución !, solo hay que tomar en cuenta un detalle, la busqueda que se hace con la solución de Mauricio se hace a la Tabla que hay en el servidor, de ahí tu acertado comentario sobre la sobre carga al servidor, mientras que la busqueda que se hace con tu solución se hace sobre el objeto RecordSet que es una copia de la tabla del lado del cliente.

Sentado lo anterior es bueno aclarar que si por alguna razón la tabla en el servidor fue actualizada con nuevos registros estos no van a estar en el RecordSet a menos de que se haga un Refresh, lo que podría provocar algunos errores.

Supongamos que estamos dando Altas de nuevos clientes pero no somos los unicos que podemos hacerlo algunas otras terminales tambien tiene esa autorización, lo lógico es que antes de realizar el alta del nuevo cliente primero revisemos que no este registrado, esta revisión debe ser a través de una busqueda que en el caso de la solución de Mauricio, aunque más lenta, sería más eficiente en cuento a resultado, mientras que la solución que ofrece Biel, aunque remota, podría caber la posibilidad de duplicar algunos clientes.

Solo mis dos centavos.

Saludos al foro
SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
User avatar
Mauricio
Posts: 199
Joined: Thu Oct 06, 2005 9:07 pm
Location: San Diego, CA

Re: Mysql & Busqueda Incremental xBrowse

Post by Mauricio »

:D

Biel,

gracias por tu sugererencia.

el problema para mi es este.

tengo un catalogo de productos de cerca de 38mil, el cual se comparte con 8 tiendas remotas,

si cargo la tabla completa al inicio se hace una pesadilla cargar los 38mil registros, con los cuales ya podria hacer la busqueda como sugieres.

lo que hago es cargar solo 250 registros al inicio o 100, de ahi el usuario ya puede empezar a teclear lo que busca y le va apareciendo, lo que me importa del catalogo es ver en caso de que uno de los almacenes no tenga el producto, saber en ese momento quien lo tiene.

por eso debo estar revisandolo en cada momento, porque todos estan vendiendo al mismo tiempo, es un punto de venta que a lo mejor en 2 minutos ya me vendio los productos y yo sigo pensando que los tiene porque la tabla la cargue al inicio.

es como lo comenta perfecto don Armando, la informacion debe estar actualizada en ese instante no me sirve de hace 3 o 5 minutos.

con la solucion que se esta haciendo es bastante rapido, solo le puse que empezara a buscar cuando el usuario escribiera mas de 2 letras.


saludos cordiales,
Mauricio :mrgreen:
User avatar
Adolfo
Posts: 815
Joined: Tue Oct 11, 2005 11:57 am
Location: Chile
Contact:

Re: Mysql & Busqueda Incremental xBrowse

Post by Adolfo »

Mauricio....

La solucion es tener una funcion que se gatille con el OnChange del Browse, que pregunte en el momento por el stock y lo muestre donde tu quieras dentro del dialogo.

Esa funcion seria sencilla...

.....
oBrw:bChange:={ || RefrescaStock(oDbProd:CODIGO) }
.....


Function RefrescaStock(codigobusca)
Local nStock:=0
Local oCmd
Local oRsCmd

oCmd:=TOleAuto():New("ADODB.Command")
oCmd:CommandText := "select STOCK from productos where CODIGO ='" + codigoBusca + "' limit 1"
oCmd:CommandType := adCmdText
oCmd:ActiveConnection:=oCn

oRsCmd:=oCmd:Execute()
nStock:=oRsCmd:Fields( 0 ):value
oRsCmd:Close()

If nStock <> Nil
oSayStock:SetText(Str(nStock))
oSayStock:Refresh()
Endif

Return Nil

Esa funcion deberia demorarse milisegundos...y le puedes poenr lo parametros que quieras para controar cuando llamar al recordset o no...
Con eso liberas el trafico y obtienes VELOCIDAD....

Saludos
DEsde Chile
Adolfo
;-) Ji,ji,ji... buena la cosa... "all you need is code"

http://www.xdata.cl - Desarrollo Inteligente
----------
Lenovo Legion Y520, 16GB Ram, 1 TB NVME M.2, 1 TB SSD, GTX 1050
User avatar
Mauricio
Posts: 199
Joined: Thu Oct 06, 2005 9:07 pm
Location: San Diego, CA

Re: Mysql & Busqueda Incremental xBrowse

Post by Mauricio »

Adolfo,

estas usando ADO?

Saludos,
Mauricio
User avatar
Mauricio
Posts: 199
Joined: Thu Oct 06, 2005 9:07 pm
Location: San Diego, CA

Re: Mysql & Busqueda Incremental xBrowse

Post by Mauricio »

Adolfo,

en ese supuesto se me complica un poco ir haciendo registro por registro

porque por ejemplo en este caso es una farmacia, le teclean AMOX , de deberia traer todo lo que contenga AMOXCILINA en todas las presentanciones, para saber cual tienes y cual le puedes ofrecer el cliente y si no la tienes en ese puesto, en cual la tienen para hacer la orden que te la traigan o se la reserven al cliente.

pueden ser que coincidan 10-20-60

y seria tardadon que el usuario vaya uno por uno,

Saludos,
Mauricio
User avatar
wmormar
Posts: 1050
Joined: Fri Oct 07, 2005 10:41 pm
Location: México
Contact:

Re: Mysql & Busqueda Incremental xBrowse

Post by wmormar »

Mauricio,

Creo lo que comenta Adolfo es bueno, solo que no en todas las necesidades se aplica.

También creo que es cuestión de mentalidad, a veces tratamos de "estirar" mucho SQL para simular DBF.

Vuelvo a repetir es por necesidades.
William, Morales
Saludos

méxico.sureste
User avatar
Mauricio
Posts: 199
Joined: Thu Oct 06, 2005 9:07 pm
Location: San Diego, CA

Re: Mysql & Busqueda Incremental xBrowse

Post by Mauricio »

:D :D

Don William,

estoy totalmente de acuerdo con Don Adolfo, por eso le puse "en este supuesto", se me complicaria,

respecto a estirar SQL desgraciadamente los clientes vienen de sistemas hechos en Clipper/FWH y DBF que se acostumbraron tanto que no hacerles casi lo mismo que hacian los sistemas viejos, para ellos es ir para atras.

saludos,
Mauricio
User avatar
Adolfo
Posts: 815
Joined: Tue Oct 11, 2005 11:57 am
Location: Chile
Contact:

Re: Mysql & Busqueda Incremental xBrowse

Post by Adolfo »

Mauricio...

Conversar con el cliente de las ventajas y desventajas de una tecnologia y la otra es el primer paso para no prometer cosas que no podras hacer.

Segundo, el cambio de la interfaz es necesario si quieres pasar a SQL, los Browses de DBF deben ser modificados y ajustados a la nueva realidad ( SQL, Recordset etc ) y vas a tener que programar updates o refresh mas seguido de lo que crees, esos botones van a estar presentes en la mayoria de los gestores de ABM. o en su defecto programar timers que te refresquen automaticamente los browses o pantallas.

Para tu problema.. un GEt donde tipees lo que buscas, aunque solo sea parte del nombre (amox... por ej ) y al presionar enter, mostrar en el browse lo pertinente. Es proceso debe ser acotado ( es decir ... rapido, sin muchas confirmaciones, 1 o 2 botones, que controle solo los errores, que valide salir con escape, que enter seleccione sin mas confirmaciones etc etc... lo que por el momento se me ocurre ) de tal forma que en unos pocos dias de uso ya sea algo mecanico para el usuario.
De la misma manera, debes tener ese MISMO y EXACTO procedimiento para todas las funciones donde el usuario deba buscar en alguna tabla. asi logras standarizacion dentro del sistema y todos saben que hacer independientemente del modulo donde se encuentren.

Saludos
Desde Chile
Adolfo
;-) Ji,ji,ji... buena la cosa... "all you need is code"

http://www.xdata.cl - Desarrollo Inteligente
----------
Lenovo Legion Y520, 16GB Ram, 1 TB NVME M.2, 1 TB SSD, GTX 1050
User avatar
wmormar
Posts: 1050
Joined: Fri Oct 07, 2005 10:41 pm
Location: México
Contact:

Re: Mysql & Busqueda Incremental xBrowse

Post by wmormar »

Mauricio,

Muy de acuerdo contigo.

Adolfo,

Cuando la aplicación es para un solo cliente el proceso aplica en su totalidad, pero cuando son muchos clientes ahi es donde (como decimos por acá) la mula tuerce el rabo, jjejjejjejje

Lo que tenemos muy claro es que no siempre ponemos las reglas los desarrolladores, el usuario final (el que paga) es muy quisquilloso y hay cosas que no debemos hacer, pero las tenemos que hacer.
William, Morales
Saludos

méxico.sureste
Post Reply