Problema con COMBOBOX

16 views
Skip to first unread message

avazq...@gmail.com

unread,
Feb 12, 2026, 4:25:22 AMFeb 12
to avazq...@gmail.com

Tengo las siguientes tablas:

CREATE TABLE `pagocli` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `idcliente` int(11) unsigned DEFAULT 0,

  `fecha` date DEFAULT NULL,

  `tipopago` enum('1.- Caja','2.- Banco','3.- Efecto','4.- Visa') DEFAULT '1.- Caja',

  `concepto` smallint(6) unsigned DEFAULT 1,

  `motivo` varchar(60) DEFAULT ' ',

  `debe` decimal(11,2) DEFAULT 0.00,

  `haber` decimal(11,2) DEFAULT 0.00,

  `visa` decimal(11,2) DEFAULT 0.00,

  `bizum` decimal(11,2) DEFAULT 0.00,

  `banco` smallint(4) DEFAULT 0,

  `ctabanco` varchar(9) DEFAULT ' ',

  `numjustifi` int(11) DEFAULT 0,

  PRIMARY KEY (`id`),

  KEY `idx_pagocli_idcliente` (`idcliente`)

) ENGINE=InnoDB AUTO_INCREMENT=3735 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;

CREATE TABLE `tabconcecli` (

  `id` smallint(6) unsigned NOT NULL AUTO_INCREMENT,

  `idconceban` smallint(6) DEFAULT 3,

  `papelnomb` char(40) DEFAULT NULL,

  `tipo_pago` tinyint(3) unsigned NOT NULL DEFAULT 0,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=323 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;

Relación
pagocli.concepto = tabconcecli.id

Tengo el siguiente formulario frmpagocli
DEFINE WINDOW TEMPLATE ;

    AT 309,144 ;

    OBJ opago ;

    WIDTH 456 ;

    HEIGHT 472 ;

    BACKCOLOR Gris_Nono ;

    FONT 'MS Sans Serif' ;

    SIZE '10' ;

    ICON 'Bandera' ;

    MODAL ;

    TITLE 'Datos del Apunte'

@ 53,20 LABEL l_tipocobro VALUE 'Tipo Cobro' WIDTH 70 HEIGHT 20

@ 50,107 COMBOBOX C_TIPOPAGO ;

   WIDTH 150 HEIGHT 120 ;

   OBJ o_c_tipopago ;

   ITEMS lee_enum("pagocli","tipopago") ;

   value 1;

   ON CHANGE {|| o_concepto_pago:DeleteAllItems(), CargaConceptos( o_c_tipopago:Value ) }

  

@ 83,20 LABEL l_concepto VALUE "Concepto:" WIDTH 70 HEIGHT 20

@ 83,107 COMBOBOX C_CONCEPTO ;

   WIDTH 200 HEIGHT 150 ;

   OBJ o_concepto_pago ;

   ITEMS {}

END WINDOW

 

 

Function main()

LOAD WINDOW frmpagocli

CENTER WINDOW frmpagocli

               nTipoPago := 1

               // Ahora cargar conceptos

               CargaConceptos( o_c_tipopago:Value )
ON KEY ESCAPE OF frmpagocli ACTION { || frmpagocli.release }

ACTIVATE WINDOW frmpagocli

 

 

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

FUNCTION CargaConceptos( nTipoPago )

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

LOCAL aDatos:={}

LOCAL i

LOCAL nDefault

LOCAL nPos := 0

 

// Obtener conceptos del tipo seleccionado

aDatos := GetRows( ;

   'SELECT id, papelnomb FROM tabconcecli ' + ;

   'WHERE tipo_pago=' + LTrim(Str(nTipoPago)) + ;

   ' ORDER BY papelnomb', .f. )

 

// Limpiar completamente el combo

o_concepto_pago:DeleteAllItems()

 

// Si no hay datos salir

IF Empty(aDatos) .OR. Len(aDatos[1]) == 0

               msginfo("VACÍO, CONSULTA CON NONO")

               RETURN NIL

ENDIF

 

// Obtener ID por defecto según tipo

nDefault := Int( DefaultConceptoPorTipoPago( nTipoPago ) )

nPos:=0

// Añadir items al combo

FOR i := 1 TO Len(aDatos[1])

   o_concepto_pago:AddItem( ;

      AllTrim(aDatos[2][i]), ;   // texto

      Int(aDatos[1][i]) )        // id real

 

   IF int(aDatos[1][i]) = int(nDefault)

      nPos := i

   ENDIF

NEXT

 

// Si no existe usar el primero

IF nPos = 0

   nPos := 1

ENDIF

// Asignar posición correcta

o_concepto_pago:Value := nPos

 

RETURN NIL

 

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

FUNCTION DefaultConceptoPorTipoPago(nTipoPago)

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

DO CASE

   CASE nTipoPago == 1

       RETURN ado_value('SELECT id FROM tabconcecli WHERE papelnomb="A CUENTA CAJA"')

   CASE nTipoPago == 2

       RETURN ado_value('SELECT id FROM tabconcecli WHERE papelnomb="A CUENTA TRANSFERENCIA"')

   CASE nTipoPago == 3

       RETURN ado_value('SELECT id FROM tabconcecli WHERE papelnomb="A CUENTA EFECTO"')

   CASE nTipoPago == 4

       RETURN ado_value('SELECT id FROM tabconcecli WHERE papelnomb="A CUENTA VISA"')

ENDCASE

 

RETURN 0


- Cuando cambio el combo c_tipopago de valor, quiero que me refresque o_concepto_pago y que se me posicione en el ítems por defecto.

 

O_concepto_pago:value no me toma el valor de nPos.
La primera vez sí, pero las siguientes da valor 0.

Qué me falta?

 

Gracias

Saludos.

Antonio Vázquez

Antonio Vázquez

unread,
Feb 12, 2026, 5:31:32 AMFeb 12
to [oohg]
Por si es de utilidad.
Valores de la tabla tabconcecli


id               
idconceban                papelnomb                                                  tipo_pago

1                        
3                         SALDO INICIAL                                                  1

2                       
3                         ANTICIPO CLIENTES                                        1

4                        
3                         VENTA CREDITO                                                0

5                        
3                         VENTA CONTADO                                              0

6                        
3                          A CUENTA CAJA                                               1

7                       
3                         DESCUENTO                                                       1

8                        
3                         A CUENTA TRANSFERENCIA                           2

9                        
3                         A CUENTA EFECTO                                            3

10                     
3                          DEVOLUCION                                                      1

322                   3                         A CUENTA VISA                                                  4


Gracias
Saludos
Antonio Vázquez

Ciro Vargas C

unread,
Feb 12, 2026, 11:24:58 PMFeb 12
to oo...@googlegroups.com

Hola Antonio

Mira si esto funciona...

El problema que describes (que funciona la primera vez pero falla al cambiar el combo posteriormente) es muy común en entornos de gestión de ventanas en Harbour/HwGUI/MiniGUI.

Cuando modificas los items de un ComboBox (`DeleteAllItems` y `AddItem`) **mientras la ventana ya está activa y visible**, el control a veces necesita ser forzado a "repintarse" o actualizar su buffer interno antes de que puedas asignarle un nuevo valor (`Value`) correctamente. Si asignas el valor antes de que el control reconozca que tiene nuevos items, la asignación se ignora o se resetea a 0.

Aquí tienes la solución y una pequeña optimización:

### Solución

1.  Añade `o_concepto_pago:Refresh()` justo después del bucle `FOR` y **antes** de asignar el valor.
2.  Elimina la llamada a `DeleteAllItems` dentro del evento `ON CHANGE` del primer combo, ya que tu función `CargaConceptos` ya lo hace (evitas llamarlo dos veces).

### Código Corregido

Modifica la definición del window y la función así:

**1. En la definición del `WINDOW` (Quita el `DeleteAllItems` del evento):**

```clipper

@ 50,107 COMBOBOX C_TIPOPAGO ;
   WIDTH 150 HEIGHT 120 ;
   OBJ o_c_tipopago ;
   ITEMS lee_enum("pagocli","tipopago") ;
   value 1;
   // ELIMINADO: o_concepto_pago:DeleteAllItems()
   ON CHANGE {|| CargaConceptos( o_c_tipopago:Value ) }
```

**2. En la función `CargaConceptos` (Añade el `Refresh`):**

```clipbit
FUNCTION CargaConceptos( nTipoPago )
// ---------------------------------------------------
// SOLUCIÓN CLAVE: Forzar la actualización del control
// ---------------------------------------------------
o_concepto_pago:Refresh()


// Si no existe usar el primero
IF nPos = 0
   nPos := 1
ENDIF

// Asignar posición correcta
o_concepto_pago:Value := nPos

// (Opcional) Asegurar que se vea el cambio visualmente
// o_concepto_pago:Refresh()

RETURN NIL
```

### ¿Por qué fallaba?
Al ejecutarse la primera vez desde el `Main`, la ventana aún no se ha pintado completamente en pantalla (`ACTIVATE WINDOW` aún no ha devuelto el control al bucle de eventos), por lo que la carga de datos se hace en memoria y el control acepta el `Value` sin problemas.

Cuando ya estás interactuando con la ventana (evento `ON CHANGE`), el control `ComboBox` está "vivo". Si borras y añades items, el control puede desincronizarse momentáneamente. La instrucción `o_concepto_pago:Refresh()` obliga al control a validar su nueva lista de items, haciendo que la siguiente asignación `o_concepto_pago:Value := nPos` surta efecto.

saludos
Ciro


--
Has recibido este mensaje porque estás suscrito al grupo "[oohg]" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a oohg+uns...@googlegroups.com.
Para ver este debate, visita https://groups.google.com/d/msgid/oohg/cdda8b60-613c-4424-b222-8f2838473f82n%40googlegroups.com.


--
Reply all
Reply to author
Forward
0 new messages