Filtrar por fecha un campo con Fecha y hora

Me hallo haciendo un formulario de consulta, en que el usuario tendrá varios campos por los que filtrar los registros.

Para ello he utlizado de referencia el ejemplo de Filtros Multiples de la web de Neckkitto (http://siliconproject.com.ar/neckkito/index.php/component/content/article/93-ejemplos-explicados/ejemplos-de-formularios/194-crear-un-filtro-multiple ) De la siguiente manera:

Private Sub cmd_query_Click()
'Defino variables
Dim vLote As String
Dim vLoteInspeccion As String
Dim vIDH As String
Dim vStatus As Integer
Dim vFechaEntrega As Variant
Dim vLargo As Integer
Dim miFiltro As String
'Funcion Nz (Define un valor como una cosa cuando no es null, o como otra cuando si que lo es)
'           (Ej: vLote tiene el valor de Me.qryLote cuando este no sea null, o "" cuando si lo sea)
vLote = Nz(Me.qryLote.Value, "")
vLoteInspeccion = Nz(Me.qryLoteInspeccion, "")
vIDH = Nz(Me.qryIDH, "")
vFechaEntrega = Nz(Me.qryFechaEntrega, "")
vStatus = Nz(Me.qryStatus, 0)
'Comenzamos con el filtro vacio
miFiltro = ""
'Añadimos las partes de la sentencia SQL según si el campo en concreto es null o no. (OJO al espacio antes de AND)
If vLote <> "" Then
    miFiltro = miFiltro & " AND [Lote]='" & vLote & "'"
End If
If vIDH <> "" Then
    miFiltro = miFiltro & " AND [IDH]='" & vIDH & "'"
End If
If vLoteInspeccion <> "" Then
    miFiltro = miFiltro & " AND [Lote_Inspeccion]= & vLoteInspeccion & "
End If
If vStatus <> 0 Then
    miFiltro = miFiltro & " AND [Status]= " & vStatus & ""
    End If
If vFechaEntrega <> "" Then
miFiltro = miFiltro & " AND [Fecha_Entrega]= #" & Format(vFechaEntrega, "dd/mm/yyyy") & "#"
End If
vLargo = Len(miFiltro)  '(Cuenta los caracteres de miFiltro)
If vLargo <> 0 Then     '(Si miFiltro no tiene 0 caracteres, es decir, si existe, entonces eliminamos los 4 primeros, que corresponden al primer " AND")
    miFiltro = Right(miFiltro, vLargo - 4)
'(Con miFiltro ya construido, puedo crear el Filtro por SQL del que se alimenta el subform)
    Filtro = "SELECT * FROM [Consulta_Visualizacion_Subformulario] WHERE" & miFiltro & ";"
    Me.Formulario_Visualizacion_Subformulario.Form.RecordSource = Filtro
End If
End Sub

Sin embargo, me encuentro el problema de que a la hora de filtrar por fechas no me funciona, puesto quelos registros se guardan en formado "dd/mm/aaaa hh:mm:ss", sin embargo a la hora de filtrar, me interesa buscar solo por fecha y que me muestre todos los registros del día seleccionado.

Si ahora mismo lo hago de esta manera, no me devuelve ningún resultado ya que ninguno coincide totalmente.

¿Existe alguna forma de dividir el valor guardado en fecha y hora por separado o quizás estoy planteando mal el problema?

2

2 respuestas

Respuesta
2

Aplica la función Format() también al campo de la tabla, para quedarte solo con la parte de fecha:

miFiltro = miFiltro & " AND Format([Fecha_Entrega],'dd/mm/yyyy')= #" & Format(vFechaEntrega, "dd/mm/yyyy") & "#"

Así te debiera funcionar.

Un saludo.


bit.ly/NkSvAcademy   /    bit.ly/ForoNkSv 

¡Gracias! 

Después de probar tu solución me funcionaba solo parcialmente, ya que me filtraba sin problema fechas con dos dígitos en el día y el mes (Ej: 27/10/2018), pero me devolvía 0 resultados con fechas de un solo dígito (03/05/2018).

Finalmente me decidí a crear un nuevo campo en la Consulta donde va a buscar los resultados, DiaEntrega: Format(Fecha_Entrega, 'Fecha Corta') y ni aún así funcionaba el formulario.

Sin embargo desde el diseño de consultas, si filtraba si que funcionaba con las fechas problemáticas. Consultando el código SQL una vez creado el diseño vi que la condición #03/05/2018# me la convertía en (...)WHERE #3/5/2018#

Finalmente trasteando un poco, probé a tratar la fecha como un numero y dejé el código así:

miFiltro = miFiltro & " AND [DiaEntrega]='" & vFechaEntrega & "'"

Ahora funciona como un guante y no me da problemas para ninguna fecha

Igual he hecho una barbaridad, pero de momento me ha solucionado la papeleta.

Muchas gracias por tu ayuda!

Tu "problema" con las fechas tiene fácil explicación y solución: los lenguajes de programación están "basados" en inglés, americano, para más señas, y por tanto las fechas las entiende en formato americano, como mm/dd/yyyy.

En consecuencia, la mejor forma de trabajar con fechas es usar siempre ese formato, es decir, usar

Format([campoFecha],"mm/dd/yyyy") y no Format([campoFecha],"dd/mm/yyyy")

¡Gracias! No hay ni una sola aportación tuya de la que no aprenda algo. No te haces ni idea de lo agradecido que estoy.

De momento lo voy a dejar como está porque funcionar, funciona y me están presionando para avanzar por otros lares, pero no dudes que cuando tenga un rato probaré a modificar los formatos.

Hola Sveinbjorn!

Disculpa que te vuelva a molestar, pero es que al final he tenido que volver a lo que me dijiste la semana pasada para seguir ampliando la base.

Mi jefe me ha pedido que no filtre por un día en concreto sino por un rango, así que tiré por donde me dijiste y cambié a Format([CampoFecha], "mm/dd/yyyy") para poder hacer una SQL con el operador BETWEEN.

Finalmente la parte de código referente a las fechas ha quedado así:

Dim vFechaEntregaInicio As Variant
Dim vFechaEntregaFin As Variant
vFechaEntregaInicio = Nz(Me.qryFechaEntregaInicio, "")
vFechaEntregaFin = Nz(Me.qryFechaEntregaFin, "")
If vFechaEntregaInicio <> "" And vFechaEntregaFin = "" Then
    miFiltro = miFiltro & " AND Format([Hora_Entrega], 'dd/mm/yyyy')=#" & Format(vFechaEntregaInicio, "mm/dd/yyyy") & "#"
    ElseIf vFechaEntregaInicio <> "" And vFechaEntregaFin <> "" Then
        miFiltro = miFiltro & " AND Format([Hora_Entrega], 'dd/mm/yyyy') BETWEEN #" & Format(vFechaEntregaInicio, "mm/dd/yyyy") & "# AND #" & Format(vFechaEntregaFin, "mm/dd/yyyy") & "#"
End If
vLargo = Len(miFiltro)  '(Cuenta los caracteres de miFiltro)
If vLargo <> 0 Then     '(Si miFiltro es mas largo de 0 caracteres, es decir, si existe, entonces eliminamos los 4 primeros, que corresponden al primer " AND")
    miFiltro = Right(miFiltro, vLargo - 4)
'(Con miFiltro ya construido, puedo crear el Filtro por SQL del que se alimenta el subform)
    Filtro = "SELECT * FROM [Consulta_Visualizacion_Subformulario] WHERE" & miFiltro & ";"
    Me.Formulario_Visualizacion_Subformulario.Form.RecordSource = Filtro
End If
End Sub

Sin embargo, cuando filtro por un rango de fechas con este, me incluye registros que deberian quedar fuera.

Esto es lo más cerca que he estado de hacer que funcione como debería, ya que probé a definir como:

(...)miFiltro = miFiltro & " AND Format([Hora_Entrega], 'mm/dd/yyyy') BETWEEN (...)

Pero entonces directamente no me devuelve ningún registro cuando aplico el filtro

Estoy seguro que es alguna tontería a la hora de definir el formato de la fecha, pero sinceramente ya no se me ocurre donde más mirar o que probar...

¿Algo de orientación para un novato perdido?

En el código que pones usas, en la parte izquierda de la igualdad (el campo de la tabla) la función Format con formato europeo (dd/mm/yyyy), mientras que en la parte derecha (cuadro del formulario) usas Format con formato americano (mm/dd/yyyy).

Tienes que usar en las dos partes el mismo formato, en concreto el americano.

Pero entonces lo que me ocurre es lo de la segunda imagen, donde no me devuelve ningún resultado.

Veo que modificas el Recordsource del subformulario (que no es la opción de filtrar que más me gusta) pero no le haces un requery.

¿Probaste a usar Format() solo en la parte derecha del filtro?

También veo que tu campo almacena fecha y hora, puedes probar a hacerlo así:

miFiltro = miFiltro & " AND [Hora_Entrega] BETWEEN #" & Format(CDate(vFechaEntregaInicio & " 00:00:00"), "mm/dd/yyyy hh:nn:ss") & " & "# AND #" & Format(CDate(vFechaEntregaFin & " 23:59:59"), "mm/dd/yyyy hh:nn:ss") & "#"

¡Gracias Sveinbjorn!

Disculpa la tardanza, pero me tienen trabajando en este proyecto de forma intermitente.

Probé a usar Format() solo en la parte derecha del filtro. Después solo en la parte izquierda. Después creo que hasta me dediqué a probar todas las posibles combinaciones que se me ocurrían y nada de nada.

Sin embargo con el filtro que me has propuesto, utilizando CDate, no he tenido ningún problema. Ha funcionado como mano de santo!

Muchísimas gracias por todo!

Respuesta
2

Miguel, los ordenadores no trabajan con fechas, trabajan con números. Al día 01/01/1900 se le asignó el 1 y sucesivamente hasta hoy. Por eso si un campo lo defines como fecha general, aunque veas 31/05/2018 10:05:00 en realidad lo que estás guardando es, por ejemplo 41305,6578 siendo 6578 las horas, minutos y segundos (son decimales de día). Al poner en el campo FechaEntrega formato fecha general, estás guardando el numero completo, con decimales. Pero si en el formulario de búsqueda, la fecha la vas a poner en formato dd/mm/aaaa en realidad el valor es entero, 41305. Al decirle tu que te busque aquellos registros en que fecha entrega sea = 41305 te dice que naranjas de la china, que no hay ninguno igual, porque el que hay en la tabla es 41305,6578

Para solucionarlo podrías usar la función Int que coge sólo la parte entera del campo. Por ejemplo

me.recordsource="select * from clientes where int[fechaentrega])=forms!nombredelformulario!fechafiltro"

¡Gracias Icue!

Estuve probando un rato y no conseguí aclararme. 

Sin embargo encontré otra solución y de momento me ha arreglado la situación.

A pesar de ello, lo de las fechas es un dato que desconocía y buscaré mas información al respecto, pues creo que me será muy útil en un futuro próximo.

Muchas gracias por tu ayuda!

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas