FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Usar valor del Get en COMBOBOX para luego rellenar array
Posts: 2069
Joined: Fri Jan 06, 2006 09:28 PM

Usar valor del Get en COMBOBOX para luego rellenar array

Posted: Sat Jul 11, 2026 08:49 PM

Saludos, mi necesidad es la siguiente, tengo un COMBOBOX vacio o dbconbo con GET, necesito que al entrar un valor en el GET y dar enter, vaya a una función, alli voy buscar un una tabla con un query where y LIKE los registros coincidentes con el valor entrado en el GET y lluego con los registros que hayan, crear un array y cambiar el array vacío o el que tenga. Por el.nuevo array, y esos sean los valores a desplegar para seleccionar en el combo box.. el valor lo estoy viendo solo si le doy al botón del COMBOBOX para desplegar y necesito sea con el enter en el GET como un valid pero del GET y no del combobox .no se si eso es posible... y recuerden debo reemplazar el array del combobox por un nuevo array y liuego esos sean los valores a mostrar para seleccionar del combobox.. gracias

Dios no está muerto...



Gracias a mi Dios ante todo!
Posts: 44508
Joined: Thu Oct 06, 2005 05:47 PM

Re: Usar valor del Get en COMBOBOX para luego rellenar array

Posted: Sun Jul 12, 2026 09:17 AM

Estimado Jose Luis,

Prueba así:

#include "FiveWin.ch"

function Main()
   local oDlg, cBuscar := Space( 40 ), oCbx, aVacio := {}

   USE clientes NEW SHARED   // tu tabla

   DEFINE DIALOG oDlg TITLE "Búsqueda" SIZE 320, 200

   @ 1, 2 SAY "Buscar:" OF oDlg

   @ 3, 2 COMBOBOX oCbx VAR cBuscar ITEMS aVacio ;
      SIZE 200, 120 ;
      STYLE CBS_DROPDOWN ;          // <-- editable (con GET)
      VALID BuscarYRecargar( oCbx, cBuscar )   // se dispara al dar ENTER

   @ 3, 26 BTNBMP ... OF oDlg  // otros controles

   ACTIVATE DIALOG oDlg CENTER
return nil

function BuscarYRecargar( oCbx, cTexto )
   local aItems := {}

   cTexto := AllTrim( cTexto )

   // ===== Aquí tu QUERY WHERE ... LIKE =====
   // SQL (FWMaria/ADO/SQLite): SELECT nombre FROM clientes
   //                           WHERE UPPER(nombre) LIKE '%" + Upper(cTexto) + "%'
   //
   // Equivalente con DBF (recorriendo y filtrando con AT):
   IF ! Empty( cTexto )
      clientes->( dbGoTop() )
      WHILE ! clientes->( Eof() )
         IF AT( Upper( cTexto ), Upper( clientes->nombre ) ) > 0
            AAdd( aItems, clientes->nombre )
         ENDIF
         clientes->( dbSkip() )
      END
   ENDIF
   // =========================================

   // Reemplaza el array vacío / anterior por el nuevo:
   oCbx:SetItems( aItems, .T. )

   // (Opcional) Despliega la lista de inmediato para elegir:
   // oCbx:Open()

return .T.   // .T. para que el foco pueda salir del control

Si quieres que al dar Enter la lista se abra sola y el foco se quede en el GET (sin saltar al siguiente control), intercepta el Enter en el oGet y evitas la navegación por defecto:
// después de crear oCbx:

local bDef := oCbx:oGet:bKeyChar
oCbx:oGet:bKeyChar := { | nKey | ;
   If( nKey == 13,                                ; // VK_RETURN
      ( BuscarYRecargar( oCbx, cBuscar ),         ; // tu búsqueda
        oCbx:Set( cBuscar ),                      ; // deja el texto tecleado
        oCbx:Open(),                              ; // abre el desplegable
        0 ),                                      ; // 0 = no navegar
      Eval( bDef, nKey ) ) }                      // resto de teclas normal

Y en BuscarYRecargar haz oCbx:SetItems( aItems, .T. ) y ya no necesitas el VALID (o puedes dejarlo también; no molesta).

