Page 1 of 4

Filtro con varios campos./Filter multiple fields.

Posted: Thu Apr 03, 2014 4:41 am
by Javier Tovar
Hola a todos

Hice una aplicación con varios campos, no se si haya una mejor forma de hacerlo, me gustaría saber su opinión.

Gracias

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

I made an application with multiple fields, is not whether there is a better way, I would like to know your opinion.

thanks
GridMio.rar
(6.1 KiB) Downloaded 198 times

Filtro con varios campos./Filter multiple fields.

Posted: Thu Apr 03, 2014 11:36 am
by Pablo César
Hola Javier, cual seria tu duda ?

Lo que noté que el prg no está en padrón UTF-8 (UNICODE).

Sobre los ComboBox, yo talvez no los pondria. Pienso que dejar la tela lo cuanto más simples, mejor. Es decir, poderia colocar através de botones, un boton para "Filtros" y asi abreria otra ventanita con las opciones de ComboBoxes.

Colocaria el Grid principal, con un boton de busca. Haria tambien que cuando el usuário clique en los HEADERS del grid, este lo pudiera ordenar através de ONHEADCLICK.

El tamanho de la pantalha, intentaria dejarla el tamanho menor posible. Yo tuve que ponerlo em VIRTUAL WINDOW (com ScrollBar) porque no me cabia, ya que uso 1024.

Esa es mi opinion, no sé si pude ayudarte en algo...

Re: Filtro con varios campos./Filter multiple fields.

Posted: Thu Apr 03, 2014 11:40 am
by serge_girard
Javier,


- Selecciona (4) is missing c4 in IF Zapatos->(DBSEEK(c1+c2+c3+c4)).
- Perhaps ON CHANGE is better.
- But better is one BUTTON to START selection instead of ON CHANGE or ONLOSTFOCUS
- Selection 1+3+5 is not possible:

Code: Select all

****window
         DEFINE BUTTON BUTTON_a1
            ROW	10
            COL	10
            CAPTION 'Start' 
            HEIGHT 86   
            WIDTH  72  
            PICTURE '..'  
            ACTION Selecciona()
         END BUTTON
.....end window

PROCEDURE Selecciona(nCampo)
	LOCAL c1 := UPPER(PADR(aTiposZapatos[Win_Filt.Combo_1.VALUE],20))
	LOCAL c2 := UPPER(PADR(aMarcasZapatos[Win_Filt.Combo_2.VALUE],20))
	LOCAL c3 := UPPER(PADR(aModelosZapatos[Win_Filt.Combo_3.VALUE],10))
	LOCAL c4 := UPPER(PADR(aColoresZapatos[Win_Filt.Combo_4.VALUE],20))
	LOCAL c5 := UPPER(PADR(aAcabadosZapatos[Win_Filt.Combo_5.VALUE],20))
	LOCAL cBusca := ''
	
	DBSELECTAREA( "Zapatos1" )
	DBSETORDER('ZZapatos')
	ZAP 

DBSELECTAREA( "Zapatos" )
DBGOTOP()

DO WHILE .not. eof()
   lok = .t.

     if!empty(c1) 
      if Zapatos->(Tipo) == c1 
      else
         lok = .f.
      endif
   endif

   if!empty(c2) 
      if Zapatos->(Marca) == c2
      else
         lok = .f.
      endif
   endif

   if!empty(c3) 
      if Zapatos->(Modelo) == c3
      else
         lok = .f.
      endif
   endif

   if!empty(c4) 
      if Zapatos->(Color) == c4
      else
         lok = .f.
      endif
   endif

   if!empty(c5) 
      if Zapatos->(Acabado) == c5
      else
         lok = .f.
      endif
   endif



   if lok      
      Zapatos1->(DBAPPEND())
      Zapatos1->Codigo := Zapatos->Codigo
      Zapatos1->Tipo   := Zapatos->Tipo
      Zapatos1->Marca  := Zapatos->Marca
      Zapatos1->Modelo := Zapatos->Modelo
      Zapatos1->Color  := Zapatos->Color
      Zapatos1->Acabado:= Zapatos->Acabado
   endif

   Zapatos->(DBSKIP())

ENDDO
win_Filt.Grid_2.Refresh
Win_Filt.Label_9.VALUE := "Total Items : " + str(Win_Filt.Grid_2.ItemCount)
RETURN NIL

 
If you have more fields this not good, then better use EVAL filter!

Succes, Serge

Re: Filtro con varios campos./Filter multiple fields.

Posted: Thu Apr 03, 2014 12:13 pm
by danielmaximiliano
Buena aplicacion Javier :

seria mas conveniente que utilizes Onchange en vez de OnLostFocus para aplicar los filtros, de esa forma aplica el filtro antes que seleccione el proximo combo.
ahora me tengo que ir, desp te paso las correcciones.
hay errores cuando seleccionas un campo y el anterior no fue seleccionado.

Code: Select all

PROCEDURE Selecciona( nCampo )
    LOCAL lEncontrado := .F.
	LOCAL c1 := UPPER( PADR( aTiposZapatos    [Win_Filt.Combo_1.VALUE],20))
	LOCAL c2 := UPPER( PADR( aMarcasZapatos   [Win_Filt.Combo_2.VALUE],20))
	LOCAL c3 := UPPER( PADR( aModelosZapatos  [Win_Filt.Combo_3.VALUE],10))
	LOCAL c4 := UPPER( PADR( aColoresZapatos  [Win_Filt.Combo_4.VALUE],20))
	LOCAL c5 := UPPER( PADR( aAcabadosZapatos [Win_Filt.Combo_5.VALUE],20))
	LOCAL cBusca := ''
	
	DBSELECTAREA( "Zapatos1" )
	DBSETORDER(   'ZZapatos' )
	ZAP 
	 

	IF nCampo == 1	
		DBSELECTAREA( "Zapatos" )
		DBSETORDER('ITipo')
		DBGOTOP()
		IF Zapatos->(DBSEEK(c1))
			DO WHILE Zapatos->(Tipo) = c1
				Zapatos1->(DBAPPEND())
				Zapatos1->Codigo := Zapatos->Codigo
				Zapatos1->Tipo   := Zapatos->Tipo
				Zapatos1->Marca  := Zapatos->Marca
				Zapatos1->Modelo := Zapatos->Modelo
				Zapatos1->Color   := Zapatos->Color
				Zapatos1->Acabado:= Zapatos->Acabado
				Zapatos->(DBSKIP())
				lEncontrado := .T.
			ENDDO
		ENDIF
	
	ELSEIF nCampo == 2
		DBSELECTAREA( "Zapatos" )
		DBSETORDER('Zapatos2')
		DBGOTOP()
		IF Zapatos->(DBSEEK(c1+c2))
			DO WHILE Zapatos->(Tipo) = c1 .AND. Zapatos->(Marca) = c2
				Zapatos1->(DBAPPEND())
				Zapatos1->Codigo := Zapatos->Codigo
				Zapatos1->Tipo   := Zapatos->Tipo
				Zapatos1->Marca  := Zapatos->Marca
				Zapatos1->Modelo := Zapatos->Modelo
				Zapatos1->Color  := Zapatos->Color
				Zapatos1->Acabado:= Zapatos->Acabado
				Zapatos->(DBSKIP())
				lEncontrado := .T.
			ENDDO
		ENDIF	
       
	ELSEIF nCampo == 3
		DBSELECTAREA( "Zapatos" )
		DBSETORDER('Zapatos3')
		DBGOTOP()
		IF Zapatos->(DBSEEK(c1+c2+c3))
			DO WHILE Zapatos->(Tipo) = c1 .AND. Zapatos->(Marca) = c2 .AND. Zapatos->(Modelo) = c3
				Zapatos1->(DBAPPEND())
				Zapatos1->Codigo := Zapatos->Codigo
				Zapatos1->Tipo   := Zapatos->Tipo
				Zapatos1->Marca  := Zapatos->Marca
				Zapatos1->Modelo := Zapatos->Modelo
				Zapatos1->Color  := Zapatos->Color
				Zapatos1->Acabado:= Zapatos->Acabado
				Zapatos->(DBSKIP())
				lEncontrado := .T.
			ENDDO
		ENDIF
	
	ELSEIF nCampo == 4
		DBSELECTAREA( "Zapatos" )
		DBSETORDER('Zapatos4')
		DBGOTOP()
		IF Zapatos->(DBSEEK(c1+c2+c3))
			DO WHILE Zapatos->(Tipo) = c1 .AND. Zapatos->(Marca) = c2 .AND. Zapatos->(Modelo) = c3 .AND. Zapatos->(Color) = c4
				Zapatos1->(DBAPPEND())
				Zapatos1->Codigo := Zapatos->Codigo
				Zapatos1->Tipo   := Zapatos->Tipo
				Zapatos1->Marca  := Zapatos->Marca
				Zapatos1->Modelo := Zapatos->Modelo
				Zapatos1->Color  := Zapatos->Color
				Zapatos1->Acabado:= Zapatos->Acabado
				Zapatos->(DBSKIP())
				lEncontrado := .T.
			ENDDO
			
		ENDIF
		
	ELSEIF nCampo == 5
		DBSELECTAREA( "Zapatos" )
		DBSETORDER('IZapatos')
		DBGOTOP()
		IF Zapatos->(DBSEEK(c1+c2+c3+c4+c5))
			DO WHILE Zapatos->(Tipo) = c1 .AND. Zapatos->(Marca) = c2 .AND. Zapatos->(Modelo) = c3 .AND. Zapatos->(Color) = c4 .AND. Zapatos->(Acabado) = c5
				Zapatos1->(DBAPPEND())
				Zapatos1->Codigo := Zapatos->Codigo
				Zapatos1->Tipo   := Zapatos->Tipo
				Zapatos1->Marca  := Zapatos->Marca
				Zapatos1->Modelo := Zapatos->Modelo
				Zapatos1->Color   := Zapatos->Color
				Zapatos1->Acabado:= Zapatos->Acabado
				Zapatos->(DBSKIP())
				lEncontrado := .T.
			ENDDO
			
		ENDIF	
        		
	ENDIF
	If ! lEncontrado 
	   MsgInfo( 'Selección ' + Chr( 10 ) + ;
	             C1           + Chr( 10 ) + ;
				 C2            + Chr( 10 ) + ;
				 C3             + Chr( 10 ) + ;
				 C4             + Chr( 10 ) + ;
				 C5             + Chr( 10 )  , ;
				"Mensaje de atención " )
	Endif
	Win_Filt.Label_9.VALUE := "Total Items : " + str( Win_Filt.Grid_2.ItemCount )
	win_Filt.Grid_2.Refresh
RETURN NIL

Re: Filtro con varios campos./Filter multiple fields.

Posted: Thu Apr 03, 2014 1:11 pm
by serge_girard
Javier,

Try this, it can take many selections:

Code: Select all

PROCEDURE Selecciona(nCampo)
LOCAL c1 := UPPER(PADR(aTiposZapatos[Win_Filt.Combo_1.VALUE],20))
LOCAL c2 := UPPER(PADR(aMarcasZapatos[Win_Filt.Combo_2.VALUE],20))
LOCAL c3 := UPPER(PADR(aModelosZapatos[Win_Filt.Combo_3.VALUE],10))
LOCAL c4 := UPPER(PADR(aColoresZapatos[Win_Filt.Combo_4.VALUE],20))
LOCAL c5 := UPPER(PADR(aAcabadosZapatos[Win_Filt.Combo_5.VALUE],20))
LOCAL cBusca := ''

DBSELECTAREA( "Zapatos1" )
DBSETORDER('ZZapatos')
ZAP 

Filter := {}

IF !EMPTY(c1)
   AADD(Filter, {|| Zapatos->(Tipo) == c1})
ENDIF

IF !EMPTY(c2)
   AADD(Filter, {|| Zapatos->(Marca) == c2})
ENDIF

IF !EMPTY(c3)
   AADD(Filter, {|| Zapatos->(Modelo) == c3})
ENDIF

IF !EMPTY(c4)
   AADD(Filter, {|| Zapatos->(Color) == c4})
ENDIF

IF !EMPTY(c5)
   AADD(Filter, {|| Zapatos->(Acabado) == c5})
ENDIF

DBSELECTAREA( "Zapatos" )
DBGOTOP()

DO WHILE .not. eof()
   IF EvalFilter()
      Zapatos1->(DBAPPEND())
      Zapatos1->Codigo := Zapatos->Codigo
      Zapatos1->Tipo   := Zapatos->Tipo
      Zapatos1->Marca  := Zapatos->Marca
      Zapatos1->Modelo := Zapatos->Modelo
      Zapatos1->Color  := Zapatos->Color
      Zapatos1->Acabado:= Zapatos->Acabado
   ENDIF

   Zapatos->(DBSKIP())

ENDDO
win_Filt.Grid_2.Refresh
Win_Filt.Label_9.VALUE := "Total Items : " + str(Win_Filt.Grid_2.ItemCount)
RETURN NIL




STATIC FUNCTION EvalFilter()
****************************
LOCAL retval := .T.
LOCAL i

FOR i := 1 TO LEN(Filter)
   retval := retval .AND. EVAL(Filter[i])
NEXT


RETURN retval
And function Limpia is not needed!

Greetings, Serge

Re: Filtro con varios campos./Filter multiple fields.

Posted: Thu Apr 03, 2014 1:22 pm
by serge_girard
Javier,


You can call Limpia with a button in order to reset your filters.

Serge

Re: Filtro con varios campos./Filter multiple fields.

Posted: Thu Apr 03, 2014 5:08 pm
by Javier Tovar
Pablo César wrote:Hola Javier, cual seria tu duda ?
La duda seria si la forma de hacerlo es la mejor, ya que como puedes ver, lo que hago es borrar toda la DBF cada vez que hago un nuevo filtro. Y selecciono un nuevo indice en cada ComboBox para que haga la busqueda, Es que aquí en México los productos de zapatos no todos tienen código de barras, mas bien es raro el quien los use, y para seleccionar un zapato en particular tendría que ser de la forma que describo, filtrar por tipo, después por marca, después por modelo... Creo que en una zapatería puede haber unos 5000 zapatos diferentes; entonces mi duda es este modo de hacerlo es el mejor, el más rápido o hay otro? Como ir filtrando por campo seleccionado?. También estoy tentado a hacer UN CAMPO tipo carácter que contenga todos los campos de busqueda e ir buscando sobre este campo como vaya seleccionanado datos y que en la grid se posicione en el primer renglon en el más próximo "Sofseek".

Lo que noté que el prg no está en padrón UTF-8 (UNICODE).
Si, no me había fijado, gracias.
Sobre los ComboBox, yo talvez no los pondria. Pienso que dejar la tela lo cuanto más simples, mejor. Es decir, poderia colocar através de botones, un boton para "Filtros" y asi abreria otra ventanita con las opciones de ComboBoxes.

Colocaria el Grid principal, con un boton de busca. Haria tambien que cuando el usuário clique en los HEADERS del grid, este lo pudiera ordenar através de ONHEADCLICK.

El tamanho de la pantalha, intentaria dejarla el tamanho menor posible. Yo tuve que ponerlo em VIRTUAL WINDOW (com ScrollBar) porque no me cabia, ya que uso 1024.

Esa es mi opinion, no sé si pude ayudarte en algo...
Si, este demo lo hice para hacer los filtrados, ya que en la compilación con todo el sistema se tarda más. Y si lo que describes esta bien, ya los había considerado. Pero de todas formas gracias, nunca esta de más reafirmar las cosas a como las haría cada uno de ustedes.

Y muchas gracias por contestar y si tienes otra idea Bienvenida.

Saludos

Re: Filtro con varios campos./Filter multiple fields.

Posted: Thu Apr 03, 2014 5:21 pm
by Javier Tovar
serge_girard wrote:Javier,


- Selecciona (4) is missing c4 in IF Zapatos->(DBSEEK(c1+c2+c3+c4)).
- Perhaps ON CHANGE is better.
- But better is one BUTTON to START selection instead of ON CHANGE or ONLOSTFOCUS
- Selection 1+3+5 is not possible:
-No entiendo lo que quieres decir aqui.
-Hola serge_girard, si a lo mejor es mejor con ON CHANGE.
-Si, solo es un demo, pero lo tomare en cuenta
-Efectivamente no se puede filtrar en campos no consecutivos.

-Voy a probar como propones el código!

Gracias por contestar y pensar en una mejor solución.

Saludos :D :D :D
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
I do not understand what you mean here.
Hello serge_girard if maybe it's better with ON CHANGE.
Yeah, it's just a demo, but I'll take into account
Indeed you can not filter on nonconsecutive fields.

I'll try and offer code!

Thanks for answer and think of a better solution.

regards :D :D :D

Re: Filtro con varios campos./Filter multiple fields.

Posted: Thu Apr 03, 2014 5:28 pm
by Javier Tovar
danielmaximiliano wrote:Buena aplicacion Javier :

seria mas conveniente que utilizes Onchange en vez de OnLostFocus para aplicar los filtros, de esa forma aplica el filtro antes que seleccione el proximo combo.
ahora me tengo que ir, desp te paso las correcciones.
hay errores cuando seleccionas un campo y el anterior no fue seleccionado.
Hola DanielMaximiliano,

Si creo que voy a cambiar a ON CHANGE.
Si esos son los problemas que tengo.
Y como ya mencione en un anterior post, la pregunta también es, cual seria la mejor forma de hacer los filtros al ir seleccionanado un campo a la vez?

Gracias por contestar y espero las correcciones.

Saludos :D :D :D

Re: Filtro con varios campos./Filter multiple fields.

Posted: Thu Apr 03, 2014 5:35 pm
by Javier Tovar
serge_girard wrote:Javier,

Try this, it can take many selections:
OK serge_girard,

Si, voy a ver tu código, hoy pruebo y te digo!

Gracias por contestar de nuevo :D :D :D

Saludos