Problemas con búsqueda en formulario wizard

Hola Experto. ¿Me podes ayudar con mi problema? Diseñe un formulario a través del wizard. El tema es que la clase me genera el formulario de búsqueda con dos parámetros. Esto es, un campo, un operador, un valor; y debajo otra vez campo, operador y valor, para recién ir al botón de buscar. ¿Cómo puedo hacer para que quede un solo parámetro (es decir eliminar el segundo)? ¿O existe alguna clase ya diseñada a tal efecto? Gracias por tu tiempo y te agradezco de antemano. Disculpá mis escasos conocimientos.

4 respuestas

Respuesta
1
Es probable que el formulario se haya generado de esa forma debido a la cantidad de campos que tú has seleccionado de alguna de tus tablas en el proceso de diseño del wizard.
Lo que puedes hacer es volver a ejecutar el asistente y selecciona sólo uno (1) campo de tu tabla.
Experto. Antes que nada, muchas gracias por tu disposición. Te comento que hice lo que me indicaste. Seleccione un solo campo de índice y antes un solo campo de datos, pero al generar el formulario me sigue generando una pantalla de búsqueda con dos parámetros de alternativa y como te dijera antes, necesito limitarla a un solo campo. De metido nomas, ingresé a la clase wizbtns (searchform y searchclass) y los formularios tienen dos campos de búsqueda, tal cual me lo desarrolla el generador de formularios.
¿Tiene esto algo que ver? Te agradezco mucho tu tiempo. Gracias. Carlos
Si, tu observación es acertada.
Si la clase está creada de esta forma no vas a poder solucionarlo desde el wizard.
La verdad no estoy familiarizado con los asistentes, pero probemos lo siguiente:
Edita el formulario de búsqueda que creaste con el asistente, selecciona los objetos que forman el segundo parámetro, toma nota de sus nombres en un papel y elimínalos del formulario.
Luego haz doble click en el formulario para que se abra la ventana de edición de código y mediante ctrl + F busca los nombres de los objetos eliminados en todos los procedimientos.
Si encuentras referencias a ellos debes eliminarlas del código para que no te genere error.
Prueba con esto y vemos.
Suerte.
Experto. Te sigo molestando. Hice lo que me aconsejaste y modifique la clase wizbtns que soporta la búsqueda en el formulario que cree con el asistente. Tras múltiples modificaciones a lo más lejos que llegué es que me realice la busque por un solo parámetro, pero en muchas oportunidades y en forma aleatoria me indica tres mensajes de error en forma sucesiva (El subíndice está fuera del intervalo definido, Incompatibilidad entre el tipo de operador y el tipo de operando, y por último, nuevamente el último mensaje de error citado). He agotado, creo, todas las alternativas de seguimiento pero no puedo localizar que omití en la modificación de la clase. Si sos tan amable de sugerirme como puedo seguir te lo agradecería, o bien que otra alternativa ponderas. Nuevamente, gracias por tu tiempo. Carlos.
Uuff, qué problema !
Espero que hoy podamos resolverlo:
Me parece que no sería una mala idea hacer el formulario de búsqueda personalizado a tus necesidades, sin utilizar el asistente, y utilizando el método de programación orientada a objetos.
Si te parece, en esto sí te puedo ayudar.
Gracias Experto, desde ya que agradecería tu ayuda en lo que sugerís. Te cuento que el formulario generado por el asistente contiene información de una base de datos de clientes. En algunos casos el cliente se repite, por lo que la actualización del formulario tras la búsqueda debiera permitirme el uso del botón siguiente y anterior. El rango de búsqueda pueden ser diferentes parámetros, por ej. apellido, dni, u otro. No sé si fui claro. Gracias de antemano por tu tiempo.
Vamos a realizar los pasos para crear tu formulario:
Lo primero que necesitamos es:
1) ¿Deseas agregar los controles de búsqueda a un formulario existente?
2) ¿Deseas crear un nuevo formulario de búsqueda?
Experto, buenas tardes. Te confirmo que conservo el formulario existente, al cual interpreto, debo agregarle controles nuevos de búsqueda. Asimismo creo, se debiera crear un nuevo formulario de búsqueda, como pequeña pantalla, que actualice los datos en el formulario. Gracias por tu tiempo y ayuda. Carlos
Cuéntame un poco cómo es tu formulario existente por favor:
¿Tiene un grid?, ¿El grid está vinculado a una tabla o a un cursor?
¿Qué otros controles tiene tu formulario?
Aguardo tu respuesta
Experto. Te comento que el formulario no tiene grid. Contiene información sobre clientes (Mi actividad es la de seguros; básicamente y en su mayoría información de automóviles. Apellido y nombre, dirección, teléfono, iva, datos de los vehículos, n° motor, patente, etc.). Los datos se visualizan en el formulario el cual contiene tres solapas de page (creo que así se denomina), dado que es mucha información para una sola pantalla. El posicionamiento lo realizo a la fecha con el buscador que me genero el asistente, al crear el formulario. Dado que poseo algunos clientes con más de un vehículo, utilizo el botón de Continuar y Anterior para posicionarme. Espero haber sido claro. Gracias. Carlos.
Perdón por la demora en responder.
Estoy con muchísimo trabajo y realmente no quiero responder a las apuradas.
Veamos si he comprendido bien:
Entiendo que tu formulario tiene varias pestañas (pages) en la que muestras la información y permites editarla. Ese sería el formulario de edición de datos.
Supongo que antes de que se abra el formulario de edición tienes otro, que quizás contenga un indice en un control grid, y un botón buscar y otro editar, para puedas seleccionar el registro y luego editarlo.
¿Está bien así?
¿Es este tu caso?
Experto. No tenés que pedir disculpa alguna. Yo soy el que esta abusando de tu tiempo. Te comento que la edición la realizo a través de otro formulario. El que está en cuestión, efectivamente tiene pestañas (tres). Este formulario es para simple visualización de datos. Al ingresar al programa, este abre este formulario y se posiciona en el primer registro de la base de datos (no es derivado por ningún grid). A partir de allí ubico el registro del cliente que necesito ver. Si el cliente tuviera más de un seguro contratado, con el botón continuar accedo al siguiente registro, o la inversa, vuelvo con el botón Anterior. La pantalla de búsqueda, que como te dijera, fue generada por el asistente, me permite ubicar el registro por el campo que elija de la base (combobox creo que se llama), luego el operador (igual, no igual, contiene, etc.) y por último un cuadro para ingresar el texto a buscar. Con el clickeo en buscar se cierra la pequeña pantalla de búsqueda y el formulario antedicho queda posicionado en el cliente. Si la búsqueda fuera infructuosa, aparece la leyenda que no encontró registro con esos parámetros. El problema radica en que este sistema de búsqueda, reitero, generada por el asistente, me duplica los parámetros de búsqueda (campo, operador y valor) concatenados con el operador Y/O. Esta duplicidad genera pérdida de tiempo adicional ya que el botón de buscar se encuentra al final, por lo que con el Enter debo pasar por todos los items, sino caer obligadamente en el mouse. Estaría bueno este sistema de búsqueda si el botón de búsqueda para clicklear estuviera tras el primer nivel de búsqueda y no al final. Cual sería el problema de uso del mouse, ¿dirás? Este programita lo usa también mi padre, de 83 años. Entenderás la dificultad que tiene en el uso del mouse, más considerando su artrosis en las manos. Disculpas si abundé en detalles. No sé si alcancé a ser lo suficientemente descriptivo en mi problemática. Gracias nuevamente. (obs.: Primero ocupate de tu trabajo, y en tu tiempo libre, si deseas ayudarme, respondéme. Nadie se ofende por ello).
Ok. Cómo hubicas el registro que necesitas ver, ¿tienes un botón buscar que te abre el formulario de búsqueda?
¿Creo qué es así verdad?
Suponiendo que así fuera debes crear un formulario de similares dimensiones al que te crea el asistente.
Ahora cuéntamen cómo quieres realizar la búsqueda:
¿La búsqueda debe devolver valores exactos o siminares?
¿Cuál es el valor que buscas con mayor frecuencia: el apellido del cliente, ...?
¿Tu formulario de búsqueda tiene alguna cuadro donde visualizas los resultados?
Aguardo tus comentarios.
Experto. El formulario contiene un botón BUSCAR. Al oprimirlo se abre el formulario de búsqueda, como ventana más pequeña, sobre el otro formulario. El actual que tengo permite elegir que campo de la base de datos. Por defecto esta en apellido del cliente. Luego el operador, y por último el cuadro de texto para introducir por teclado, en este caso el apellido. Debajo hay un botón de buscar. Si no lo encuentra advierte esto. Sino, se cierra el pequeño formulario de búsqueda citado y queda el otro (que quedaba debajo), actualizado con los datos de ese cliente. Gracias Experto.
Vamos a tratar de resolver el problema:
Deberemos crear un formulario nuevo (no con el asistente) de dimensiones similares al formulario de búsqueda que te genera el asistente.
Deberemos agregarle los controles label y txtbox necesarios para introducir los valores del nombre del campo, operador y valor a buscar.
Luego, más abajo deberás agregar a tu formulario el botón buscar y el botón cancelar.
Finalmente estiliza tu formulario para darle la apariencia que te guste, utilizando el cuadro de propiedades.
Una vez que hayas finalizado el diseño del formulario me avisas para que te pase el código para cada objeto.
Experto. Ya tengo diseñado el formulario con los tres label y txtbox. Gracias.
Repasemos entonces, tienes los siguientes controles:
1) Un Label. Caption: "Campo:"
2) Un Combobox. Campo. Establece la propiedad rowsourcetype de este combobox en 8 (estructura), y la propiedad rowsource debe ser el nombre de la tabla cuya estructura deseas mostrar.
3) Un combobox. Operator. A este combobox deberás realizarle los siguientes ajustes en en cuadro de propiedades:
a) Columncount=2
b) Columnlines= .F.
c) Columnwidths= 40,150 (aproximadamente)
Luego haz doble click en el control combobox para que se abra la ventana de edición de código y busca el evento init del control. Allí deberás escribir los siguientes comandos:
this.addlistitem ("<", 1, 1)
this.addlistitem ("Menor que", 1, 2)
this.addlistitem (">", 2, 1)
this.addlistitem ("Mayor que", 2, 2)
this.addlistitem ("=", 3, 1)
this.addlistitem ("Igual que", 3, 2)
this.addlistitem ("#", 4, 1)
this.addlistitem ("Distinto que", 4, 2)
this.addlistitem ("<=", 5, 1)
this.addlistitem ("Menor o Igual que", 5, 2)
this.addlistitem (">=", 6, 1)
this.addlistitem ("Mayor o Igual que", 6, 2)
4) Un TxtBox.Valor: donde introducirás el valor a buscar.
5) Botón buscar: En el evento click de tu botón buscar deberás escribir el siguiente código:
thisform.mousepointer=11
* variables locales *
local lcCampo, lcOperator, lcValue
lcCampo=alltrim(thisform.cmbocampo.value)
lcOperator=alltrim(thisform.cmbooperator.value)
lcValue=alltrim(thisform.txtvalor.value)
* busca el registro *
select mitabla
set order to lcCampo
locate for &lcCampo &lcOperator lcValue
* libera variables locales *
Release lcCampo, lcOperator, lcValue
Thisform. Release
thisform.mousepointer=0
Bueno espero sea esto lo que necesitas.
Experto. Muchas gracias. Cargué los códigos que gentilmente me proporcionaste. Asimismo agregué un botón de cancelación. Asimismo un botón para Continuar la búsqueda con skip, y otro para volver al Anterior. Al buscar por los campos índices de la tabla me realiza la búsqueda, pero si ingreso un campo que no integra el índice me advierte "No se encuentra la etiqueta de índice" (trabajo con una base .dbf). Por otro lado al clickear el botón de Continuar la búsqueda, cuando termina de mostrar cada registro del parámetro, continúa mostrando el resto de los registros, y que no responden al parámetro ingresado (obviamente igual sucede con el botón Anterior). ¿Existe alguna forma de limitar el Siguiente o Anterior a los registros específicos del dato ingresado a buscar? (Creo por lo que vi en el asistente para generar formularios que lo haría el set filter to.). Gracias por tu tiempo, si es que dispones del mismo para ayudarme. Sino todo bien. Gracias. Carlos
Nos hemos acercado bastante.
En cuanto al problema de los campos no indizados, generalmente no necesitamos utilizarlos para búsquedas. Sin entrar en mayor complejidad te sugiero, si te parece bien, que en lugar de tomar la estruc tura de la tabla como origen de datos para tu combobox, limpies los valores de las propiedades rowsourcetype y rowsource del combobox y agregues los valores manualmente en el evento init del combobox, tal como hiciste con el segundo combobox.
En cuanto al comportamiento de los botones Siguiente o Anterior la solución, como tú dices es filtrar la tabla. Esto no es muy recomendable en tablas con grandes cantidades de registros. Aunque en tu caso solucionarías los dos problemas.
Si decides filtrar la tabla omite el consejo del primer párrafo, y lo único que debes hacer para resolver ambos problemas es cambiar la siguientes líneas de código.
* busca el registro *
select mitabla
set order to lcCampo
locate for &lcCampo &lcOperator lcValue
por estas otras:
* filtrar tabla *
select mitabla
set filter to &lcCampo &lcOperator lcValue
Prueba y me cuentas.
Experto. Modifiqué el buscador de acuerdo a tus instrucciones. En cuanto al filtrado, realicé las correcciones, y se posiciona en el primer registro, pero el botón de Continuar o Anterior me da mensaje de error: No se encuentra la variable 'LCVALUE' (Los botones tienen la consigna SKIP 1 y SKIP -1 en el procedimiento Click). ¿En qué me equivoqué? Gracias Experto. Carlos
Perdón, es mi error, estamos liberando una variable que sirve de parámetro para el filtrado.
Vamos a tener que cambiar la forma de definir la variable lcValue
Quita la variable lcvalue del comando Local y del comando release del evento click del botón buscar.
Luego ve al evento init del formulario y escribe Public lcValue, después ve al evento destroy del form y escribe release lcValue
Finalmente presiona las teclas ctrl + f para buscar dentro del código de tu formulario y en el cuadro de búsqueda escribe lcValue, luego presiona el botón reemplazar y escribe pcValue, asegúrate de que el alcance de la búsqueda sea todos los objetos y luego dale clic a reemplazar todo.
Con esto hemos cambiado la variable de local a publica, de esta manera estará activa durante los filtrados.
Prueba y me avisas.
Experto. Dejé un formulario de búsqueda con set order y el otro con set filter para tener mayor variedad de forma de búsquedas. En cuanto al último código para el formulario con filtrado que gentilmente me pasaste, para su funcionamiento debí eliminar el release pcValue del evento Destroy del formulario de búsqueda (Sino me advierte que "no encuentra la variable pcValue). Así me limita los registros a los parámetros de búsqueda deseados. El único inconveniente lo obtengo cuando llego a los extremos de la base de datos, donde me advierte por mensaje de error el final o inicio de la tabla. Intenté con EOF() pero si continúo pulsando el Continuar me actualiza un registro con todos los campos en blanco y otro error en Anterior con BOF(). Indudablemente estoy cometiendo algún tipo de error. Gracias nuevamente por tu disposición. Carlos
Es correcto lo que hiciste con la variable del filtrado
En cuando al problema de Siguiente / Anterior vas a necesitar agregar código para deshabilitar los controles de tu formulario en caso de no encontrá registros coincidentes, o cuando se alcance el encabezado o final de la tabla.
if bof() .or. eof() .or. recno(0)
Wait windows "No hay registros coincidentes."
Deshabilitar controles utilizando la propiedad enabled.
Endif
Experto. Correcto. Deshabilite los controles e introduje lo sugerido en click de los botones, pero me advierte error si coloco recno(0) ("El valor, tipo o número de argumentos no es válido para la función"). Si elimino ese código no advierte error pero cuando llego al final de tabla me agrega a la vista un registro en blanco. Gracias por tu tiempo, he aprendido muchísimo. Carlos
Prueba cambiando el código por este:
if bof() .or. eof() .or. recno()<0
No deberías tener problemas.
Experto. Sigo abusando de tu tiempo. Te comento que aún con el último código que me diste, el botón de Siguiente recién se detiene en una vista con los campos en blanco, como si hubiera un registro totalmente vacío. Chequeo la base de datos y no existe tal registro. ¿Qué estoy haciendo mal? Gracias. Carlos
Ese registro vacío es algo que no debiera existir.
¿Estás trabajando con una tabla o con un cursor?
Si estás trabajando con una tabla fíjate qué nº de registro tiene ese último registro vacío.
Luego abre la tabla con el comando use y desde la ventana de comandos ejecuta goto registro y kuego un browse para verificar. Si en cuentras el registro vacío elimínalo.
Toma la precaución de poner set deleted en off
Prueba esto y me avisas.
Experto. Gracias por responder. Te sigo molestando. No puedo darle la puntada final al buscador. Todo funciona bien, excepto lo que te comentara, me sigue agregando una vista de un registro al final, con los campos completamente en blanco. Ya chequee y no hay registro alguno vacío. Es más, con el buscador antiguo que tengo, que me fue generado por el asistente no lo muestra, por lo que descarto que sea un tema de un registro de la base de datos. ¿Tenés alguna sugerencia? Gracias, nuevamente, por tu tiempo. Carlos
Necesitamos averiguar el Nº de registro de ese último registro vacío.
Agrega a tu código la siguiente línea:
Wait windows alltrim(str(recno()))
Experto. Con el código: if bof() .or. eof() .or. recno()<0; y el último que me pasaste: wait windows alltrim(str(recno())) en el botón Siguiente, no me informa número alguno de registro. Sencillamente continúa registro por registro (con el parámetro de búsqueda ingresado) y culmina con una vista de un registro en blanco. Este último ni siquiera puede ser editado, es una simple vista. Si coloco recno(0) en vez de recno()<0 me advierte de error ("El valor, tipo o número de argumentos no es válido para la función") y me informa si del n° de registro, que varía según el parámetro de búsqueda, pero tras un nuevo click en Siguiente, nuevamente me aparece la vista del registro en blanco. No sé si fui lo suficientemente claro. Gracias Carlos.
Si colocas el código:
Wait windows alltrim(str(recno()))
Al final del programa de tu botón siguiente te aparecerá una ventanita en pantalla cada vez que des click en siguiente. En esa ventana aparecerá en cada oportunidad un Nº que es el Nº de registro activo.
Como lo que te está sucediendo es realmente extraño necesito saber cómo es el Nº del último registro.
Experto. Agregué la línea de código al final. Te comento que me indica que el n° de registro es el 2190. La base contiene 2189 registros. Si busco ese registro desde la pantalla de comandos del FoxPro (go 2190) me informa que El registro está fuera del intervalo. Sería un registro inexistente, solo me aparece con el botón Siguiente al final de la tabla. No contiene nada y tampoco el botón de edición lo modifica. No sé si te sirve esta información. Gracias Experto. Carlos
Claro, el puntero se ha situado más allá del último registro.
Algo pasa que no está funcionando el comando eof()
Reemplaza la línea de comando por esta otra y prueba:
if eof() .or. recno()<0
La verdad la función bof() no era necesaria ya que el 1º registro de la tabla también cuenta en los resultados.
Experto. No hay caso, el puntero sigue al final fuera de la base, avistando un supuesto registro vacío. Para tu mejor análisis te paso los código que ingresé.
Un botón del formulario deriva al formulario de búsqueda. En este último, en click de su botón Buscar el código es, como me instruyeras:
thisform.mousepointer=11
* variables locales *
local lcCampo, lcOperator
lcCampo=alltrim(thisform.cmbocampo.value)
lcOperator=alltrim(thisform.cmbooperator.value)
pcValue=upper(alltrim(thisform.txtvalor.value) )
* filtro *
set filter to &lcCampo &lcOperator pcValue
locate for &lcCampo &lcOperator pcValue
* libera variables locales *
release lcCampo, lcOperator
thisform.release
thisform.mousepointer=0
En click del botón Siguiente el código es;
if eof() .or. recno()<0
thisform.command35.enabled=.f.
else
skip
Thisform.refresh
Endif
No sé si te sirve esta información o si he ingresado algo incorrectamente. Gracias nuevamente y disculpá por abusar de tu tiempo. Gracias. Carlos
Tanto nos ha llevado algo tan tonto !
Si analizas tu código notarás que estas evaluando si estás al final de la tabla cuando te encuentras en el último registro de la misma (todavía no estás al final de la tabla), Entonces si te va a permitir hacer el último skip que te lleva el puntero al final de la tabla (como registro en blanco)
Prueba el siguiente código para el evento click del botón siguiente:
Skip 1
if eof() .or. recno()<0
     thisform.command35.enabled=.f.
     Wait windows "Este es el último registro"
     Skip -1
Endif
Thisform. Refresh
En este caso el orden de los factores si altera el producto !
Experto. Muchas gracias. Con la rutina que me pasaste logré poner un tope y evitar aparezca el registro en blanco. Ahora sigo depurando los detalles y agregándole algunas funciones adicionales. Nuevamente gracias por tu tiempo y sentido altruista. Espero no tener que molestarte nuevamente. Si residís en Argentina, mi mail es [email protected] Cuando necesites asesoramiento sobre seguros te devuelvo la gentileza. Carlos.
Me alegro mucho que hayas podido solucionar el problema. La idea es poder colaborar y compartir, así que de ninguna manera es molestia.
Respuesta
1
Yo te recomiendo que no utilices el Wizard. Hacé "a mano" los formularios y demás para adaptarlos exactamente a tus preferencias y requerimientos. Te puedo ayudar en lo que quieras. Cualquier duda que tengas nada más consúltame, ¿sí?
Ante todo, gracias por tu tiempo. Tienes idea donde puedo obtener un modelo de prog. ¿De búsqueda que actualice el formulario que cree con el asistente? Gracias nuevamente. Carlos.
Detallá las características de tu programa y te ayudo a hacerlo.
Respuesta
1
Bueno cuando usas los wizard estas limitado a lo que te haga el wizard en lo personal nunca los he usado prefiero hacer los form justamente para adaptarlo a mis requerimientos, no te podría indicar como hacer para que solo te pida un parámetro y bueno como un sano consejo te diría que hagas tu mismo el form así ya te vas adaptando a la programación en vfp, suerte en todo
Respuesta
1
Ok, mira lo que pasa es que es de mala costumbre programar por medio del wizard, ya que nunca queda como tu quieres, lo que te recomiendo es que programes pero no por el wizard, y pues si tu no sabes te puedo ayudar por que así queda como tu quieras. De lo contrario para poder editar el wizard lo que tu tienes que hacer es lo siguiente :
Darle doble click sobre el objeto o el comando o no se en donde tu tengas tu consulta, ahí seguramente en el evento click o en alguno de los eventos debe de estar una sentencia sql en donde tiene que decir algo por así select * from algo así y ahí tiene que decir where algo entonces ahí es donde tienes que editar para que solo pida un parámetro.
Saludos espero que te sirva, de lo contrario comenta nuevamente!

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas