¿Se puede utilizar a la vez contar y filtrar por fechas?
Estoy intentando hacer una aplicación para la gestión de la biblioteca que tenemos en la empresa que trabajo. Ya la tengo avanzada y lo último que se me ha ocurrido es intentar saber que libros han sido los más leídos en un periodo determinado.
He intentado hacer una consulta agrupando los números de libros (IDLibros) leídos a la vez que filtrando los datos entre un intervalo de fechas. Si ejecuto las sentencias por separado ambas funcionan pero si las uno no.
He utilizado el DCont tanto en la consulta como en Origen de control y no consigo nada.
3 Respuestas
Por aportar otra solución diferente pero igual de válida que las dos anteriores, y que vendría a ser algo intermedio entre ambas (es como la solución de Icue pero en una única consulta, como la de Jacinto, pero con una construcción más sencilla):
Haces una consulta de totales como la Consulta2 de Icue, pero directamente sobre la tabla, y le añades también el campo Fecha. A este campo fecha, le pones un criterio como el de Icue, para que te pida entre qué fechas devolver los resultados, y a mayores le haces estos dos cambios: primero le desmarcas la casilla de Mostrar, y segundo, el Agrupar Por lo pones "Dónde". Al ejecutar esta consulta, obtendrás lo que buscas.
Y el resultado (sin ordenar):
La SQL de esta consulta sería:
SELECT TPtmos.Libro, Count(TPtmos.Libro) AS [Ptmos periodo] FROM TPtmos WHERE (((TPtmos.Fecha) Between [Fecha inicial] And [Fecha final])) GROUP BY TPtmos.Libro;
Un saludo.
Sveinbjorn el rojo, muchas gracias por responder.
La verdad es que me habéis dado un abanico de posibilidades y eso es de agradecer.
Primeramente voy a intentar empezar con la respuesta que aparentemente me parece más sencilla, para una vez conseguido el resultado deseado ir subiendo en el escalafón para ver si soy capaz de comprender y aprender algo.
El mundo de la informática me apasiona.
Ya te diré cuál ha sido el resultado que he obtenido.
Muchas gracias. Un saludo
Hola sveinbjorn el rojo.
Siguiendo tu recomendación tengo que decirte que el resultado es satisfactorio en la consulta, pero me encuentro con el problema que al trasladar los datos a un formulario con su subformulario pierdo toda posibilidad de acotar el resultado dado que el campo fechaPtmo está oculto (al agrupar por “dónde” desaparece el campo, como bien sabes).
El botón filtrar lo he construido con la instrucción siguiente:
Dim sFiltro As String
‘Dim FechaPtmo As String ' Aveces quito este campo porque no sirve pero el resultado es el mismo
If IsNull(txtFechaInicio) And IsNull(txtFechaFin) Then
FechaPtmo = ""
End If
If Me.txtFechaInicio > Me.txtFechaFin Then
MsgBox "LA FECHA INICIAL NO PUEDE SER MAYOR A LA FECHA FINAL", vbInformation, "AVISO"
Me.txtFechaInicio.SetFocus
End If
If Not IsNull(txtFechaInicio) And Not IsNull(txtFechaFin) Then
sFiltro = "FechaPtmo BETWEEN # " & Format(Me.txtFechaInicio, "mm-dd-yyyy") & _
"# AND #" & Format(Me.txtFechaFin, "mm-dd-yyyy") & "#"
Me.[Subformulario libros más leídos_1].Form.Filter = sFiltro
Me.[Subformulario libros más leídos_1].Form.FilterOn = True
Me.[Subformulario libros más leídos_1].Visible = True
Else
MsgBox "TIENES QUE PONER AMBAS FECHAS, LA INICIAL Y LA FINAL"
End If
Muchas gracias. Un saludo
Puedes, en vez de aplicarle un filtro al formulario, cambiarle el origen de datos y hacer el filtro ahí. El código es muy parecido, pero en vez de usar la propiedad Filter y FilterOn, Usas Recordsource, y le pasas la SQL completa, no solo la parte del WHERE, algo como:
... If Not IsNull(txtFechaInicio) And Not IsNull(txtFechaFin) Then sFiltro = "SELECT Libro, Count(Libro) AS Cuenta FROM TPtmos FechaPtmo BETWEEN # " & Format(Me.txtFechaInicio, "mm-dd-yyyy") & _ "# AND #" & Format(Me.txtFechaFin, "mm-dd-yyyy") & "# GROUP BY Libro" Me.[Subformulario libros más leídos_1].Form.RecordSource= sFiltro 'Si así no se te actualiza el subform con los datos del filtro, añade esta linea ' Me.[Subformulario libros más leídos_1].Form.Requery Me.[Subformulario libros más leídos_1].Visible = True Else ...
También puedes vincular los cuadros de texto del formulario en los criterios de la consulta, y no te haría falta aplicar el filtro por código:
SELECT TPtmos.Libro, Count(TPtmos.Libro) AS [Ptmos periodo] FROM TPtmos WHERE (((TPtmos.Fecha) Between [Formularios]![NombreFormulario]![txtFechaInicio] And [Formularios]![NombreFormulario]![txtFechaFin])) GROUP BY TPtmos.Libro;
Gracias sveinbjorn el rojo.
Me has puesto el listón muy alto. De todos modos lo voy a intentar.
Un saludo
Hola, Sveinbjorn El Rojo. Primeramente darte la gracias por tu tiempo a la vez que decirte que he aplicado las dos opciones que me indicabas con resultado dispar.
Mientras que funciona perfectamente si vinculo los cuadros de texto del formulario en los criterios de consulta.
Quedaría así:
SELECT TOP 10 T_LibMLeídos.IdLibro, Count(T_LibMLeídos.IdLibro) AS CuentaDeIdLibro, T_LibMLeídos.Título, T_LibMLeídos.Autor
FROM T_LibMLeídos
WHERE (((T_LibMLeídos.FechaPtmo) Between [Formularios]![F_libros más leídos]![txtFechaInicio] And [Formularios]![F_libros más leídos]![txtFechaFin]))
GROUP BY T_LibMLeídos.IdLibro, T_LibMLeídos.Título, T_LibMLeídos.Autor
ORDER BY Count(T_LibMLeídos.IdLibro) DESC;
Para que quede un poco mejor he creado un botón que me traslada toda la información a un informe y queda bastante bien.
La segunda opción es otra cuestión porque si trato de filtrar en el formulario me da mensaje de error 3131 en tiempo de ejecución a la vez que Error en sintaxis cláusula FROM y el cursor se posiciona en la línea que he puesto en negrita y letra cursiva.
………….
If Not IsNull(txtFechaInicio) And Not IsNull(txtFechaFin) Then
sFiltro = "SELECT IdLibro, Count(IdLibro) AS Cuenta FROM C_LibMLeídos.FechaPtmo BETWEEN # " & Format(Me.txtFechaInicio, "mm-dd-yyyy") & _
"# AND #" & Format(Me.txtFechaFin, "mm-dd-yyyy") & "# GROUP BY IdLibro"
Me.[Subformulario libros más leídos].Form.RecordSource = sFiltro
Me.[Subformulario libros más leídos].Form.Requery
Me.[Subformulario libros más leídos].Visible = True
Else
………………
Viendo que el problema está resuelto no sé si interesa perder el tiempo con la segunda opción aunque si tienes tiempo y no te molesta demasiado échale un vistazo a ver el error que cometo.
Gracias
El error esta en que después del From tienes que poner el nombre se una tabla o consulta, y tu parece que pones el de una /consulta y un campo...
También te faltaría un WHERE para añadir la parte del filtro.
Es como si te hubieras comido un trozo se sql... jejeje
Hola, Sveinbjorn El Rojo.
Después de estar devanándome los sesos unos días tengo que decir que no he conseguido resolver la situación. He sustituido los términos por los nombres de mis tablas y campos y siempre me aparece el mensaje de error que aparecía anteriormente.
Tengo que decir que he obtenido el resultado deseado con la instrucción que figura mas abajo, pero me genera dudas porque mientras que tú en la instrucción haces mención solo y exclusivamente a “campos”, yo tengo que poner el título de la tabla y el campo. También que en el Where no me ha hecho falta hacer referencia al formato fecha al estilo US.
Supongo que debo haber cometido todo tipo de errores y tropelías informáticas, jajajajaj.
Échale un vistazo si puedes. Muchas gracias y un saludo
Esta es la instrucción.
……….
End If
If Not IsNull(txtFechaInicio) And Not IsNull(txtFechaFin) Then
sFiltro = "SELECT T_LibMLeídos.IdLibro, Count(T_LibMLeídos.IdLibro) AS CuentaDeIdLibro, T_LibMLeídos.Título, T_LibMLeídos.Autor " _
& "FROM T_LibMLeídos " _
& "WHERE (((T_LibMLeídos.FechaPtmo) Between [Formularios]![F_libros más leídos]![txtFechaInicio] And [Formularios]![F_libros más leídos]![txtFechaFin])) " _
& "GROUP BY T_LibMLeídos.IdLibro, T_LibMLeídos.Título, T_LibMLeídos.Autor " _
& "ORDER BY Count(T_LibMLeídos.IdLibro) DESC;"
………..
La SQL está bien, y si le quitas todos los T_LibMLeídos menos el que va después del FROM, te funcionará igual. El nombre de la tabla solo es obligatorio ponerlo cuando en el SELECT interviene más de una, y aún así, si los campos no se llaman igual, es muy probable que también funcione sin ponerlo...
En cuanto al formato americano, no te hace falta porque esa SQL vincula directamente con el formulario a través del motor SQL de Access (vamos, como cuando creas la consulta en vista diseño y copias la SQL resultante), y ya se encarga él de coger el formato adecuado (el americano). En la SQL que te proponía yo, la construyes encadenando cadenas de texto, en concreto el valor de un cuadro de texto del formulario (aunque parezca lo mismo, no lo es), y si no lo formateas adecuadamente, puedes encontrarte con que no te muestra todos los registros que debiera
- Compartir respuesta
Si no te quieres calentar la cabeza con código lo mejor es que, si por ejemplo, tienes una tabla Libros
Crea una consulta Consulta1 con este diseño
Y con esta consulta crea otra Consulta2 con el diseño
Cuando vayas a abrir está última te pedirá las fechas entre las que quieres ver y el resultado. En este caso he puesto las fechas para que salgan todos
En caso de que quisieras limitar los registros a, por ejemplo, los tres más vistos, en la barra de menús, en Devuelve le pones 3
Icue, gracias por la respuesta.
Ya había contemplado la posibilidad que me indicas, y la estuve probando con un resultado nada satisfactorio por lo que supongo que estaba haciendo algo mal. Lo probaré para saber en dónde estaba cometiendo el error.
Dicho lo anterior lo que trato es que la información se plasme en un formulario, subformulario o informe.
Gracias por tu tiempo.
Un saludo
- Compartir respuesta
Vicente: Si interpreto bien tu pregunta, solo tienes que agrupar por libro, como dices que lo estás haciendo y en un Campo de la consulta que se puede llamar Veces en lugar de agrupar puedes poner >>
Veces: DCont("*";"Pedidos";"Pedidos!IdCliente = '" & [IdCliente] & "'" & " AND " & "FechaPedido >=#" & Format([Formularios]![VisorConFechas]![TxtDesdeFecha];"mm/dd/aaaa") & "#" & " AND " & "FechaPedido <=#" & Format([Formularios]![VisorConFechas]![TxtHastaFecha];"mm/dd/aaaa") & "#")
En lugar de Agrupar Por >> Expresión
Adapta los Nombres a los tuyos teniendo en Cuenta que:
Pedidos >> Es la Tabla que en tu caso pueda ser LibrosLeidos
IdCliente >> Tu identificador de Libro ( que lo he puesto como Texto). Si fuera un Numero sería >>
= " & IdCliente & "
FechaPedido >> Puede ser una FechaDevolucion por ejemplo
VisorConFechas es el Nombre del Formulario que contiene la TxtFechaDesde y TxtFechaHasta
Un saludo >> Jacinto
Jacinto, muchas gracias.
Voy a probar la solución que me dices.
Mi nivel de destreza con Access y con VBA es ínfimo por lo que igual tardo unos días en publicar el resultado de las prueba.
Muchas gracias. Un saludo
Hola Jacinto.
Decir que he intentado todas las posibilidades que mi conocimiento de access me permite y no he conseguido el resultado deseado. Siento molestarte nuevamente.
La expresión que me indicaste la transformé a mi consulta atendiendo a las observaciones que me hacías, cambié los nombres de los campos por los que tengo y también el IdClientes que ha pasado a ser IdLibro y con formato de número al ser el número (autonumérico) que ocupa en la biblioteca.
La expresión ha quedado como sigue:
Veces: Cuenta(DCont("*";"T_LibMLeídos";"T_LibMLeídos!IdLibro = " & [IdLibro] & "" & " AND " & "FechaPtmo >=#" & Format([Formularios]![Libros más leídos]![txtFechaInicio];"mm/dd/aaaa") & "#" & " AND " & "FechaPtmo <=#" & Format([Formularios]![Libros más leídos]![txtFechaFin];"mm/dd/aaaa") & "#"))
Si ejecuto la consulta (desde consultas),tras pedirme la fecha de inicio y la fecha fin me muestra toda la relación de los libros que han sido prestados. No hace ningún acotamiento (filtro) pero si totaliza el número de veces que ha sido prestado el libro. Si por el contrario me dirijo al formulario, tras solicitarme la fecha inicial y final aparece un mensaje de aviso con el siguiente texto. “Error de sintaxis en la fecha en la expresión de consulta “T_LibMLeídos!IdLibro = 30 And FechaPtmo >= ## AND FechaPtmo <=#’.
Tras mostrar el mismo error en cada uno de los libros prestados (no acota por filtro), aparece toda la relación de libros prestados pero sin el número de veces prestado.
Agradecería me pudieras ayudar. Gracias
Un saludo
Vicente: De entrada veo dos errores:
1.- Sobra el Cuenta( inicial con lo que sobraría el paréntesis Final
2.- Sobra una de las "2 dobles comillas" que hay después de ..." & [IdLibro] & ""
De ese modo y si tus nombres están bien yo probaría con >>
Veces: DCont("*";"T_LibMLeídos";"T_LibMLeídos!IdLibro = " & [IdLibro] & " & " AND " & "FechaPtmo >=#" & Format([Formularios]![Libros más leídos]![txtFechaInicio];"mm/dd/aaaa") & "#" & " AND " & "FechaPtmo <=#" & Format([Formularios]![Libros más leídos]![txtFechaFin];"mm/dd/aaaa") & "#")
o más simplificada
Veces: DCont("*";"T_LibMLeídos";"T_LibMLeídos!IdLibro = " & [IdLibro] & " & " AND FechaPtmo >=#" & Format([Formularios]![Libros más leídos]![txtFechaInicio];"mm/dd/aaaa") & "#" & " AND FechaPtmo <=#" & Format([Formularios]![Libros más leídos]![txtFechaFin];"mm/dd/aaaa") & "#")
Ya me contarás >> Un saludo >> Jacinto
Muchas gracias, Jacinto.
He comprobado que con las observaciones (modificaciones ) que me has hecho, añadiendo una doble comilla en el ampersand (" & [Idlibro] & "" & " AND " & ) y después diciendo que solamente muestre aquellos valores que sean superiores a cero, el resultado es el deseado.
Muchas gracias.
Ahora me toca estudiar de qué manera puede surtir el mismo efecto si las fechas se solicitan desde un formulario.
Seguro que te doy la paliza nuevamente.
Nuevamente muchas gracias.
- Compartir respuesta