Page 1 of 2

ON EDIT CHANGE en Combobox (Sin Solución)

Posted: Mon May 27, 2013 7:17 pm
by Leo
Srs. del foro, tengo el siguiente dilema:

En mi diálogo existe un combobox, el cual debo poder cambiar según el nombre de la ciudad, es decir, si digito "SANTIA", inmediatamente debe posicionarme en la ciudad de "SANTIAGO", el tema es que esto funciona solamente con el combobox de pelles c con el atributo sort, el cual me arroja como resultado cualquier cosa, es decir, si digito "SANTIA", este me devuelve "IQUIQUE". Existe alguna forma de hacer esto, pero con el valor correcto del item?

Codigo Fuente:

Code: Select all

Function New_City()
Local o4001,o4002,o4003,o4004,o4005,o4006,o4007,o4008,o1001,o1002,oDlg,oImg,oBrush,lSave

Public Codigo:=Space(5),Descrip:=Space(40),Code_Planta:=Space(5),D_Planta:=Space(40),aPlanta:={},aCodes:={}

Set Resources To "AztecCode.dll"

DEFINE DIALOG oDlg RESOURCE "AGREGAR_DESTINO" Title "Crear Nueva Ciudad" Font oFont Color CLR_BTNFACE ,CLR_BTNFACE

oQry[21] := oConected:Query( "SELECT * FROM destinos ORDER BY Planta" )
D_Planta := oQry[21]:Planta+" "+Str(oQry[21]:Codigo_Planta,5)
Do While !oQry[21]:Eof()
    aAdd(aPlanta,oQry[21]:Planta+" "+Str(oQry[21]:Codigo_Planta,5))
    oQry[21]:Skip(1)
EndDo
oQry[21]:GoTop()
aSort(aPlanta,,, { |x, y| UPPER(x[1]) < UPPER(y[1]) })
Redefine Say o4001 Id 4001 Of oDlg Font oFont Color CLR_BLACK ,CLR_BTNFACE
Redefine Say o4002 Id 4002 Of oDlg Font oFont Color CLR_BLACK ,CLR_BTNFACE
Redefine Say o4003 Id 4003 Of oDlg Font oFont Color CLR_BLACK ,CLR_BTNFACE
Redefine Get o4004 Var Codigo      Picture "@ #####" Id 4004 Of oDlg Valid (Valida_Cod_City(Codigo,oDlg))
Redefine Get o4005 Var Descrip     Picture "@K!"     Id 4005 Of oDlg Valid (!Empty(Descrip))
Redefine Get o4006 Var Code_Planta Picture "@ #####" Id 4006 Of oDlg Update
REDEFINE COMBOBOX o4007 VAR D_Planta PICTURE "@K!"        ;                                            // esto es lo que intento con el combobox
   ITEMS aPlanta ID 4007 OF oDlg UPDATE ;                                                                           // Pero, me arroja cualquier resultado, aún ordenando el array que contiene los items
    ON EDIT CHANGE (o4007:Refresh(),Busca_Code_Planta(D_Planta,oDlg)) ;                      // Alguna idea?
    ON CHANGE (Busca_Code_Planta(D_Planta,oDlg),o4006:Refresh(),oDlg:Update())

// Valid (Busca_Code_Planta(D_Planta,oDlg))
o1001 := Cancel := TBtnBmp():ReDefine( 1001,,, "Save.Bmp",,, {|Self|(lSave:=.T.,oDlg:End())}, oDlg, .T.,, .F.,,,,,,,, .T.,,, .T. )
o1002 := Cancel := TBtnBmp():ReDefine( 1002,,, "Volver.Bmp",,, {|Self|(lSave:=.F.,oDlg:End())}, oDlg, .T.,, .F.,,,,,,,, .T.,,, .T. )

o4004:bKeyDown:={|nKey| IIF( nKey==27,(oDlg:End,lSave:=.F.), )}

ACTIVATE DIALOG oDlg Centered

IF lSave
   oClientsQry:GetBlankRow(.F.)
   oClientsQry:Codigo_Planta:=Codigo
   oClientsQry:Planta       :=Descrip
   oClientsQry:Save()
ENDIF

Return Nil
Function Busca_Code_Planta(Codigo,oDlg)
Local lRet:=.F.,cOrder:="Codigo_Planta",nSeek,cWhere:="Codigo_Planta="+Right(Codigo,5),I

