Filtro por combos en cascada

Tengo un Formulario llamado frmCODIGO (con datos de una tabla tblCOD, los campos son Id, Usuario y Cod), y dentro un subformulario fsubCASOS (con datos de una tabla tblCASOS, los campos son Id, Usuario y Caso) en el que puede haber varios casos por código.

Las tablas están relacionadas por el campo USUARIO.

En otro formulario frmCONSULTA tengo un combo para elegir el código y otro para el caso. Cuando filtro por código todo funciona, pero cuando añado el caso o lo pruebo solo no me da ningún resultado. Supongo que es porque no nombro bien el campo del Caso, pero he probado varias maneras de llamar al campo y no hay manera.

Gracias de antemano.

El código que he puesto es:

Private Sub Comando34_Click()
   Dim vCaso As String
   Dim vCod As Byte
   Dim miFiltro As String
   vCaso = Nz(Me.cboCaso.Value, "")
   vCod = Nz(Me.cboCod.Value, 0)
   miFiltro = ""
   If vCod > 0 Then
      miFiltro = "[Cod]=" & vCod
   Else
      miFiltro = ""
   End If
   If vCaso <> "" Then
      If vCod > 0 Then
         miFiltro = miFiltro & " AND Forms![frmCOD]![fsubCASOS]![Caso]='" & vCaso & "'"
      Else
         miFiltro = "Forms![frmCOD]![fsubCASOS]![Caso]='" & vCaso & "'"
      End If
   End If
   DoCmd.OpenForm "frmCOD", acNormal, , miFiltro, acFormReadOnly
End Sub

2 Respuestas

Respuesta
1

Me funciona a medias.

Me explico: cuando introduzco un valor de Caso me devuelve todos los registros aunque en el subformulario no aparecen los números de caso de ninguno de ellos excepto el del caso que he buscado.

Y cuando introduzco valor de Código y valor de Caso, me filtra por valor de código pero hace lo mismo, saca todos los registros con ese código y sólo muestra en el subformulario el valor de caso que he buscado (en el registro correspondiente, claro).

.

Respuesta
2

El problema, si te he entendido bien, está en que tienes que aplicar dos filtros, uno al formulario y otro al subformulario, pero tienes que hacerlo independientemente:

miFiltroForm="Cod=" & vCod

miFiltroSubform="Caso='" & vCaso & "'"

Luego abres el formulario (que tiene el subformulario) filtrado:

DoCmd. OpenForm "frmCOD", acNormal,, miFiltro, acFormReadOnly

Y le aplicas el filtro al subformulario:

Forms("frmCOD").fsubCASOS.Form.Filter=miFiltroSubform

Forms("frmCOD").fsubCASOS.Form.FilterOn=True

A ver si así te funciona.

Un saludo.


Uf! No sé cómo lo he hecho pero me he respondido a mí misma. :P

Como decía la solución me funciona a medias:

Cuando introduzco un valor de Caso me devuelve todos los registros existentes aunque en el subformulario no aparecen los números de caso de ninguno de ellos excepto el del caso que he buscado.

Y cuando introduzco valor de Código y valor de Caso, me filtra por el valor de código que he escogido, pero hace lo mismo, saca todos los registros con ese código y sólo muestra en el subformulario el valor de caso que he buscado (en el registro correspondiente, claro, el resto de registros aparecen pero sin valor de caso).

No tengo ninguna idea de porqué puede ser.

Pues no sé... yo acabo de probar ese sistema y me funciona correctamente, es decir, me filtra tanto el formulario como el subformulario y aunque cambie de registro en el formulario principal, ambos siguen filtrados: http://filebig.net/files/VUjbtdTdbN

Aquí, la pesada de nuevo,

He revisado de arriba a abajo las diferencias entre tu BD y la mía, he cambiado todas las propiedades del subformulario y del formulario por si afectaban, pero no consigo ver dónde está el problema. Tampoco es que sea una experta, más bien lo contrario, pero es que le he dado mil vueltas y nada.

http://filebig.net/files/fMSkWT96nN 

Para nada eres pesada...

He estado revisando tu archivo un poco por encima, y funciona correctamente según lo programada. Otra cosa es que no nos hayamos entendido y no sea ese el resultado que quieres conseguir...

Veamos, con tu BD de ejemplo:

1º/ Selecciono como nombre "255" y el formulario me devuelve 2 registros -> Correcto. El filtro para el formulario funciona.

2º/ Selecciono como caso "BC-AC019800-69" y el formulario devuelve los 13 registros (es decir, no filtra el formulario) y en el subformulario solo devuelve los registros correspondientes a ese caso, el resto aparece en blanco. -> Esto indica que el filtro del subformulario funciona.

Aqui tengo la duda: ¿Tu quieres que en el formulario principal te aparezcan solo los registros que tienen ese caso, es decir, el que se corresponde con el producto "ABC"?

Si es así, hay que usar un truquillo para hacerlo. Me lo dices y te lo programo.

Perdona, no he sabido explicarme con el problema. Tienes toda la razón, no es que no me filtrara el subformulario, sí filtraban por un lado el formulario y por otro el subformulario, pero me salían en blanco y no es lo que lo yo buscaba.

Sí, justo eso es lo que necesito, buscar la ficha del producto cuando sé su número de caso. Tengo más de 3000 productos y se me ponen los pelos como escarpias sólo de pensar que tengo que mirarlos uno a uno para saber cuál es. ¿Cuál es ese truquillo? :)

Te devuelvo el archivo con unas modificaciones:

1º/ Al primer cuadro combinado le puedes "eliminar" los valores duplicados si conviertes la consulta de origen en una consulta de totales.

2º/ Al segundo cuadro combinado, se los puedes eliminar usando DISTINCT en la consulta o también convirtiendo la consulta en una de totales.

3º/ Te he simplificado el código para la creación del filtro enormemente, para evitar tanto If anidado que a la larga hace menos eficiente el código. Puedes ver una explicación de lo que he hecho en este ejemplo de Neckkito: http://bit.ly/2e4jEbB

4º/ El truquillo para filtrar un formulario por los valores del subformulario, es hacer una consulta que devuelva los valores del campo relacionado que cumplen con el criterio del filtro, y luego filtrar el formulario principal por esos valores.

En tu caso esto se hace así:

   If vCaso <> "" Then
      miFiltro = miFiltro & " AND [Producto] IN (SELECT Producto FROM tblCasos WHERE NumCaso='" & vCaso & "')"
   End If

Con ese SELECT, buscas en la tabla tblCasos (base para el subformulario) los productos que cumplen con la condición de filtrado (que el NumCaso sea igual al valor seleccionado, es decir " ... WHERE NumCaso='" & vCaso & "'")

El operador IN hace que el filtro devuelva todos los registros cuyo campo Producto coincida con algún valor de los que devuelve ese SELECT.

Un ejemplo con tu BD de ejemplo: si selecciono el caso "BC-AB013568-61", me devuelve dos registros (los correspondientes al producto 255), porque ese SELECT me devuelve esos dos valores (lo puedes comprobar haciendo esa consulta), y el filtro se "interpreta" así: Producto In ('255','255')

http://filebig.net/files/mDkde3mryt 

Un saludo.


Muchísimas gracias, Sveinbjorn, es mucho más de lo que esperaba.

Ni me había dado cuenta de que salían repetidos los casos  :O

Por aprender algo más: aunque sólo me lo aconsejas en el segundo cuadro combinado, he cambiado la consulta de totales del primer cuadro combinado por DISTINCT y veo que funciona pero le tengo que quitar el ORDER BY ¿La pega de usar DISTINCT para quitar valores duplicados en este caso es únicamente porque no se pueden ordenar por un campo que no es el que estás seleccionando o hay algo más? ¿Es más aconsejable utilizar DISTINCT o la consulta de totales dependiendo de algo en concreto? o.O

Me das una alegría con lo de la simplificación del código. Porque escribí el que te he mandado siguiendo el ejemplo de Neckitto (el del curso, no el que me has enviado), pero se me ocurrió que tal como lo has escrito tú era más simple y podía funcionar y lo probé. Aunque me faltó añadir la parte de eliminar el AND con el LEN. Es a veces me cuesta integrar los conceptos, y aunque los entienda por separado luego me cuesta mezclarlos en un mismo procedimiento. Pero al menos me doy cuenta de que no iba tan mal encaminada. :))

El último If:

   If Len(miFiltro) = 0 Then

     Exit Sub

   Else

      miFiltro = Right(miFiltro, Len(miFiltro) - 5)

   End If

lo he quitado y he dejado sólo el siguiente código:

      miFiltro = Right(miFiltro, Len(miFiltro) - 5)

porque había puesto al principio que saltase un mensaje de aviso si no se había seleccionado nada para filtrar, sólo que lo quité para que te resultara más fácil de leer el código.

Pues eso, mil gracias de nuevo por tu ayuda.

Un saludo,

Carmen

Para responder a lo del DISTINCT vs Consutla Totales: de cualquiera de las dos formas consigues el mismo objetivo, por lo que según lo que quieras es indistinto usar uno y otro. Ahora bien, en el caso concreto del primer orden, si usas Distinct te da error no porque no sea compatible con el ORDER BY (que si lo es), sino porque ordenas por un campo que "no está" en la consulta.

Fíjate:

SELECT tblCASOS.NumCaso FROM tblCASOS INNER JOIN tblPRODUCTOS ON tblCASOS.Producto = tblPRODUCTOS.Producto GROUP BY tblCASOS.NumCaso, tblPRODUCTOS.Producto HAVING (((tblCASOS.NumCaso) Like "*" & [Formularios]![frmConsultaPRODUCTOS]![txtCaso] & "*")) ORDER BY tblPRODUCTOS.Producto; 

Si a esta le pones el DISTINCT, te salta el error de incompatibilidad con ORDER BY. Pero si le añades el campo Producto al SELECT, ya puedes usar DISTINCT:

SELECT DISTINCT tblCASOS.NumCaso, tblPRODUCTOS.Producto FROM tblCASOS INNER JOIN tblPRODUCTOS ON tblCASOS.Producto = tblPRODUCTOS.Producto GROUP BY tblCASOS.NumCaso, tblPRODUCTOS.Producto HAVING (((tblCASOS.NumCaso) Like "*" & [Formularios]![frmConsultaPRODUCTOS]![txtCaso] & "*")) ORDER BY tblPRODUCTOS.Producto; 

Un saludo, y simplemente comentarte que también nos puedes encontrar a Neckkito o a mi en nuestro foro: http://nksvaccessolutions.com/Foro/

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas