Magia potagia y ases en la manga I
Este artículo va a resultar un poco raro porque va a contar cosas algo raras que he estado haciendo con Access 2007 y en el mismo orden en que han vagado mis ideas de un lado para otro: ninguno.
Resulta que ando últimamente hechizado por la magia de las consultas a base de una tabla de números consecutivos que combinamos con otra tabla sin establecer relaciones, de manera que el resultado es un producto cartesiano que luego filtramos. Es una técnica conocida pero, en general poco usada ¿Qué pasa si echamos una pastilla efervescente en la clara de huevo? ¿Y si cocemos un huevo en el microondas? ¿Y si me suturo la herida del dedo con Super Glue? Yo soy de los que tienen que probar, aunque ya lo hayan hecho otros, y estas consultas raras me permiten experimentos sin tener que fregar luego la gaseosa derramada. Esta vez me lo he pasado tan bien que tengo que contarlo, como Dominguín después de lo de Ava Gadner.
Usar memos para crear un calendario sin usar casi código
Ya dije que la cosa era un poco rara y, como seguirá siendo rara, empezamos por el final. Éste es el formulario:
Y éste es todo el código:
Option Compare Database
Option ExplicitPrivate Sub Comando45_Click()
TempVars!AñoInicial = Nz(TempVars!AñoInicial, Year(Date)) + 1
Me.Anyo.Requery
End SubPrivate Sub Comando46_Click()
TempVars!AñoInicial = Nz(TempVars!AñoInicial, Year(Date)) – 1
Me.Anyo.Requery
End Sub
Pero, para hacer esto no necesitaba usar alguna de las cosas raras que he usado. Para lo que las he necesitado ha sido para conseguir esto otro:
Tabla Calendar:
Se trata de crear un informe que presente tantos calendarios mensuales como sean necesarios para mostrar todos los periodos anotados en un conjunto de registros. Y todo el código VBA que necesita es éste:
Option Compare Database
Option ExplicitPrivate Sub EncabezadoDelGrupo0_Format(Cancel As Integer, FormatCount As Integer)
TempVars!AñoInicial = Me.Anyo.Value
End SubPrivate Sub Report_Close()
TempVars.Remove («AñoInicial»)
End SubPrivate Sub Report_Open(Cancel As Integer)
TempVars!AñoInicial = Year(DMin(«Fecha», «qryFestivosVirtuales»))
End Sub
Números y fechas
Una fecha es un número, por lo que si a una serie de números le sumamos una fecha, tenemos una serie de fechas. Podemos añadir campos calculados para mes, año o día de la semana. Hace falta una tabla, que llamaremos Números (sí, con acento, en español) con un campo que llamaremos Número y que llenamos con números consecutivos y que nos va a servir para muchas más cosas. Con sólo esa tabla podemos hacer una consulta así:
SELECT [número]+DateSerial(Year(Date()),Month(Date()),1)-1 AS Fecha, Format([fecha],»dddd») AS Dsemana, (Month([fecha])) AS Mes, (1+(([fecha]-2)7)) AS Fila
FROM Números;
El resultado es una cosa así:
Nos sale un campo raro que se llama fila y que usaremos más adelante para unos cálculos. Si guardamos esta consulta como «Fechas Virtuales» y sobre ella hacemos una de referencias cruzadas usando el día de la semana como encabezados de columna.
TRANSFORM Min([Fechas virtuales].Fecha) AS MínDeFecha
SELECT [Fechas virtuales].Fila, Month([fecha]) AS mes, Year([fecha]) AS Anyo
FROM [Fechas virtuales]
GROUP BY [Fechas virtuales].Fila, Month([fecha]), Year([fecha])
PIVOT [Fechas virtuales].Dsemana In («lunes»,»martes»,»miércoles»,»jueves»,»viernes»,»sábado»,»domingo»);
Obtenemos el siguiente resultado:
¡Juer! ¿Y dónde está eso del producto cartesiano? Tranqui, de momento no hace falta, ya lo usaremos luego. Ahora, de momento, vamos a ponerlo en un formulario para que quede más mono:
La magia y el producto cartesiano (¿Descartes y magia? :-S)
Muy fácil de hacer el calendario, pero no sirve para nada; para eso es mucho más sencillo utilizar un MonthViewer ActiveX. Le faltan las fechas en colores marcando los distintos periodos que tenemos guardados en nuestra tabla Calendar.
Cogemos nuestra tabla:
Abra Cadabra…
SELECT [start Time]+[número]-1 AS Fecha, Calendar.ID
FROM Calendar, Numeros
WHERE ((([start Time]+[número]-1)<=[end time]))
ORDER BY [start Time]+[número]-1;
Le Voilá!
Hemos sacado todas las fechas correspondientes a los periodos de nuestro calendario. Y todavía no hemos escrito una línea de código.
Pero… Si nos fijamos, se trata de un formulario continuo y, si cambiamos el color del texto en un campo de un registro, se cambiará en todos. Podríamos usar formato condicional, pero falla más que una escopeta de feria y, además, iba a ser lento.
Un memo en la manga
Sabemos que los controles que muestran campos memos tienen una propiedad TextFormat que, usando etiquetas HTML permite mostrar el texto en formato de texto enriquecido. Si al cuadro de texto le ponemos como origen un campo de distinto tipo, no admite el formato de texto enriquecido, pero, si usamos un campo calculado, sí que nos lo va a admitir. Vamos, que como no sabe qué tipo de campo es, se porta como un memo.
O sea, que si en un campo calculado con formato de texto enriquecido añadimos las etiquetas correspondientes, se mostrará en rojo (o como nos de la gana si usamos las etiquetas correctas:
<font color=red>» & Día([fecha]) & » </font>
Sólo tenemos que coger nuestra consulta de Fechas Virtuales, combinarla con la consulta de Festivos Virtuales y, donde coincidan ponerle las etiquetas para que luego se muestre en rojo:
SELECT [Copia de Fechas virtuales].*, IIf(Not IsNull([qryFestivosVirtuales].[Fecha]),»<font color=red>» & Day([Copia de Fechas virtuales.fecha]) & » </font>»,Day([Copia de Fechas virtuales].[fecha])) AS Expr1
FROM [Copia de Fechas virtuales] LEFT JOIN qryFestivosVirtuales ON [Copia de Fechas virtuales].Fecha = qryFestivosVirtuales.Fecha
ORDER BY IIf(Not IsNull([qryFestivosVirtuales].[Fecha]),»<font color=red>» & Day([Copia de Fechas virtuales.fecha]) & » </font>»,Day([Copia de Fechas virtuales].[fecha]));
El resultado, mostraría registros así:
Con esa consulta creamos una consulta de referencias cruzadas como la que hicimos antes:
TRANSFORM Min(FechasyFestivosVirtuales.Expr1) AS MínDeExpr1
SELECT FechasyFestivosVirtuales.Mes, FechasyFestivosVirtuales.Anyo, FechasyFestivosVirtuales.Fila
FROM FechasyFestivosVirtuales
GROUP BY FechasyFestivosVirtuales.Mes, FechasyFestivosVirtuales.Anyo, FechasyFestivosVirtuales.Fila
PIVOT [FechasyFestivosVirtuales].Dsemana In («lunes»,»martes»,»miércoles»,»jueves»,»viernes»,»sábado»,»domingo»);
Y hacemos con ella el origen de un formulario calendario como el que teníamos antes, pero los controles originales (en amarillo), los ocultamos y añadimos unos campos calculados que tengan su origen en ellos y cuyo formato de texto sea Texto enriquecido.
Después de tapar los controles invisibles con los nuevos controles calculados y reajustar los tamaños, nos queda una cosa así:
Que, cuando usemos como subformulario, al vincular por meses con el formulario principal, nos mostrará sólo los días de cada mes.
De la misma manera, podríamos haber construido un subinforme. Ya sólo queda insertar suficientes subformularios o subinformes para que cubran todo el periodo.
Pero ¿Hasta qué fecha? ¿Tendremos números suficientes? ¿Cómo seleccionamos las fechas? ¿Dónde co…o están esas líneas de código? ¿A dónde iba Dominguín a las siete de la mañana?
La respuesta en el próximo capítulo.
13 Responsesso far
O sea, que los memos han dejao de ser estúpidos… :))
Buen trabajo, me gusta que intentes suturas con super glue 😉
No olvides un tubito de Super Grue en tu botiquín ni una tabla con números consecutivos en tu base de datos 🙂
Muy, pero muy bueno.
Estaba buscando algo asi pero no lo encontraba.
Con esto sutura mi herida, Ja!
PD: Cuando tengas algo + para Access, avisame.
Mil saludos.
Cesar
Increible, más magia por favor !!! Mejor que Jorge Blas !!!
Impresionante,¿y el capitulo siguiente, cuando?
Estoy haciendo una base de datos y necesito saber como introducir un calendario con las mismas aplicaciones del que tiene outlook con recurrencias y otros en access 2007 pero sin codigo ya que no soy programadora y por tanto no entiendo esos codigos. Agradecere su ayuda a este particular.
Por favor si alguien lo pudo hacer que me envie a mi mail.. roro1650@hotmail.com… muuuuuuuuuuuuuuuuuuuuuuuchaaaaaaaaasssssssss gracias
oye pues pasa el programa ya con todo echo
Hola q tal me podrian pasar el programa ya hecho para checarlo muchas gracias amigos
En otro artículo hay un enlace a una solución ya hecha: http://geeks.ms/blogs/access/archive/2009/06/12/magia-potagia-ii-el-desenlace.aspx
He estado sigueindo los pasos para la creación del calendario y no sé de dónde sale la tabla donde aparece los campos Star Time y End Time que se utiliza para la parte en la que se explica cómo se resaltan en color algunas fechas. ¿Alguien podría decirme cómo se crea o dónde se consigue esa tabla calendar?
MUCHAS, MUCHAS GRACIAS POR ESTE SUPER CHINGON EJEMPLO EN ACCESS PARA GENERAR UN CALENDARIO… ME HA SIDO DE MUCHA UTILIDAD TU SABIA GUÍA PASO A PASO PARA COMPRENDER CON CLARIDAD LAS PROPIEDADES DE UN CAMPO CON TEXTO ENRIQUECIDO….
MUCHAS, MUCHAS GRACIAS POR TU VALIOSA PAGINA Y POR DEDICARNOS A TUS USUARIOS (ASÍ ME CONSIDERO) TU VALIOSO Y APRECIABLE CONOCIMIENTO…
Me ha encantado este blog, para todos aquellos amantes de MS Access, todo el contenido muy bien elaborado (de antemando felicito a la persona que administra este blog) por el esfuerzo dedicado a ello, asi mismo les dejo mi blog que tambien lleva el mismo proposito de compartir los alcances con MS Access a la comunidad de habla hispana. Saludos y Felicitaciones sinceras.
Visiten el AulaClick de Access
http://aulaclick-access.blogspot.com