oQry[21]:SetWhere(cWhere)
*MsgAlert(cWhere)
*xBrowse(oQry[21])
IF oQry[21]:nRecCount<>0
   lRet:=.T.
    Code_Planta:=oQry[21]:Codigo_Planta
    oDlg:Update()
Else
   lRet:=.F.
    MsgAlert("Sr. Usuario, la Planta Especificada NO EXISTE...","Advertencia...")
ENDIF
oQry[21]:SetWhere("")

Return lRet
De Antemano, muchas gracias.

Re: ON EDIT CHANGE en Combobox

Posted: Tue May 28, 2013 7:05 pm
by Antonio Linares

Re: ON EDIT CHANGE en Combobox

Posted: Tue May 28, 2013 8:59 pm
by Leo
Antonio, gracias por responder, pero el problema persiste. Al asignar la propiedad sort este ordena el array alfabéticamente, pero este no considera el número de elemento y finalmente entrega otro resultado que no tiene que ver con el que se digitó.

Ejemplo:

al escribir chill el resultado debería ser chillán, sin embargo va al número de elemento que corresponde a curicó.

Re: ON EDIT CHANGE en Combobox

Posted: Tue May 28, 2013 9:14 pm
by Antonio Linares
No uses el estilo sort en el recurso, en vez de eso ordena el array con ASort()

Re: ON EDIT CHANGE en Combobox

Posted: Wed May 29, 2013 3:00 am
by Leo
Por requerimientos de usuario, debo poder digitar la ciudad, y lo único que me permite generar ese tipo de búsqueda en el combobox es el atributo sort en el control.

Re: ON EDIT CHANGE en Combobox

Posted: Wed May 29, 2013 2:41 pm
by elmoiquique
Hola Leo...

te comento tengo el mismo problema con el combobox, el usuario igual requiere poder digitar y encontrar lo que busca, con el sort del combobox se puede, pero en ocasiones la informacion que muestra no es la misma que despliega posteriormente y esto ha llevado a mi cliente a errores gravisimos... Al inabilitar el sort del combobox solo busca la posicion del primer caracter cosa que el usuario no quiere, ya que maneja mucha informacion con ese caracter requiere de una busqueda manual....
Al parecer es un error del combobox, porue solo al habilitar esa opcion se producen errores, pero se require para poder agilizar la busqueda caso contrario se vuelve lento el proceso...

No se si lograste resolver el tema.... si es asi como lo hiciste

Saludos

Elmo

Re: ON EDIT CHANGE en Combobox

Posted: Wed May 29, 2013 2:53 pm
by elmoiquique
Antonio Linares wrote:No uses el estilo sort en el recurso, en vez de eso ordena el array con ASort()
En el recurso al no activar el sort, solo busca por el primer caracter, en cambio cuando uno activa el sort este busca una cadena de caracteres, por lo cual es mas efectivo, pero est opcion tiene un grave error, de mostrar algo y seleccionar algo diferente...

Re: ON EDIT CHANGE en Combobox

Posted: Wed May 29, 2013 3:34 pm
by Leo
Elmo, logré crear una solución pero bien de parche. En la tabla más pequeña que tiene mas o menos como 16 o 18 registros, agregué un campo numérico que las oficia de indice, donde le doy el orden que debe tener la combobox. De esa forma genero el query en mysql y relleno el array en el orden que debe tener y problema solucionado. El tema es como solucionas el problema en tablas que tienen un constante crecimiento.

Me he dado cuenta del siguiente tema:

MySql ordena alfabéticamente en inglés, es decir, no toma combinaciones de letras como en el español como la CH. Esto es un grave problema por que el atributo sort, respeta las reglas de ordenamiento, mientras que MySql ordena de la siguiente forma:

Code: Select all

Ciuidad MySQL               Ciudad Combobox
---------------------------------------------
ANTOFAGASTA                 ANTOFAGASTA
ARICA                       ARICA 
CALAMA                      CALAMA           // HASTA AQUÍ TODO BIEN
CHILLAN                     CONCEPCION       // AQUÍ APARECE EL PROBLEMA, PUESTO QUE NO SE CAMBIAN LOS NÚMEROS DE ELEMENTO EN EL ARRAY
CONCEPCION                  COPIAPO
COPIAPO                     COYHAIQUE
COYHAIQUE                   CURICO
CURICO                      CHILLAN         // Este es el caso Clásico, al seleccionar Chillán en el Combobox, este está en el número de 
IQUIQUE                     IQUIQUE         // elemento que corresponde a Curicó en el array con el orden propuesto por MySql, por lo tanto
LA SERENA                   LA SERENA       // conserva este número de elemento y el resultado no es "Chillán" como se había seleccionado
LOS ANGELES                 LOS ANGELES     // Sino Curicó como consta en los elementos del array. Usar la función aSort, sólo distorsiona
OSORNO                      OSORNO          // más la información.
PUERTO MONTT                PUERTO MONTT
PUNTA ARENAS                PUNTA ARENAS
RANCAGUA                    RANCAGUA
SANTIAGO                    SANTIAGO
SIN PLANTA                  SIN PLANTA
TALCA                       TALCA
TEMUCO                      TEMUCO
VALDIVIA                    VALDIVIA
VALPARAISO                  VALPARAISO
He buscado miles de fórmulas como solucionar este problema, y nada resulta con tablas de longitud variable de constante crecimiento.

Re: ON EDIT CHANGE en Combobox

Posted: Wed May 29, 2013 5:21 pm
by Antonio Linares
La clase combobox que hemos publicado recientemente, hace esas búsquedas automaticamente :-)

http://forums.fivetechsupport.com/viewt ... 62#p145162

Re: ON EDIT CHANGE en Combobox

Posted: Wed May 29, 2013 6:07 pm
by elmoiquique
Antonio Linares wrote:La clase combobox que hemos publicado recientemente, hace esas búsquedas automaticamente :-)

http://forums.fivetechsupport.com/viewt ... 62#p145162
Hola Antonio, te comento no funciona del todo bien,

Este es mi ejemplo como veras, el que esta bien ordenado es la primera columna, pero al buscar en el combobox solo busca el primer caracter,en la segunda columna te permite ir digitando y se va posecionando en el q es igual, pero si yo selecciono el D5100, me despliega D3200 y sin que el usuario se de cuenta, lo cual lleva a grandes errores, con el programa que tu dices no funciona muy bien porque.. al seleccionar D5200 me despliega D5200, hasta ahi bien, pero si yo vuelvo a entrar para verificar la informacion me muestra en el combobox seleccionado el D7000 como si yo la primera vez me hubiese equivocado al ingresar,
Ademas este error es muy antiguo estuve revisano lo post y esta reportado el 2008

http://forums.fivetechsupport.com/viewt ... rt#p142029

Sort=.f. Sort=.t.

D-3200 D3100
D-3200W/18 D3100W
D-7000W/18 D3200
D-90 D-3200
D3100 D-3200W/18
D3100W D5100
D3200 D5200
D5100 D7000
D5200 D7000W/18
D7000 D90
D90 D-90

Re: ON EDIT CHANGE en Combobox

Posted: Wed May 29, 2013 8:12 pm
by Antonio Linares
Quique,

Efectivamente al probar los elementos de tu array he detectado que no comprobabamos los numeros ni los guiones ni los espacios.

Con esta modificacion se comporta mucho mejor y ya esta mas cerca de lo que se desea:

Code: Select all

METHOD GetKeyChar( nKey ) CLASS TComboBox

   local nAt, cText

   if ( nKey == VK_TAB .and. ! GetKeyState( VK_SHIFT ) ) .or. nKey == VK_RETURN
      ::oWnd:GoNextCtrl( ::hWnd )
      return 0
   else   
      if nKey == VK_TAB .and. GetKeyState( VK_SHIFT )
         ::oWnd:GoPrevCtrl( ::hWnd )
         return 0
      endif
   endif
   
   if ( nKey >= Asc( "A" ) .and. nKey <= Asc( "Z" ) ) .or. ;
      ( nKey >= Asc( "a" ) .and. nKey <= Asc( "z" ) ) .or. ;
      ( nKey >= Asc( "0" ) .and. nKey <= Asc( "9" ) ) .or. ;
      Chr( nKey ) $ "- " .or. nKey == VK_BACK
      if nKey == VK_BACK
         cText = SubStr( ::oGet:GetText(), 1, ::oGet:oGet:pos - 1 )
      else
         cText = SubStr( ::oGet:GetText(), 1, ::oGet:oGet:pos - 1 ) + Chr( nKey )
      endif   
      if ! Empty( cText ) 
         if ( nAt := AScan( ::aItems, { | c | Upper( Left( c, Len( cText ) ) ) == ;
                                           Upper( cText ) } ) ) != 0
            ::oGet:SetText( ::aItems[ nAt ] )
            ::oGet:oGet:buffer = PadR( ::aItems[ nAt ], Len( ::oGet:oGet:buffer ) )
            if nKey != VK_BACK
               ::oGet:SetPos( ::oGet:oGet:pos + 1 )
            else   
               ::oGet:SetPos( ::oGet:oGet:pos )
            endif  
            return 0
         endif   
      else   
         ::oGet:SetText( "" )
         ::oGet:oGet:buffer = ""
         ::oGet:oGet:pos = 0
         ::oGet:SetPos( 0 )
      endif
   endif
   
return nKey          
 

Re: ON EDIT CHANGE en Combobox

Posted: Wed May 29, 2013 9:16 pm
by Leo
Antonio, gracias por responder y revisar, pero el problema persiste sin variación, de hecho, ahora sólo estoy con el nombre de la ciudad.

Re: ON EDIT CHANGE en Combobox

Posted: Wed May 29, 2013 9:54 pm
by elmoiquique
Hola Antonio

Gracias por responder... acabo de probar la modificacion que enviaste, pero persiste el problema....

Antes de incorporar el programa COMBOBOX.PRG, el combobox del recurso hacia lo siguiente.
Selecciono el dato del combobox, graba otra informacion y cuando lo revisava nuevamente esta el que habia seleccionado, asi que el usuario no se daba cuenta del error, porque era todo interno. solo cuando emite el informe se da cuenta

Ahora cuando incorpore el nuevo programa combobox, todo cambio
Selecciono el dato del combobox, graba la informacion correcta y cuando lo revisa aparece otra informacion, asi que ahora el usuario cree que se equivoco, pero el informe sale correcto.

Todo esto sucede al activar el sort del recurso...... al desactivarlo todo funciona bien pero la busqueda es lenta porque es practicamente manual uno a uno, hasta encontrar el que necesito

SAludos

Re: ON EDIT CHANGE en Combobox

Posted: Wed May 29, 2013 10:00 pm
by Antonio Linares
Esta version funciona mejor:

Code: Select all

METHOD GetKeyChar( nKey ) CLASS TComboBox

   local nAt, cText

   if ( nKey == VK_TAB .and. ! GetKeyState( VK_SHIFT ) ) .or. nKey == VK_RETURN
      ::oWnd:GoNextCtrl( ::hWnd )
      return 0
   else   
      if nKey == VK_TAB .and. GetKeyState( VK_SHIFT )
         ::oWnd:GoPrevCtrl( ::hWnd )
         return 0
      endif
   endif
   
   if ( nKey >= Asc( "A" ) .and. nKey <= Asc( "Z" ) ) .or. ;
      ( nKey >= Asc( "a" ) .and. nKey <= Asc( "z" ) ) .or. ;
      ( nKey >= Asc( "0" ) .and. nKey <= Asc( "9" ) ) .or. ;
      Chr( nKey ) $ "+-/=?$*&%$() " .or. nKey == VK_BACK
      if nKey == VK_BACK
         cText = SubStr( ::oGet:GetText(), 1, ::oGet:oGet:pos - 1 )
      else
         cText = SubStr( ::oGet:GetText(), 1, ::oGet:oGet:pos - 1 ) + Chr( nKey )
      endif   
      if ! Empty( cText ) 
         if ( nAt := AScan( ::aItems, { | c | Upper( Left( c, Len( cText ) ) ) == ;
                                           Upper( cText ) } ) ) != 0
            ::oGet:SetText( ::aItems[ nAt ] )
            ::oGet:oGet:buffer = PadR( ::aItems[ nAt ], Len( ::oGet:oGet:buffer ) )
            if nKey != VK_BACK
               ::oGet:SetPos( ::oGet:oGet:pos + 1 )
            else   
               ::oGet:SetPos( ::oGet:oGet:pos )
            endif  
            return 0
         endif   
      else   
         ::oGet:SetText( "" )
         ::oGet:oGet:buffer = Space( Len( ::oGet:oGet:buffer ) )
         ::oGet:oGet:pos = 0
         ::oGet:SetPos( 0 )
      endif
   endif
   
return nKey          

Re: ON EDIT CHANGE en Combobox

Posted: Wed May 29, 2013 10:01 pm
by Antonio Linares
Por que activas el sort del recurso ? Prueba a no activarlo y ordena el array antes de mostrarlo