Contar registros filtrados

Antes de nada agradecer la ayuda ya prestada como "visitante anónimo", que es mucha.

Me gustaría saber el número de registros que devuelve un filtro. He "peleado" con dcount, intentado hacer una consulta, pero nada. ¿Puede ser cosa de la sintaxis...?

Este es el código:

Private Sub Comando43_Click() 'filtrar
Dim confiltro, cftabla, cfform As String
Dim nrexfil As Integer
Dim ctrl As Control
On Error GoTo comando43_Click_Error
Set ctrl = Screen.PreviousControl
ctrl.SetFocus
cfform = CStr(ctrl)
cftabla = CStr(ctrl.ControlSource)
confiltro = CStr(cftabla & " = " & cfform)
DoCmd.RunCommand acCmdFilterBySelection
nrexfil = DCount("*", "TABLAMATRIZ","&confiltro&")
On Error GoTo 0
Exit Sub
comando43_Click_Error:
MsgBox "xxxxxxxxxxxxxxxxxx"
End Sub

Respecto a mis intentos con la consulta, me he quedado aún más lejos...

confiltro = "SELECT * FROM TABLAMATRIZ WHERE " & cftabla & " = " & cfform & ""

Me.RecordSource = confiltro
Me.Requery

nrefil=me.recordcount

Gracias anticipadas y saludos. Buenas fiestas

1 respuesta

Respuesta
1

Ante todo decirte que tienes una forma bastante peculiar de filtrar... yo creo que todo eso que has puesto se puede hacer en muchas menos lineas (creo que con menos de 5 se salva)

Entiendo que deseas filtrar por el valor de un campo (del último control dónde se ha estado). Ese código que tienes funcionará bien siempre que el usuario no haga clic en otro sitio antes de clicar el botón. Si quiero filtrar el campo, por ejemplo, Cliente y, después de hacer clic en Cliente y antes de hacerlo en el botón hago clic en Dirección, es obvio que filtrara por la dirección. Lo digo porque es algo muy a tener en cuenta a la hora de programar.

Si quieres hacerlo así perfecto pero tal como lo tienes solo puedes filtrar por valores numéricos; para filtrar por textos necesitaras poner el texto entre comillas o apostrofes. En esos casos yo acostumbro a utilizar el Tag del control para almacenar el tipo de dato que contiene. De esa forma puedo crear la cadena de filtro adecuadamente.

Una cadena de filtro numérico:

"Campo=" & Me!elcampo

Uno de texto:

"Campo = '" & Me!elcampo & "'" 'ojo: apostrofe, comillas, ampersand, Me!elcampo, ampersand, comillas, apostrofe, comillas

Finalmente la aplicación del filtro. Nunca he utilizado esa forma por lo que desconozco si los filtros son acumulativos o no. En caso de no serlo me parece que la técnica no es la más adecuada. La utilización de Filter es más "académica"

Me.Filter = lacadenadefiltro

Me.FilterOn = True

Otra forma de contar es aplicar el filtro a nivel de RecordSource creando la SQL adecuada (algo como lo que has hecho en tu intento de contar)

En cualquier caso la forma más adecuada de contar los registros resultantes (independientemente de la técnica de filtrado aplicada) es utilizar el Recordsetclone.

Una vez aplicado el filtro:

nfil = Me.RecordsetClone.RecordCount

Otro consejo más: si aplicas un valor al Me. RecordSource no es necesario hacer un Requery a continuación. Con eso ejecutarás dos veces la consulta consumiendo unicamente recursos. En algunos sistemas locales no es importante pero en ciertos sitios programas buscando arañar décimas de segundo (te lo digo por experiencia)

Un saludo

Xavi

http:/www.aesoft-databases.com
http://www-mvp-access.com/

Hola otra vezagradecer antes de nada tu respuesta, me ha sido de utilidad. Cierto que mi código es un poco peculiar o a "machetazos" :( que digo yo, así salen algunas cosas... ya quisiera saber más...pero las circunstancias son las que son.

me gustaría pedirte tu solución para el mismo filtro, si no es excesivo. Por si hay suerte te (os) explico:

pretendía que con un "click" en un campo (tres teniendo en cuenta el error) el usuario pueda filtrar los registros, cualquiera que fuese el campo -todos texto- elegido y que también devuelva el número de registros con ese valor. Y que la misma instrucción sirviese para todo. No se si me explico, probablemente no.

saludos y reitero agradecimiento

La verdad es que no acabo de entender la mecánica que quieres implementar ni si los filtros deben ser acumulativos o no.

Viendo que hablas de 3 campos para filtrar yo utilizaría, ademas de 3 cuadros de texto, 3 botones de alternar de esa forma se pueden acumular filtros. Así tendríamos 6 controles: txt1, txt2, txt3, alt1, alt2 y alt3. A esos controlesd faltaría añadir una etiqueta para mostrar la cuenta.

Después crearía una función que evaluara los estados de los controles y aplicaría los filtros.

Private Function fntAplicaFiltro()

Dim strFilter As String

' Empezaría creando una condición ineludible: 1 = 1

strFilter = "1=1"

'Después, y aprovechando los controles numerados, abriría un bucle para recorrer lkos controles y concatenar la cadena de filtro

Dim i As Integer

For i = 1 To 3

If Me("alt" & i) Then

strFilter = strFilter & " AND " & Me("txt" & i).ControlSource & "='" & Me("txt" & i) & "'"

End If

Next

Me.Filter = strFilter

Me.FilterOn = True

Me!lblCuenta.Caption = Me.RecordsetClone.RecordCount

End Function

Ahora solo es necesario asociar esa función al evento AfterUpdate (después de actualizar) de los 3 botones de alternar. Yo eso lo hago en el Open del formulario (manías que tiene uno)

Me!alt1.AfterUpdate = "=fntAplicaFiltro()"

Me!alt2.AfterUpdate = "=fntAplicaFiltro()"

Me!alt3.AfterUpdate = "=fntAplicaFiltro()"

A ver si te sirve

Xavi

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas