Construyendo un Generador de Búsquedas

Por Pedro Pascua
© Copyrights 1996 by FoxPress, All rights reserved
FoxPress, Octubre 1996

El fuente de este artículo en www.datapress.com (area de suscriptores)

Cualquiera que haya pasado un rato 'jugando' con VFP conoce su generador de consultas. Esta herramienta es muy versátil y nos permite crear consultas SQL avanzadas sobre nuestra base de datos de modo sencillo e intuitivo. Este sistema resulta útil a la hora de crear vistas o definir consultas para informes que se realizan con relativa frecuencia pero siempre con el mismo formato.

Por otro lado, al desarrollar una aplicación suele ser interesante dotarla de la posibilidad de que, al margen de las opciones preestablecidas en los menús y formularios, el usuario pueda visualizar sus datos personalizando la consulta según sus necesidades. En este caso, no podremos utilizar el generador de consultas, ya que la consulta va a ser distinta cada vez. Si nos encontramos en esta situación, lo más fácil es que nos creemos nuestro propio generador de consultas y que lo incluyamos como un formulario más dentro de nuestra aplicación.

Como veremos a continuación, generar una consulta es algo bastante sencillo. Sólo necesitamos

un interfaz en el que el usuario indique qué campos quiere ver, en qué orden y con qué condiciones, para luego construir una cadena que contenga la instrucción SQL necesaria para ejecutar la consulta. En nuestro ejemplo, hemos hecho un caso sencillo con una sola tabla, pero no habría ningún problema en agregar más tablas e ir aumentando las posibilidades de nuestro generador. Veamos a continuación nuestro ejemplo:

Hemos creado un formulario como muestra la imagen, en cuyo entorno de datos incluimos la tabla ORDERS que se encuentra en el directorio \VFP\SAMPLES\DATA. En el formulario tenemos cuatro cuadros de lista. El de la izquierda para listar todos los campos de la tabla. Los dos de arriba para seleccionar campos y orden de los mismos y el de la parte inferior para agregar condiciones de búsqueda.

Para agregar campos a las listas, utilizamos el Drag&Drop, con lo que nos evitamos unos cuantos botones. El mismo sistema es usado para eliminar elementos de las listas, pues basta con arrastrarlos hasta la papelera del extremo inferior izquierdo.

Para llenar la lista grande con los campos de la tabla, agregamos el siguiente código en el Init() del formulario:

lcNumCampos = FCOUNT('orders')
For i=1 to lcNumCampos

ThisForm.NombreCampos.AddItem(FIELDS(i))
ThisForm.cboCampos.AddItem(FIELDS(i))

EndFor

En cada evento MouseMove() de los cuadros de lista, añadimos:

LPARAMETERS nButton, nShift, nXCoord, nYCoord
If nButton = 1
This.Drag(1)
Endif

De este modo detectamos el inicio del Drag en cada lista. El evento Drop dependerá del control en el que soltamos el elemento. Si lo hacemos sobre la papelera ocurrirá el evento Image1.DragDrop() :

LPARAMETERS oSource, nXCoord, nYCoord
oSource.RemoveItem(oSource.ListIndex)

Si lo hacemos sobre una de las dos listas de selección de campos ocurrirá uno de estos dos eventos: ListaCampos.DragDrop() o bien, ListaOrden.DragDrop(), que tienen el mismo código:

LPARAMETERS oSource, nXCoord, nYCoord
This.AddItem(oSource.List(oSource.ListIndex))

El combo de condiciones tiene dos columnas, aunque sólo hacemos visible una de ellas. De este modo, podemos guardar en cada uno de los Items de la lista de condiciones, el nombre que mostramos en pantalla (Mayor que, Menor que, Igual a ... ) y el carácter que insertamos en la cadena de consulta (<, >, =).

** cboCondición.Init() **
This.AddListItem("Y",1,1)

This.AddListItem(" AND ",1,2)
This.AddListItem("O",2,1)
This.AddListItem(" OR ",2,2)
This.AddListItem(" NO ",3,1)
This.AddListItem(" NOT ", 3,2)

Lo mismo hemos hecho con el combo de operadores:

** cboOperador.Init() **
This.AddListItem("Igual a",1,1)
This.AddListItem(" = ",1,2)

This.AddListItem("Mayor que",2,1)
This.AddListItem(" > ",2,2)

This.AddListItem("Menor que",3,1)
This.AddListItem(" < ", 3,2)

Para completar el ejemplo, podríamos añadir en estas dos listas, todas aquellas condiciones que queramos incluir en nuestras consultas.

Una vez que hemos completado las listas de campos y condiciones, sólo queda generar la cadena que contenga la instrucción SQL correspondiente y ejecutar dicha instrucción. Esto lo hacemos en el Click del botón 'Ejecutar consulta':

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

** cmdConsulta.Click() **

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

ThisForm.Refresh()

lcConsulta = "SELECT"

lcNumCampos = ThisForm.ListaCampos.ListCount

If lcNumCampos = 0

x = MessageBox("No ha seleccionado ningún campo para ejecutar la consulta",0+64,"Advertencia")

else

For linea = 1 to lcNumCampos

lcConsulta = lcConsulta + " "

+ThisForm.ListaCampos.List(linea);

+ IIF(linea = lcNumCampos, "", ",")

EndFor

lcConsulta = lcConsulta + " FROM orders"

lcCond=ThisForm.ListaCondiciones.ListCount

If lcCond >0

lcConsulta = lcConsulta + ' WHERE '

For linea = 1 to lcCond

lcConsulta = lcConsulta +

ThisForm.ListaCondiciones.List(linea)

EndFor

EndIf

lcOrden = ThisForm.ListaOrden.ListCount

If lcOrden > 0

lcConsulta = lcConsulta + ' ORDER BY '

For linea = 1 to lcOrden

lcConsulta = lcConsulta +

ThisForm.ListaOrden.List(linea);

+ IIF(linea = lcOrden, "", ",")

EndFor

EndIf
&lcConsulta

Endif

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

Como se puede ver, el proceso es bastante sencillo, y se podría mejorar añadiendo otra lista en la que eligiéramos las tablas sobre las que hacer la consulta y consecuentemente, implementando la generación de consultas sobre múltiples tablas, tarea ésta que dejamos para el lector.

PEDRO PASCUA es matemático y trabaja con VB, VFP, C++, Oracle y lo que le echen (e-mail: ped@datapress.com)