Si usas TDbCombo (dbcombo con GET)
El método equivalente es SetItems( aItems, aList, .T. ) (III params). Lo mismo: búscalo en VALID y reemplaza el array.
¿Quieres que te adapte el ejemplo a tu motor concreto (FWMaria/ADO/SQLite o DBF) o a TDbCombo?

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 2069
Joined: Fri Jan 06, 2006 09:28 PM

Re: Usar valor del Get en COMBOBOX para luego rellenar array

Posted: Wed Jul 15, 2026 09:44 PM

Saludos mr Antonio. Voy a probar lo que envías y luego comento.. gracias

Dios no está muerto...



Gracias a mi Dios ante todo!
Posts: 2069
Joined: Fri Jan 06, 2006 09:28 PM

Re: Usar valor del Get en COMBOBOX para luego rellenar array

Posted: Thu Jul 16, 2026 09:14 PM
Antonio Linares wrote:

Estimado Jose Luis,

Prueba así:

#include "FiveWin.ch"

function Main()
   local oDlg, cBuscar := Space( 40 ), oCbx, aVacio := {}

   USE clientes NEW SHARED   // tu tabla

   DEFINE DIALOG oDlg TITLE "Búsqueda" SIZE 320, 200

   @ 1, 2 SAY "Buscar:" OF oDlg

   @ 3, 2 COMBOBOX oCbx VAR cBuscar ITEMS aVacio ;
      SIZE 200, 120 ;
      STYLE CBS_DROPDOWN ;          // <-- editable (con GET)
      VALID BuscarYRecargar( oCbx, cBuscar )   // se dispara al dar ENTER

   @ 3, 26 BTNBMP ... OF oDlg  // otros controles

   ACTIVATE DIALOG oDlg CENTER
return nil

function BuscarYRecargar( oCbx, cTexto )
   local aItems := {}

   cTexto := AllTrim( cTexto )

   // ===== Aquí tu QUERY WHERE ... LIKE =====
   // SQL (FWMaria/ADO/SQLite): SELECT nombre FROM clientes
   //                           WHERE UPPER(nombre) LIKE '%" + Upper(cTexto) + "%'
   //
   // Equivalente con DBF (recorriendo y filtrando con AT):
   IF ! Empty( cTexto )
      clientes->( dbGoTop() )
      WHILE ! clientes->( Eof() )
         IF AT( Upper( cTexto ), Upper( clientes->nombre ) ) > 0
            AAdd( aItems, clientes->nombre )
         ENDIF
         clientes->( dbSkip() )
      END
   ENDIF
   // =========================================

   // Reemplaza el array vacío / anterior por el nuevo:
   oCbx:SetItems( aItems, .T. )

   // (Opcional) Despliega la lista de inmediato para elegir:
   // oCbx:Open()

return .T.   // .T. para que el foco pueda salir del control

Si quieres que al dar Enter la lista se abra sola y el foco se quede en el GET (sin saltar al siguiente control), intercepta el Enter en el oGet y evitas la navegación por defecto:
// después de crear oCbx:

local bDef := oCbx:oGet:bKeyChar
oCbx:oGet:bKeyChar := { | nKey | ;
   If( nKey == 13,                                ; // VK_RETURN
      ( BuscarYRecargar( oCbx, cBuscar ),         ; // tu búsqueda
        oCbx:Set( cBuscar ),                      ; // deja el texto tecleado
        oCbx:Open(),                              ; // abre el desplegable
        0 ),                                      ; // 0 = no navegar
      Eval( bDef, nKey ) ) }                      // resto de teclas normal

Y en BuscarYRecargar haz oCbx:SetItems( aItems, .T. ) y ya no necesitas el VALID (o puedes dejarlo también; no molesta).

Si usas TDbCombo (dbcombo con GET)
El método equivalente es SetItems( aItems, aList, .T. ) (III params). Lo mismo: búscalo en VALID y reemplaza el array.
¿Quieres que te adapte el ejemplo a tu motor concreto (FWMaria/ADO/SQLite o DBF) o a TDbCombo?


***********************

Antonio, uso es DBCOMMBO, fijate, el VALID se dispara al dar el ENTER, pero no lleva a la funcion, el valor entrado en el GET, pero si le doy al boton de despliegue del DBCOMBO, entonces se dispara el VALID y si lleva el valor entrado en el GET, necesito es que lo lleve al dar enter...estoy usando mysql.. gracias

REDEFINE DBCOMBO aGetLla[10] VAR aVarLla[10] ID 4004 OF oFldx:aDialogs[1] UPDATE ; // NOM.SEC.ORI
ITEMS aSecOri1 ;
LIST aSecOri2 ;
VALID ( nuevo_buscador( aVarLla[10], aGetLla[10] ) )


---------------

FUNCTION nuevo_buscador( cSecOriDes, oGetOriDes ) // NUEVO BUSCADOR DESDE DBCOMBO - 26/06/2026

? "nuevo_buscador: ", cSecOriDes

RETURN .t.

Dios no está muerto...



Gracias a mi Dios ante todo!
Posts: 44508
Joined: Thu Oct 06, 2005 05:47 PM

Re: Usar valor del Get en COMBOBOX para luego rellenar array

Posted: Fri Jul 17, 2026 08:44 AM

Estimado Jose Luis,

El síntoma que describes tiene una causa concreta en la clase TDBCombo: el VALID se evalúa a través del LostFocus, y en TDBCombo la variable enlazada (bSetGet) se actualiza después de llamar al LostFocus del padre (que es donde se dispara el VALID).

Mira el método LostFocus de TDBCombo:

source/classes/dbcombo.prg

Code (harbour): Select all Collapse
[code]METHOD LostFocus( hWndGetFocus ) CLASS TDBCombo
   local nAt := ::SendMsg( CB_GETCURSEL )
   ...
   uRet := ::Super:LostFocus( hWndGetFocus )   // <-- aquí se evalúa el VALID
   if !::lIndexVar
      Eval( ::bSetGet, uVal )                  // <-- la variable se actualiza DESPUÉS
   endif
return uRet[/code]
``` [0-cite-0](#0-cite-0) 

Cuando das ENTER, la navegación provoca el `LostFocus`, y el `VALID` corre **antes** de que `Eval( ::bSetGet, uVal )` haya volcado el texto tecleado a `aVarLla[10]`. Por eso tu primer parámetro `cSecOriDes` llega vacío/con el valor anterior. [0-cite-1](#0-cite-1) 

En cambio, cuando pulsas el botón de despliegue y seleccionas, se dispara `Change()`, que sí hace `Eval( ::bSetGet, ... )` y `::oGet:VarPut( Eval( ::bSetGet ) )` **antes** de perder el foco, por eso ahí sí llega el valor correcto. [0-cite-2](#0-cite-2) 

## Solución

No dependas de la variable enlazada dentro del `VALID`; lee el texto directamente del control. En tu `VALID` ya estás pasando el objeto del combo (`aGetLla[10]`), así que usa su método `GetText()` (que devuelve el texto real del edit del combo, como se ve en `ListGet`): [0-cite-3](#0-cite-3) 

```harbour
[code]REDEFINE DBCOMBO aGetLla[10] VAR aVarLla[10] ID 4004 OF oFldx:aDialogs[1] UPDATE ;
   ITEMS aSecOri1 ;
   LIST  aSecOri2 ;
   VALID ( nuevo_buscador( aGetLla[10] ) )

FUNCTION nuevo_buscador( oGetOriDes )
   LOCAL cTexto := AllTrim( oGetOriDes:GetText() )   // texto tecleado real
   ? "nuevo_buscador: ", cTexto
   // ... aquí tu SELECT ... WHERE ... LIKE '%' + cTexto + '%' (MySQL)
RETURN .t.[/code]

Así, tanto en ENTER como al desplegar, GetText() te devuelve lo que hay escrito en el GET del combo, sin depender del orden en que se actualiza aVarLla[10].

Si prefieres seguir usando la variable, otra opción es forzar el volcado antes de buscar dentro de la función: oGetOriDes:oGet:GetText() sobre el oGet interno del control da el mismo resultado.

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 2069
Joined: Fri Jan 06, 2006 09:28 PM

Re: Usar valor del Get en COMBOBOX para luego rellenar array

Posted: Fri Jul 17, 2026 06:06 PM

Saludos, Antonio reviso. Pruebo ...y luego comento.. gracias

Dios no está muerto...



Gracias a mi Dios ante todo!
Posts: 2069
Joined: Fri Jan 06, 2006 09:28 PM

Re: Usar valor del Get en COMBOBOX para luego rellenar array

Posted: Tue Jul 21, 2026 08:31 PM
Antonio Linares wrote:

Estimado Jose Luis,

El síntoma que describes tiene una causa concreta en la clase TDBCombo: el VALID se evalúa a través del LostFocus, y en TDBCombo la variable enlazada (bSetGet) se actualiza después de llamar al LostFocus del padre (que es donde se dispara el VALID).

Mira el método LostFocus de TDBCombo:

source/classes/dbcombo.prg

Code (harbour): Select all Collapse
[code]METHOD LostFocus( hWndGetFocus ) CLASS TDBCombo
   local nAt := ::SendMsg( CB_GETCURSEL )
   ...
   uRet := ::Super:LostFocus( hWndGetFocus )   // <-- aquí se evalúa el VALID
   if !::lIndexVar
      Eval( ::bSetGet, uVal )                  // <-- la variable se actualiza DESPUÉS
   endif
return uRet[/code]
``` [0-cite-0](#0-cite-0) 

Cuando das ENTER, la navegación provoca el `LostFocus`, y el `VALID` corre **antes** de que `Eval( ::bSetGet, uVal )` haya volcado el texto tecleado a `aVarLla[10]`. Por eso tu primer parámetro `cSecOriDes` llega vacío/con el valor anterior. [0-cite-1](#0-cite-1) 

En cambio, cuando pulsas el botón de despliegue y seleccionas, se dispara `Change()`, que sí hace `Eval( ::bSetGet, ... )` y `::oGet:VarPut( Eval( ::bSetGet ) )` **antes** de perder el foco, por eso ahí sí llega el valor correcto. [0-cite-2](#0-cite-2) 

## Solución

No dependas de la variable enlazada dentro del `VALID`; lee el texto directamente del control. En tu `VALID` ya estás pasando el objeto del combo (`aGetLla[10]`), así que usa su método `GetText()` (que devuelve el texto real del edit del combo, como se ve en `ListGet`): [0-cite-3](#0-cite-3) 

```harbour
[code]REDEFINE DBCOMBO aGetLla[10] VAR aVarLla[10] ID 4004 OF oFldx:aDialogs[1] UPDATE ;
   ITEMS aSecOri1 ;
   LIST  aSecOri2 ;
   VALID ( nuevo_buscador( aGetLla[10] ) )

FUNCTION nuevo_buscador( oGetOriDes )
   LOCAL cTexto := AllTrim( oGetOriDes:GetText() )   // texto tecleado real
   ? "nuevo_buscador: ", cTexto
   // ... aquí tu SELECT ... WHERE ... LIKE '%' + cTexto + '%' (MySQL)
RETURN .t.[/code]

Así, tanto en ENTER como al desplegar, GetText() te devuelve lo que hay escrito en el GET del combo, sin depender del orden en que se actualiza aVarLla[10].

Si prefieres seguir usando la variable, otra opción es forzar el volcado antes de buscar dentro de la función: oGetOriDes:oGet:GetText() sobre el oGet interno del control da el mismo resultado.

Saludos Antonio, lamentablemente o no supe como hacerlo o no funciono lo que me sugeriste, ya que aunque haga AllTrim( oGetOriDes:GetText(), en la funcion donde envio el oGet que es buscador(), solo muestra el valor del GET cuando se dispara el VALID que es cuando le doy al boton de despliegue... voy seguir haciendo prueba, lo que no quiero es hacer otro GET ya que el mismo DBCOMBO trae y asi evito dos objetos, si no hay manera, tendre que hacerlo, pero espero alguna otra sugerencia a ver..gracias

Dios no está muerto...



Gracias a mi Dios ante todo!

Continue the discussion