Problema para cargar un combobox con un cursor

Tengo que cargar en un formulario un combo con ciudades, para esto tengo un método en una clase ciudadesDatos que me devuelve un cursor con todas las ciudades :
FUNCTION buscarCiudades()
IF !USED("ciudad")
USE ciudad IN 0 SHARED
ENDIF
SELECT *;
FROM ciudad INTO CURSOR cCiudad
IF _tally = 1
resp = 'cCiudad'
ELSE
resp = null
ENDIF
USE IN ciudad
RETURN resp
ENDFUNC
en el formulario en el init pongo
ciu = NEWOBJECT("ciudadNegocio", "classCiudad.prg")
ciud = ciu.buscarCiudades()
y en un metodo llenarfourmulario pongo
SELECT ciud
LOCATE FOR id_ciudad = thisform.obj.id_ciudad_d &&para pocicionarlo en && un registro seleccionado
thisform.combo_destino.ControlSource = ciud
thisform.combo_destino.RowSource = ciud.id_ciudad
thisform.combo_destino.Refresh()
El problema es que no me carga nada, como si el cursor estuviese vacío..

2 Respuestas

Respuesta
1
Órale, me parece un poco extraña la forma como estás haciendo las cosas pero al fin de cuentas es posible y si así quieres hacerlo, está bien.
Según lo que veo, el problema es que te falta especificar la propiedad "RowSourceType" del combo, te recomiendo que la pongas como "2 - Alias", para que jale los datos directamente de la tabla, o cursor en este caso. La propiedad "ControlSource" está de más, la puedes quitar, a no ser que quieras que se pueda modificar la tabla directamente desde el combo.
Por otro lado, no entiendo bien para qué creas un cursor de la tabla, si al fin de cuentas tienen los mismos datos, tal vez sería mejor enlazar el combo directamente con la tabla, pero bueno, puedes tener tus razones para hacerlo y es completamente válido.
Básicamente esto es lo que ocupas configurar en el combo:
ThisForm.Combo_Destino.RowSourceType = 2
ThisForm.Combo_Destino.RowSource = "ciud.ciud"
Nota que cuando selecciones una opción del combo, la tabla se posicionará en el registro correspondiente, con lo cual puedes acceder a cualquier dato de dicho registro. Así podrías obtener el "Id" después de haber seleccionado una opción:
nIdCiudad = ciud.id_ciudad
Disculpa mi ignorancia, pero me sigue sin andar.. lo tengo que hacer de esa manera, porque es un trabajo para una materia de la facultad, y tengo que programar en capas, o sea no puedo llamar desde el formulario directo a las tablas, sino que tengo que tener una clase de datos que se comunique con las tablas..
La siguiente sentencia de devuelve datos
FUNCTION buscarCiudades()
IF !USED("ciudad")
USE ciudad IN 0 SHARED
ENDIF
SELECT *;
FROM ciudad INTO CURSOR cCiudad
IF _tally = 1
resp = 'cCiudad'
ELSE
resp = null
ENDIF
USE IN ciudad
RETURN resp
ENDFUNC
pero puede ser q cuando hago esto:
ciu = NEWOBJECT("ciudadNegocio", "classCiudad.prg")
ciud = ciu.buscarCiudades()
ciud quede vacio??
Desde ya muchas gracias!
Te cuento, hice como me dijiste y el combo sigue estando vacío. Para ver si el cursor tiene registros, lo que hice fue:
IF RECCOUNT(ciud)=0
MESSAGEBOX("malllll")
ELSE
MESSAGEBOX("biennnn")
Endif
Cursor si tiene registros, por lo tanto algo de
ThisForm.Combo_Destino.RowSourceType = 2
ThisForm.Combo_Destino.RowSource = "ciud.id_ciudad"
Me esta fallando..
Gracias!
Saludos..
Sí, viéndolo bien creo que se me pasaron algunos detalles.
Para empezar, la variable "_tally" te devuelve el número de registros afectados por la última instrucción (de algunas instrucciones de Fox) ejecutada. En este caso tendría el número de registros que obtenga la consulta, es muy probable que no sea uno y entonces tu condición no funcionará adecuadamente. Creo no tiene mucho caso hacer esta evaluación, pues de cualquier forma, aunque la consulta no regrese ningún registro, el cursor se generará y no se mostraran errores. Ahora que si debes hacerlo, haz la comparación así "IF _tally > 0" para que no suceda esto.
Otro detalle que se me pasó es que, en el "RowSource" del combo, debes poner el nombre del campo que quieres que se muestre. Yo utilicé el "ciud.ciud" (tabla "ciud" campo "ciud") pero para empezar "ciud" es una variable de tipo cadena que tiene el nombre del cursor generado y realmente no sé si exista un campo con el nombre "ciud" en dicho cursor, debes asegurarte que sea uno válido. Podría quedar algo así:
** Método "llenarfourmulario"
SELECT (ciud) && ya que "ciud" es una variable que contiene el nombre del cursor
LOCATE FOR id_ciudad = thisform.obj.id_ciudad_d
thisform.combo_destino.RowSourceType = 2
thisform.combo_destino.RowSource = ciud + "id_ciudad"
Aunque de cualquier forma se me hace raro, porque si no hubiera existido algo, me imagino que te habría marcado un error.
Sí después de esto, el problema persiste, puedes intentar lo siguiente para depurar la aplicación:
<ul>
<li>Fíjate que valor tiene la variable "cuid" después de ejecutar la función "cui.buscarCiudades()".</li>
<li>Fíjate si el cursor tiene datos, para lo cual puedes poner lo siguiente después de mandar llamar a la función:
SELECT (ciud)
BROWSE LAST</li>
</ul>
Muchas gracias! Ahora el combo se me carga!
Una pregunta más, yo pensé que con el locate for el cursor se hubicaba en un registro, y el combo se cargaba seleccionado en ese registro.. no se si me explico.. esto no me esta pasando, el combo se me carga pero la selección queda en blanco. ¿Esta bien la manera que lo estoy haciendo (con el locate)? ¿Hay otra manera que el combo aparezca con registro seleccionado?
Disculpa que haga tantas preguntas, pero es algo que no lo encontré en google.. je
Muchas gracias!
Saludos.
Sí, entiendo. Para especificar que opción del combo quieres que aparezca seleccionada debes especificar la propiedad "ListIndex" del control, la cual indica, mediante enteros, el número del elemento de la lista que está seleccionado.
En este caso, si tu tabla no está ordenada de ninguna forma, podrías usar el número de registro actual después del "LOCATE" para indicarle al combo cuál elemento debe estar seleccionado.
LOCATE FOR id_ciudad = thisform.obj.id_ciudad_d
nIndice = RECNO()
ThisForm.Combo_Destino.ListIndex = nIndice
Respuesta
1
Disculpa la demora.
Prueba utilizar
SELECT (cCiudad)
***Suerte***

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas