¿Cómo hacer un formulario multiconsulta?

He visto una entrada tuya del 5 de noviembre del 2011. Resulta que tengo un problema muy parecido, quiero hacer un formulario multiconsulta con varios parámetros, he conseguido hacerlo pero necesito rellenar todos los parámetros del formulario para que me haga la consulta. El problema es que no consigo generar bien la regla de validaciones de los campos para que pueda ir construyendo la consulta de acuerdo al los parámetros que desee elegir en el momento.

He probado a poner en la hoja de propiedades del formulario de un campo en su regla de validación la siguiente expresión:

=SiInm([Cuadro combinado0] Es Nulo;[*];[Cuadro combinado0] ) pero no me hace nada.

Cuadro combinado0 sería uno de los 4 parámetros que utilizo para hacer la multiconsulta. La intención es que si solo quiero consultar por uno de esos 4 parámetros, que me haga la consulta revolviéndome todos los valores del resto del parámetros, no sé si me explico.

Es muy parecido a tu formulario de Librería, cuando quieres consultar por un Autor, o por la Editorial, o por la Fecha de Edición, o por dos de ellos a la vez, etc...

El caso es que no controlo el SQL y me manejo con la vista diseño y el generador de expresiones.

Podrías orientarme para saber qué es lo que estoy haciendo mal.

2 Respuestas

Respuesta
1

Intentaré contestarte de la manera en que yo lo hice.

Partimos de una tabla llamada "Libreria" que tiene los campos 'Campo1', 'Campo2', 'Campo3' (en cualquiera de ellos puedes elegir entre sus propiedades, en la pestaña Búsqueda, que sea un cuadro combinado y le defines el Tipo de origen de la fila). Creas una consulta (la llamamos C_Multiconsulta) con origen de datos en la tabla anterior. Al trasladar los campos de la tabla a esta multiconsulta en vez de quedar (en la fila "Campo") el nombre de los campos de la tabla, hay que utilizar la función Nz para que te devuelva cero los campos vacíos, de forma que tienes que modificarlo para que queden así:

Campo1: Nz ([Libreria]![Campo1];"") y así con los otros 3 campos

En esa misma consulta, en "Criterios" pon esta cadena:

En el correspondiente al 'Campo1':       Como "*" & ([Formularios]![F_Multiconsulta]![C1]) & "*"

En el correspondiente al 'Campo2':       Como "*" & ([Formularios]![F_Multiconsulta]![C2]) & "*";  y lo mimso para el 'Campo3' : Como "*" & ([Formularios]![F_Multiconsulta]![C3]) & "*".

Si algunos de los campos (p.e. 'FechaEdicion') es tipo Fecha tendrías que ponerlo así:

FechaEdicion: Nz([Libreria]![FechaEdicion];#01/01/1000#) y en Criterios para buscar por un rango de fechas tendría que quedar así:    >=Nz([Formularios]![F_Multiconsulta]![Desdefecha].[Value];#01/01/1000#) Y <=Nz([Formularios]![F_Multiconsulta]![Hastafecha].[Value];#01/01/3000#)  donde 'DesdeFecha' y 'Hastafecha' son los nuevos nombres que has de dar a dos cuadros de texto que has de colocar en el formulario F_Multiconsulta

Observa dos cosas: en la función Like (Como) utilizo comodines por delante y por detrás; así puedes buscar cualquier registro que contenga la cadena que quieres buscar. Si quieres que sólo te busque exactamente lo que escribes déjalo así : Como ([Formularios]![F_Multiconsulta]![C1]).

La otra cuestión es que tienes que dar un nombre distinto a los campos en la fila de criterios (en este caso C1, C2 y C3); este será el nombre de los campos que aparecen en el formulario al que llamaremos F_Multiconsulta que ahora te explico:

Crea un formulario al que le puedes llamar "F_Resultado", con origen de datos en la Consulta que has creado (C_Multiconsulta) y trasladas al mismo los campos de esa consulta.

Creamos otro formulario "F_Multiconsulta" con origen de datos en la tabla "Libreria". Después de haber completado el diseño vas a sus propiedades y eliminas el Origen del registro dejándolo en blanco (también podrías inicialmente crear el formulario sin origen de datos e ir incluyendo los diversos cuadros de texto, uno para cada uno de los campos de la tabla, pero de esta forma resulta más sencillo a mi parecer; además si utilizar cuadros combinados te sigue manteniendo el tipo de origen que has definido en la tabla). Después en cada uno de los campos de ese formulario, en sus propiedades, también eliminas el Origen del control dejándolo en blanco y cambias sus nombres ('Campo1' por C1 y así con los tres). Crea un botón de comando al que podemos llamar Ejecutarconsulta y en el evento "al hacer clic", al picar en los tres puntos selecciona Generador de Código de forma que al final te quede esto:

Private Sub EjecutarConsulta_Click()

On Error GoTo Err_EjecutarConsulta_Click

    Dim stDocName As String

    Dim stLinkCriteria As String

    stDocName = "F_Resultado"

    DoCmd.OpenForm stDocName, , , stLinkCriteria

Exit_EjecutarConsulta_Click:

    Exit Sub

Err_EjecutarConsulta_Click:

    MsgBox Err.Description

    Resume Exit_EjecutarConsulta_Click

   End Sub

De esta forma estamos llamando al formulario F_Resultado, el cual tiene su origen en la consulta C_Multiconsulta, la cual toma como parámetros de búsqueda lo que le hemos puesto en cualquiera de los campos de F_Multiconsulta .

Bueno, parece algo laborioso por lo extenso de la explicación pero la verdad es que no lo es tanto;

Respuesta
2

Lo más versátil es usar código para construir la SQL y luego pasarla como origen del objeto que sea, pero obviamente puedes hacerlo usando criterios en la consulta.

Créate la consulta que incluya todos los campos que vayas a usar como cirterios de selección (y los que quieras mostrar claro está).

Añade en la fila de criterios expresiones como la siguiente:

Como SiInm(EsNulo([Formularios]![miFormulario]![Cuadro combinado 0]);"*";[Formularios]![miFormulario]![Cuadro combinado 0])

Uso la nomenclatura larga para definir al campo Cuadro combinado 0 ya que no se como tienes montada la pantalla, consulta... pero puede valerte la abreviada.

Esta expresión te devolverá todos los registros si no hay nada seleccionado en Cuadro combinado 1, y usará el valor que tengas si hay algo seleccionado. Si pones en la misma línea criterios similares para los otros tres campos por los que quieres filtrar, obtienes una consulta que comprobará el valor de los cuatro campos y los usará si hay algún valor o 'pasará' un asterisco, es decir, como si no hubieses usado filtro en ese campo.

Cordiales saludos.

Al releerme la pregunta creo que debo de añadir algo a mi respuesta.

Tu planteabas usar reglas de validaciones en los campos. Mi propuesta es que no hagas esas reglas si solo las necesitas para usar estos campos como filtros. Úsalas para comprobar si un valor es válido, es por ejemplo un número dentro de un rengo determinado, o lo que quieras validar si es una entrada de texto libre.

En donde debes de incluir las expresiones como la que te mostraba es en la consulta origen del registro del formulario o informe en donde presentas los resultados. Esta consulta hace las comprobaciones de que filtros has usado y muestra lo que debe, para lo cual escribes criterios como el apuntado en la misma línea de la cuadrícula de vista de diseño de la consulta. Con ello los criterios quedan unidos por un 'And' lo que quiere decir que se van a evaluar todos y todos influyen en el resultado mostrado. Al usar el inicio de los criterios Como SiInm(EsNulo... consigues que aun teniéndolos todos en cuenta realmente solo se apliquen los que tengan algún valor.

Cordiales saludos.

Hola muchas gracias por tu rapidez.

He hecho lo que me has comentado,y he puesto los siguientes criterios:

SiInm(Es Nulo ([Formularios]![PRUEBA CONSULTA1]![Cuadro combinado0]);"*";[Formularios]![PRUEBA CONSULTA1]![Cuadro combinado0])

SiInm(Es Nulo([Formularios]![PRUEBA CONSULTA1]![Cuadro combinado5]);"*";[Formularios]![PRUEBA CONSULTA1]![Cuadro combinado5])

Al hacer ejecutar el formulario Access me contesta:

Esta expresión no está escrita correctamente o es muy compleja para evaluarse.

Entonces vuelvo a la consulta y me ha modificado algunas cosas:

SiInm([Formularios]![PRUEBA CONSULTA1]![Cuadro combinado0] Es Nulo;"*";"«Expr» Formularios![PRUEBA CONSULTA1]![Cuadro combinado0]")

 SiInm(([Formularios]![PRUEBA CONSULTA1]![Cuadro combinado5]) Es Nulo;"*";[Formularios]![PRUEBA CONSULTA1]![Cuadro combinado5])

Creo que estoy escribiendo algo más, pero no tengo duda de que la solución anda cerca y entorno a esto, seguiré probando.

Muchas gracias por arrojar un poco de luz a mi cuestión.

Un saludo

Es importante que el criterio comience con Como. Normalmente un criterio complejo y que se va a evaluar finalmente como una cadena debes de comenzarlo con Como SiInm...

Cordiales saludos.

Y debes de eliminar «Expr»

¡Gracias! Seguiré probando, espero informarte de que al final lo he conseguido.

Buenas noches y muchas gracias de nuevo

Hola, Ángel, sigo sin poder con la tecla del asunto, y el caso es que no consigo ver dónde estoy cometiendo el error. He pensado pegarte el comando en SQL a ver su tu consigues ver dónde está el fallo:

SELECT [ENTRADAS FRUTA].*
FROM [ENTRADAS FRUTA]
WHERE ((([ENTRADAS FRUTA].IdCLIENTE)=SiInm(EsNulo([Formularios]![PRUEBA CONSULTA1]![Cuadro combinado 0]),"*",[Formularios]![PRUEBA CONSULTA1]![Cuadro combinado 0])) AND (([ENTRADAS FRUTA].IdPRODUCTO)=SiInm(EsNulo(([Formularios]![PRUEBA CONSULTA1]![Cuadro combinado 0]),"*",[Formularios]![PRUEBA CONSULTA1]![Cuadro combinado 5])));

Cuando en la consulta coloco en el criterio de ambos campos:

([Formularios]![PRUEBA CONSULTA1]![Cuadro combinado 0]

([Formularios]![PRUEBA CONSULTA1]![Cuadro combinado 5]

me funciona correctamente cuando cumplimento ambos campos,después cuando le pongo las condiciones de SiIm no hay manera.

Podrías ayudarme, ya que si consigo tener este formulario me ahorraría muchas consultas en la base.

Muchas gracias

Me he creado una tabla con los dos campos que citas y un formulario con los dos cuadros combinados. Partiendo de tu consulta he usado el asistente para generarla

Te copio la consulta que he creado. A mi me responde correctamente.

SELECT [ENTRADAS FRUTA].*
FROM [ENTRADAS FRUTA]
WHERE ((([ENTRADAS FRUTA].IdCliente) Like IIf(IsNull([Formularios]![PRUEBA CONSULTA1]![Cuadro combinado 0]),"*",[Formularios]![PRUEBA CONSULTA1]![Cuadro combinado 0])) AND (([ENTRADAS FRUTA].IdPRODUCTO) Like IIf(IsNull([Formularios]![PRUEBA CONSULTA1]![Cuadro combinado 5]),"*",[Formularios]![PRUEBA CONSULTA1]![Cuadro combinado 5])));

En consultas con errores en la sintaxis ves usando el asistente. Créate primero la consulta con un criterio directo, por ejemplo, ([ENTRADAS FRUTA].IdCliente) Like [Formularios]![PRUEBA CONSULTA1]![Cuadro combinado 0]. Luego ves añadiendo el SiInm y el EsNulo y todas las funciones que necesites de una en una, usando como te comento el asistente y comprobando el resultado en cada paso.

Cordiales saludos.

Hola Ángel, después de estar toda la tarde haciendo pruebas y más pruebas, al final he conseguido hacer el Formulario Multiconsulta, pero empezando por la consulta. Parece ser que lo que me daba problema eran los cuadros combinados.

He hecho una consulta con las tablas de las que quería sacar los campos combinados, después he creado un formulario con Cuadros de Texto, cadapara cada variable que quería consultar, después en la consulta debajo de cada campo he puesto lo siguiente:

  • Como SiInm([Formularios]![CENTRADA]![Texto13] Es Nulo;"*";[Formularios]![CENTRADA]![Texto13])
  • Como SiInm([Formularios]![CENTRADA]![Texto17] Es Nulo;"*";[Formularios]![CENTRADA]![Texto17])
  • Como SiInm([Formularios]![CENTRADA]![Texto19] Es Nulo;"*";[Formularios]![CENTRADA]![Texto19])

En SQL sería:

SELECT [ENTRADAS FRUTA].IdENTRADAS, CLIENTES.NOMBRE, [ENTRADAS FRUTA].[FECHA ENTRADA], PRODUCTOS.[NOMBRE PRODUCTO], [TIPO CONTENEDOR].ENVASE, [ENTRADAS FRUTA].TRATAMIENTO, [ENTRADAS FRUTA].[CANTIDAD ENTRADA], [ENTRADAS FRUTA].[OBSERVACIONES ENTRADAS]
FROM CLIENTES INNER JOIN ([TIPO CONTENEDOR] INNER JOIN (PRODUCTOS INNER JOIN [ENTRADAS FRUTA] ON PRODUCTOS.IdPRODUCTOS = [ENTRADAS FRUTA].IdPRODUCTO) ON [TIPO CONTENEDOR].IdCONTENEDOR = [ENTRADAS FRUTA].IdCONTENIDO) ON CLIENTES.IdCLIENTE = [ENTRADAS FRUTA].IdCLIENTE
WHERE (((CLIENTES.NOMBRE) Like IIf([Formularios]![CENTRADA]![Texto13] Is Null,"*",[Formularios]![CENTRADA]![Texto13])) AND ((PRODUCTOS.[NOMBRE PRODUCTO]) Like IIf([Formularios]![CENTRADA]![Texto17] Is Null,"*",[Formularios]![CENTRADA]![Texto17])) AND (([TIPO CONTENEDOR].ENVASE) Like IIf([Formularios]![CENTRADA]![Texto19] Is Null,"*",[Formularios]![CENTRADA]![Texto19])));

Así, sí que me permite hacer la multiconsulta eligiendo la situación que me conviene en cada caso.

Después he intentado sustituir uno por un cuadro combinado pero ya no me realizaba la consulta.

¿Puedo convertir los Texto 13, Texto 17 y Texto 19, en cuadros combinados desde la Hoja propiedades? Me conformo con este formulario pero claro, el problema está en que tienes que poner exactamente los nombres como son, sino no te realiza la consulta, con cuadros combinados ese problema desaparece.

Muchas gracias por tu paciencia

Un saludo

Puedes usar cuadros combinados en lugar de cuadros de texto. En el ejemplo que te he enviado yo he usado cuadros combinados y no cuadros de texto. Lo único que hay que tener en cuenta es si el cuadro combinado tiene más de una columna. Si tiene solo una (como en el ejemplo que me cree) la referencia la haces igual que si fuese sobre un cuadro de texto.

Si tuviese más de una puedes usar la propiedad Column. Por ejemplo [XXX] Like Forms!Form1!CuadroDeTexto.Column(1)

Recuerda que la primera columna sería la (0).

Cordiales saludos

¡Gracias!, volveré a probar con más cuidado, si a ti te sale, me debe de salir también.  Muchas gracias ya te iré contando. 

Muchas gracias de nuevo por tu paciencia.

Un saludo

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas