Pasa Programación, apuntes y soluciones con Access
Página principal Mis apuntes de Access Mis utilidades Mis ejemplos Mis agradecimientos Enlaces a otras Webs

Fechas y horas en Access

  1. Índice.
  2. Qué es una fecha.
  3. Qué tipos de campo de fecha hay.
  4. 5 de enero o 1 de mayo.
  5. Operar con fechas.
  6. Bibliografía.

5 de enero o 1 de mayo

Cuando 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úmero

Si 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 literal

Access 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:

  • #mes/día/año# Es el formato americano, y como estos programas se han desarrollado en Estados Unidos, es el formato predefinido para los literales de fecha. En nuestra Sql de ejemplo, hemos indicado #01/05/2008# (mes 1, día 5, año 2008).
  • #año/mes/dia# Es el formato ISO o internacional (algun@s lo conocen como japonés, ya que es el que se usa en ese país). Si en la instrucción Sql cambiamos el valor #01/05/2008# por #2008/01/05#, obtendremos el mismo resultado.
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 texto

Las 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(), que sirve para convertir una expresión en una fecha, nos permite esto:

? 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, CDate() nos devuelve una fecha que es el 1 de mayo. Pero si el formato de fecha está establecido a mes/día/año, la misma instrucción nos devuelve 5 de enero. Puedes comprobarlo sencillamente. Copia y pega la siguiente instrucción en la ventana Inmediato de VBA:

? 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 funciones

Si 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 Now(), al igual que otras funciones de fecha, devuelven un objeto de tipo Variant, pero con un subtipo de Fecha, lo que permite a Access entender qué fecha es exactamente, sin tener que ir a comprobar la configuración regional para formatear la fecha. Para entendernos un poco mejor, si usamos una función de Access (o una personalizada por nosotros) que devuelva un objeto Date o un objeto Variant de subtipo Fecha, es como si le indicáramos la fecha como un valor numérico, tal y como vimos más arriba, en el apartado Fechas como número.

2008 Patxi Sanz
Libro de visitas
Hosted by www.Geocities.ws

1