![]() |
||||||
|
|
||||||
Fechas y horas en Access
5 de enero o 1 de mayoCuando usamos fechas para filtrar los registros en una consulta, nos podemos encontrar con que Access nos devuelve registros cuyas fechas no se encuentran dentro del criterio que hemos indicado, o eso es al menos lo que nos parece. También ocurre a veces que al insertar o actualizar una fecha mediante consultas o VBA, la fecha almacenada no se corresponde a la que queríamos guardar. Esto suele pasar por el trato que da Access (y otros gestores de bases de datos) a las fechas. Al guardarlas como valores numéricos y mostrarlas como valores alfanuméricos, Access y/o VBA deben convertir las fechas que pasamos en números para poder usarlas, ya sea en consultas o en el código. Y la conversión que va a realizar depende de cómo pasemos las fechas y horas. O mejor dicho, de cómo le digamos a Access que le estamos pasando las fechas: Fechas como númeroSi usamos un número en una consulta o en VBA, podemos estar seguros de que Access va a saber perfectamente a qué fecha nos estamos refiriendo, ya que no tiene que hacer ningún tipo de conversión. Por ejemplo, si en la base de datos de ejemplo creamos la siguiente consulta:
SELECT * FROM TablaPruebas WHERE SoloFecha > 39500
La consulta nos devolverá todos los registros en los que la fecha guardada en el campo SoloFecha sea mayor que 39.500 (22 de febrero de 2008). Con este tipo de consultas podemos estar seguros de no equivocarnos nunca con las fechas, pero tenemos un problema: saber que estamos introduciendo una fecha que deseamos, porque ¿quién sabe a qué fecha corresponde el número 39999? La respuesta es sencilla: sólo Access y VBA, pero no el/la usuari@ de la base de datos. Fechas como literalAccess y VBA permiten que pasemos las fechas como literales; es decir, un texto delimitado por almohadillas (#) que corresponde a una fecha. Así, si cambiamos la Sql anterior por esta:
SELECT * FROM TablaPruebas WHERE SoloFecha < #01/05/2008#
La consulta nos devolverá todos los registros cuyo valor en el campo SoloFecha sea inferior al cinco de enero de 2.008. Y este valor es indiferente de nuestra configuración regional, ya que Access y VBA siempre esperan recibir un literal de fecha con uno de los siguientes formatos:
Nota: Hay otros formatos que Access y VBA permiten usar, pero aquí no los tendremos en cuenta, ya que el mes hay que introducirlo como texto, y tendríamos que usar los nombres de los meses en inglés. Si no tenemos claro esto, nos pasará lo que a tod@ programdor@ le ha pasado alguna vez: Crear una consulta similar a esta:
SELECT * FROM TablaPruebas WHERE SoloFecha < #05/01/2008#
Pensando que iba a seleccionar las fechas anteriores al 5 de enero, y encontrarse con registros de febrero, marzo, abril y mayo. Y el problema es mucho mayor porque Access nos permite hacer esto:
SELECT * FROM TablaPruebas WHERE SoloFecha < #25/01/2008#
La fecha pasada, #25/01/2008#, no se asemeja a ninguno de los formatos indicados: mes/día/año o año/mes/día. Sin embargo, Access no se queja y nos muestra los datos que queríamos: todas las fechas anteriores al 25 de enero. ¿Por qué pasa esto? Porque Access está muy mal acostumbrado: recoge la fecha y se da cuenta que no la puede convertir según los formatos que conoce. Pero, antes de dar un error, revisa una serie de formatos más o menos comunes, y se da cuenta que hay un formato de fecha con el valor día/mes/año. Así que prueba a convertir los datos a ese formato, y se encuentra con una fecha válida, con lo que procede a mostrar los datos. En cambio, si pasamos la fecha como mes/año/día, por ejemplo, sí que nos dará un error porque ese formato no lo reconoce. ¿Y VBA tiene el mismo problema? Pues sí, pero también es un poco más educado. Si creamos una fecha dentro de una función, y le intentamos dar el valor #25/01/2008#, VBA nos lo convierte automáticamente a #01/25/2008#, lo que siempre ayuda un poco. También nos sirven de ayuda las vistas Sql y Diseño de las consultas de Access. Si creamos una de las consultas anteriores en vista Sql y pasamos a vista Diseño, veremos que el valor que hemos escrito (por ejemplo, #01/05/2008#) lo ha convertido al formato de fecha que tengamos definido en la Configuración regional de nuestro ordenador. En mi caso, ese formato es día/mes/año, con lo que el valor lo convierte a #05/01/2008#. Así podemos controlar cómo se ven las fechas (vista Diseño de la consulta) y cómo quiere trabajar Access con ellas (vista Sql de la consulta). Fechas como textoLas fechas no las podemos pasar entrecomilladas, como si fueran texto. Este tipo de conversión no nos lo permite Access en las vistas Diseño o Sql de la consulta. De hecho, si intentamos hacer algo similar a esto:
SELECT * FROM TablaPruebas WHERE SoloFecha < "05/01/2008"
Access nos va a mostrar un mensaje similar a este: No coinciden los tipos de datos en la expresión de criterios Que viene a decir: no acepto textos para filtrar un campo de fecha y hora. Y aunque guardemos la consulta, no podremos usarla en código, en las propiedades de los controles con DLookup, DSum, etc., o como origen del registro de un formulario o informe. Obtendremos el mismo resultado, un error, si intentamos usar una fecha entrecomillada para una función de VBA que espere una fecha para filtrar un campo. Por ejemplo, si escribimos esto en la ventana Inmediato:
? DCount("SoloFecha", "SelectConTextos", "SoloFecha = '05/01/2008'")
Pero hay funciones en VBA que sí permiten recibir una cadena de texto que representa una fecha. Por ejemplo, la función
? CDate("01/05/2008")
Pero en estos casos hay que tener mucho cuidado: al pasar una cadena de texto, esta función supone que estamos pasando "algo" que se corresponde con la configuración regional del ordenador, así que si la configuración regional está establecida a día/mes/año,
? Format(CDate("01/05/2008"), "dddd, dd \de mmmm \de yyyy")
Y ejecútala. Verás un resultado parecido a jueves, 01 de mayo de 2008, o puedes obtener un resultado completamente distinto: sábado, 05 de enero de 2008, dependiendo de tu configuración regional. Una vez la hayas ejecutado, ve a tu Configuración Regional y cámbiala. Aplica y acepta los cambios, y vuelve a ejecutar la instrucción: verás que el resultado es completamente distinto: depende de la configuración que hayas indicado. ¿Y qué ocurre si indicamos un formato del tipo año/mes/día? Pues pasa algo similar a lo indicado más arriba: como el texto pasado no se adecúa al formato, VBA decide que el formato es el americano: mes/día/año. Fechas devueltas por funcionesSi en vez de tener una fecha fija, tal como #05/01/2008# tenemos una fecha devuelta por una función, como en la sentencia siguiente:
SELECT * FROM TablaPruebas WHERE SoloFecha < Now();
El resultado que obtenemos es todas las fechas anteriores a la fecha actual. Y aunque cambiemos la configuración regional, el resultado será el mismo, independientemente del formato que tengamos. Esto es así, ya que la función |
||||||
|
2008 Patxi Sanz Libro de visitas |