Вы находитесь на странице: 1из 52

22/06/13

Access
Iniciar sesin | HAZTE MIEMBRO! | Ayuda

Access
Lo que vamos conociendo de Access 2007 y Access 2010 27/2/2013 0:03 Utilizar un subinforme como sustituto de un control TreeView en Access 2010 Con los problemas y vulnerabilidades cada vez mas frecuentes de los Activex, aunque existan parches para ir tirando, muchos programadores en Access han decidido finiquitar el nico control del vetusto Common Controls que segua mereciendo la pena y que careca de una alternativa nativa: el TreeView Control. El que mas y el que menos se ha elaborado sus propias soluciones recurriendo a lo que tenan a mano en Access, en general jugando con cuadros de lista o subformularios y el resultado, variable, a veces sorprende por lo sencillo y lo eficiente. Sin embargo, no conozco a nadie que haya optado por utilizar un informe. En Access una estructura en rbol se muestra fcilmente, de toda la vida, con un informe agrupado. Puede ser como una fotografa, mas rica, de un Control TreeView, pero es difcil imaginarse un informe que no sea completamente esttico, sin capacidad de contraer o expandir las ramas. Sin embargo las versiones 2007 y 2010 de Access aportaron nuevas caractersticas, la Vista Informe en 2007 y la posibilidad de incrustar un subinforme en un formulario en 2010 que, bien utilizadas, pueden convertirse en una alternativa, mas sencilla de usar, mas potente y mas bonita que el control original.

El subinforme como alternativa al TreeView Control


Desde Access 2007, existe una nueva vista para los informes, la llamada Vista Informe que, al contrario que los informes tradicionales, no est pensada para imprimir, sino para ver en pantalla; por eso no reparte el informe en pginas, por lo que tampoco se producen los eventos Format o Print, sino que lo muestra todo seguido, y, tambin por eso, admite bsquedas y filtros directamente o eventos mas propios de los formularios, como Click, DblClick, keyDown, etc. Desde Access 2010, los subInformes, en Vista Informe, se pueden incluir en un formulario exactamente igual que si fueran subformularios. Pueden ser independientes, o vinculados al formulario principal a travs de las propiedades LinkMasterFields y LinkChildFields. Con todos estos ingredientes es fcil imaginar que un informe podra sustituir con ventaja a un control TreeView. Los informes podemos vincularlos a un origen de datos de forma muy sencilla y sin escribir una sola lnea de cdigo, y podemos agrupar datos con facilidad, mostrando una estructura en ramas. Podemos usar distintos formatos de texto, colores, fondos, formatos condicionales, aadir los campos que queramos, resmenes, totales solo con unos clics de ratn. Parece que en todo, en facilidad y posibilidades, superan al control TreeView y que solo les falta una cosa: La facilidad de los controles TreeView para contraer y expandir ramas. Pues bien, esto tambin es posible con un poco de programacin, mas bien muy poco, un poco de SQL y cuidando algunos detalles del diseo, nada que no est al alcance la la inmensa mayora de los desarrolladores en Access. Aqu tenemos una imagen de un ejemplo de un subinforme ejerciendo de TreeView. Puede descargase la aplicacin de ejemplo en http://www.bengoechea.net/utilidades-1/reporttreeview

Funciona? S, y solo un parpadeo casi imperceptible a la hora de contraer o expandir una rama hace que no sea cien veces mejor que un control TreeView. Aunque hay que cuidar algunos detalles en el diseo convencional del informe para que el resultado sea el que buscamos, esta parte no se aleja de la manera de disear un informe con grupos a la que estamos acostumbrados. Lo que tiene su pequeo truco, que necesita mas explicacin, es la manera de hacer que las ramas se expandan o contraigan.

geeks.ms/blogs/access/default.aspx

1/52

22/06/13

Access

La consulta origen del informe


Un informe con grupos se basa en una nica consulta en la que estn contenidas todas las tablas relacionadas entre s por campos en comn. Si a estos campos en comn aadiramos uno mas de cada lado, cambiando su valor podramos hacer que la consulta no devolviera los registros correspondientes de esa rama, si hacemos, a continuacin de cambiar el valor de ese campo, un requery del informe basado en esa consulta, el efecto ser el de contraer o expandir la rama. A ver si me explico un poco mejor. Tenemos dos tablas, Gnero y Especie, con un campo en comn idGenero; con una consulta que vincule ambas tablas mediante ese campo el resultado ser una relacin de todos los gneros y las especies de cada gnero. Pero podemos incluir un campo mas en cada tabla, bExpandir y bExpandiendo, por ejemplo, y bExpandiendo tendra siempre valor True. Si relacionamos tambin ambas tablas por esos campos, cambiando el campo bExpandir de la tabla Gnero coincidir o no con el de la tabla Especie y, en consecuencia, se mostrarn o no las especies de ese gnero. Ese planteamiento inicial obligara a a cambiar el diseo de las tablas implicadas y a andar cambiando datos en ellas de manera poco justificada, por lo que, partiendo de esa idea, lo que hacemos es utilizar una tabla auxiliar, con el campo en comn y el campo bExpandir, que interponemos entre las dos tablas relacionadas. No necesitamos modificar ni andar tocando las tablas originales, sino que escribimos en la tabla auxiliar y, en vez utilizar una tabla auxiliar para cada par de tablas relacionadas, utilizamos una sola, con distintas consultas filtradas por el nombre de la tabla del lado uno, que son las que interponemos. As sera la consulta original del informe que mostramos arriba si fuera esttico:

O, si lo prefiere, as sera el texto SQL:


S E L E C TT t u l o s . * ,G r u p o s . * ,c u e n t a s . * F R O M( T t u l o sL E F TJ O I NG r u p o sO NT t u l o s . I D _ T I T U L O=G r u p o s . I D _ T I T U L O )L E F TJ O I Nc u e n t a sO NG r u p o s . I D _ G R U P O=c u e n t a s . I D _ G R U P O ;

Sin embargo, para poder ocultar o mostrar las ramas a voluntad, la consulta qArbolCuentas ha quedado como sta:

S E L E C TT t u l o s . * ,q E x p a n d i r T i t u l o . N o m b r e T a b l a P a d r e ,q E x p a n d i r T i t u l o . E x p a n d i r A SE x p a n d i r T i t u l o ,G r u p o s . * ,q E x p a n d i r G r u p o . N o m b r e T a b l a P a d r e ,q E x p a n d i r G r u p o . E x p a n d i r

geeks.ms/blogs/access/default.aspx

2/52

22/06/13

Access

A SE x p a n d i r G r u p o ,c u e n t a s . * F R O M( ( ( T t u l o sL E F TJ O I Nq E x p a n d i r T i t u l oO NT t u l o s . I D _ T I T U L O=q E x p a n d i r T i t u l o . i d P a d r e ) L E F TJ O I NG r u p o sO Nq E x p a n d i r T i t u l o . i d P a d r e=G r u p o s . I D _ T I T U L O ) L E F TJ O I Nq E x p a n d i r G r u p oO NG r u p o s . I D _ G R U P O=q E x p a n d i r G r u p o . i d P a d r e ) L E F TJ O I Nc u e n t a sO Nq E x p a n d i r G r u p o . i d P a d r e=c u e n t a s . I D _ G R U P O ;

Es decir, entre Ttulos y Grupos hemos interpuesto la consulta qExpandirTitulo, y, entre Grupos y Cuentas, qExpandirGrupo. Tambin hemos aadido los respectivos campos Expandir, que cambiamos de nombre. Las consultas qExpandirTitulo y aExpandirGrupo, se basan ambas en una nica tabla filtrada porque Expandir sea Verdadero y por un nombre, que podra se aleatorio, y que servir luego para filtrar en la tabla que registros modificar.

S E L E C Tt b l E x p a n d i r . I d ,t b l E x p a n d i r . i d P a d r e ,t b l E x p a n d i r . N o m b r e T a b l a P a d r e ,t b l E x p a n d i r . E x p a n d i r F R O Mt b l E x p a n d i r W H E R E( ( ( t b l E x p a n d i r . N o m b r e T a b l a P a d r e ) = " G r u p o s " )A N D( ( t b l E x p a n d i r . E x p a n d i r ) = T r u e ) ) ;

S E L E C Tt b l E x p a n d i r . I d ,t b l E x p a n d i r . i d P a d r e ,t b l E x p a n d i r . N o m b r e T a b l a P a d r e ,t b l E x p a n d i r . E x p a n d i r F R O Mt b l E x p a n d i r W H E R E( ( ( t b l E x p a n d i r . N o m b r e T a b l a P a d r e ) = " T t u l o s " )A N D( ( t b l E x p a n d i r . E x p a n d i r ) = T r u e ) ) ;

Como la tabla tblExpandir est de momento vaca, ahora la consulta qArbolCuentas solo mostrara los Ttulos, pues no existen los campo idPadre que se interponen entre las distintas tablas. Si le aadimos el ID de un ttulo, lo identificamos con el nombre Titulos y le damos al campo Expandir valor Verdadero, se mostrarn todos los Grupos de ese Ttulo, y si cambiamos Expandir a Falso, no se mostrarn, pues qExpandirTitulo solo devuelve los registros en que Expandir es verdadero. Con las consultas creadas, solo nos falta crear el informe y aadirle un par de procedimientos para que busque y modifique el campo Expandir correspondiente y lo aada si no existe.

El diseo del informe


El diseo del informe es bien sencillo, aunque hay algunos detalles que no se deben dejar escapar.

geeks.ms/blogs/access/default.aspx

3/52

22/06/13

Access

Tiene su origen en la consulta qArbolCuentas, est agrupado por Titulo y por Grupo y muestra los campos Titulo, Grupo y Cuenta y, a la izquierda de los dos primeros, el valor correspondiente de Expandir y, a la derecha de cada uno de ellos, oculto, el ID correspondiente. Debemos cuidar que las propiedad Autocomprimible, tanto de los controles que se expanden como de las secciones que los contienen, sea S y, adems, la propiedad Alto Automtico de las distintas secciones (Encabezado de Grupo y Detalle) sea tambin S. Si los controles no se comprimen, o si no se comprime la seccin que los contiene, aunque no haya contenido para ese grupo, se muestra en blanco el espacio correspondiente a ese control o a esa seccin y, aparte del derroche de espacio innecesario, el resultado es menos esttico. Lo controles solo se comprimen cuando no tienen nada que mostrar y las secciones cuando todos los controles estn comprimidos, as que no podemos aadir a las secciones prcticamente nada que no sean campos de texto que puedan estar vacos; no podemos, por ejemplo, aadir casillas de verificacin o botones. Tampoco podemos ocultarlos o cambiar de tamao sobre la marcha, pues no tenemos los eventos Format y Prine La pega que tenemos es que ExpandirGrupo y ExpandiTitulo, devuelven valores 0 y 1, aunque no haya registros que mostrar y que, adems, no queremos mostrarlos as, sino como + y . En el campo ExpandirTitulo es mas sencillo, pues, como, al ser el tronco, siempre se mostrar, y no importa que no se comprima. Lo que hacemos con el campo ExpandirGrupo es cambiarlo por un campo calculado que devuelve un nulo si el Grupo es nulo.
= S i I n m ( E s N u l o ( [ G r u p o ] ) ; N u l o ; [ E x p a n d i r G r u p o ] )

Y, en ambos campos, para que se muestren como + y , lo que utilizamos es la propiedad Formato, que tiene distintas secciones, separadas por punto y coma, para valores positivos, negativos, ceros y nulos. En ambos casos, la propiedad formato es: +;-;+

En el caso de la cuenta, no hay un campo Expandir, por lo que utilizamos un campo calculado. txtPunto, cuyo origen es:
= S i I n m ( E s N u l o ( [ C u e n t a ] ) ; N u l o ; 0 ) Y ,c o m o lo que queremos es que se muestre una vieta, la propiedad Formato es:

;; Volviendo a ExpandirTitulo, y puesto que siempre muestra algn registro, no nos ha importado adornarlo un poco poniendo un botn de forma redonda y fondo transparente sobre l, para darle un resultado mas aparente

El cdigo VBA
Lo que bsicamente hace el cdigo es que, cuando pulsamos sobre el campo ExpandirTitulo o ExpandirGrupo, que en el informe se muestran con + o , se cambia por el contrario el valor correspondiente en la tabla tblExpandir para la tabla Titulos o Grupos y, si no exista el registro en la tabla tblExpandir, se aade. A continuacin, hacemos un Requery del informe, que ser lo que produzca el efecto de contraer o expandir la rama.
P r i v a t eS u bE x p a n d i r T i t u l o _ C l i c k ( ) f F i n d E d i t T b l e x p a n d i rN z ( M e . T t u l o s _ I D _ T I T U L O ) ," T t u l o s " ,N o tN z ( M e . E x p a n d i r T i t u l o ) E c h oF a l s e M e . R e q u e r y E c h oT r u e E n dS u b P r i v a t eS u bT x t E x p a n d i r G r u p o _ C l i c k ( ) f F i n d E d i t T b l e x p a n d i rN z ( M e . G r u p o s _ I D _ G R U P O ) ," G r u p o s " ,N o tN z ( M e . T x t E x p a n d i r G r u p o ) E c h oF a l s e M e . R e q u e r y

geeks.ms/blogs/access/default.aspx

4/52

22/06/13
E c h oT r u e E n dS u b

Access

Estos eventos llaman a un procedimiento en un mdulo general que busca en la tabla tblExpandir el ID y el texto identificativo de la tabla (Ttulos o Grupos) que pasamos como argumento y cambia el valor de el campo Expandir por el que tambin le pasamos. Si no encuentra el registro, llama a otro procedimiento que lo aade con los valores de los argumentos que hemos pasado al primero. Ninguna cosa del otro mundo, pero, para que quede mas claro, pego el cdigo.
' 'P r o c e d u r e:f F i n d E d i t T b l e x p a n d i r 'D a t e T i m e :1 1 / 0 2 / 1 32 0 : 3 3 'A u t h o r :C h e a 'P u r p o s e :A b r i ru nr e c o r d s e td eD A O,b u s c a rp o ru nc a m p oya s i g n a rv a l o r ' P u b l i cF u n c t i o nf F i n d E d i t T b l e x p a n d i r ( B u s c a r l i d P a d r eA sL o n g ,s N o m b r e T a b l a P a d r eA sS t r i n g ,b E x p a n d i rA sB o o l e a n )A sL o n g D i mm i B DA sD A O . D a t a b a s e D i mr s t b l E x p a n d i rA sD A O . R e c o r d s e t O nE r r o rG o T of F i n d E d i t T b l e x p a n d i r _ E r r o r S e tm i B D=C u r r e n t D b ( ) S e tr s t b l E x p a n d i r=m i B D . O p e n R e c o r d s e t ( " t b l E x p a n d i r " ,d b O p e n D y n a s e t ) W i t hr s t b l E x p a n d i r I fN o t( . E O FA n d. B O F )T h e n . F i n d F i r s t" ( i d P a d r e="&B u s c a r l i d P a d r e&" )A N D(N o m b r e T a b l a P a d r e=' "&s N o m b r e T a b l a P a d r e&" ' ) " I fN o t. N o M a t c hT h e n . E d i t ! E x p a n d i r=b E x p a n d i r . U p d a t e . B o o k m a r k=. L a s t M o d i f i e d f F i n d E d i t T b l e x p a n d i r=! I d E l s e f A d d T b l e x p a n d i rB u s c a r l i d P a d r e ,s N o m b r e T a b l a P a d r e ,b E x p a n d i r E n dI f E l s e f A d d T b l e x p a n d i rB u s c a r l i d P a d r e ,s N o m b r e T a b l a P a d r e ,b E x p a n d i r E n dI f . C l o s e E n dW i t h S e tr s t b l E x p a n d i r=N o t h i n g S e tm i B D=N o t h i n g f F i n d E d i t T b l e x p a n d i r _ S a l i d a : O nE r r o rG o T o0 E x i tF u n c t i o n f F i n d E d i t T b l e x p a n d i r _ E r r o r : M s g B o x" E r r o r"&E r r . N u m b e r&"( "&E r r . D e s c r i p t i o n&" )i np r o c e d u r ef F i n d E d i t T b l e x p a n d i r" G o T of F i n d E d i t T b l e x p a n d i r _ S a l i d a : E n dF u n c t i o n ' 'P r o c e d u r e:f A d d T b l e x p a n d i r 'D a t e T i m e :1 1 / 0 2 / 1 32 1 : 1 1 'A u t h o r :C h e a 'P u r p o s e :A b r i ru nr e c o r d s e td eD A O,a a d i ru nn u e v or e g i s t r oya s i g n a rv a l o r ' :al o sc a m p o sd ee s er e g i s t r oc o nl o sv a l o r e sq u es ep a s e nc o m op a r m e t r o s . ' P u b l i cF u n c t i o nf A d d T b l e x p a n d i r ( l i d P a d r eA sL o n g ,s N o m b r e T a b l a P a d r eA sS t r i n g ,b E x p a n d i rA sB o o l e a n )A sL o n g D i mm i B DA sD A O . D a t a b a s e D i mr s t b l E x p a n d i rA sD A O . R e c o r d s e t O nE r r o rG o T of A d d T b l e x p a n d i r _ E r r o r S e tm i B D=C u r r e n t D b ( ) S e tr s t b l E x p a n d i r=m i B D . O p e n R e c o r d s e t ( " t b l E x p a n d i r " ,d b O p e n D y n a s e t ) W i t hr s t b l E x p a n d i r . A d d N e w ! i d P a d r e=l i d P a d r e ! N o m b r e T a b l a P a d r e=s N o m b r e T a b l a P a d r e ! E x p a n d i r=b E x p a n d i r . U p d a t e . B o o k m a r k=. L a s t M o d i f i e d f A d d T b l e x p a n d i r=! I d . C l o s e E n dW i t h S e tr s t b l E x p a n d i r=N o t h i n g S e tm i B D=N o t h i n g f A d d T b l e x p a n d i r _ S a l i d a : O nE r r o rG o T o0

geeks.ms/blogs/access/default.aspx

5/52

22/06/13
E x i tF u n c t i o n f A d d T b l e x p a n d i r _ E r r o r :

Access

M s g B o x" E r r o r"&E r r . N u m b e r&"( "&E r r . D e s c r i p t i o n&" )i np r o c e d u r ef A d d T b l e x p a n d i r" G o T of A d d T b l e x p a n d i r _ S a l i d a : E n dF u n c t i o n

Hay algo mas de cdigo, por ejemplo, para llamar al evento ExpandirTitulo_Click, cuando pulsamos sobre el botn que cubre el campo, o para detectar pulsaciones de teclas y pasarlas al evento Click correspondiente. No lo ponemos para que quede mas claro el funcionamiento bsico.

Conclusin
Los informes, usados generalmente como subinformes, son una alternativa al Control Treeview, sencilla, completamente funcional y con mas posibilidades. Estamos utilizando elementos nativos de Access y algo tan sumamente familiar como son los informes. No vamos a tener que instalar o registrar nada ajeno a Acces, ni vamos a tener nunca problemas por cambio de versiones o caractersticas obsoletas. Se necesita menos cdigo que con un TreeView Control y el diseo grfico de los informe facilita muchsimo la tarea. Se pueden aadir todos los campos que se quiera, del tipo que se quiera y en la posicin que se quiera. No tenemos por qu limitarnos al clsico TreeView. Seguramente es mas lento que un TreeView y produce un ligero parpadeo cada vez que hacemos Requery (contraemos o expandimos) Este parpadeo es mas notorio cuanto mas cosas le pidamos al informe, por ejemplo, formatos condicionales, totales y en general todo lo que signifique clculos en el informe, pues los campos afectados tardan una pizca mas el mostrarse. Pero algn precio habra que pagar.

Publicado por Chea con no comments Archivado en: Informes,Access 2010,TreeView 16/2/2013 23:48 Apuntes para una seguridad a nivel de usuario en Access 2010 II. Macros de datos Despus de casi dos aos tomando impulso, por fin me animo a continuar con la seguridad a nivel de usuario usando las macros de datos. El que consiga acabar este artculo me disculpar por el retraso, pues se dar cuenta de que haca falta tener nimo para ponerse a hablar de las macros de datos: Apenas nadie utiliza macros, el editor y muchas caractersticas son completamente nuevos y las macros de datos son una novedad absoluta en Access 2010, a lo que se aade que apenas existen ayuda o facilidades al respecto. Tendra que explicar el funcionamiento de las macros, los tipos, sus posibilidades, las macros de datos y, cuando empezara por la forma de usarlas para asegurar una tabla a nivel de usuario, ya habra escrito todo un tratado, seguramente muy aburrido. As que voy directamente al grano, a empezar dando unas ideas de cmo crear macros que eviten que los usuarios no autorizados expresamente manipulen los datos de las tablas y, a medida que las voy explicando, mencionar pormenores y detalles de las macros y de su editor. Espero que se entienda algo. En el artculo anterior veamos que, para asegurar una base de datos Access, es necesario hacer inaccesible el back-end y dbamos unas pistas acerca de cmo protegerlo. Si un usuario sin permiso expreso puede acceder directamente al contenido de las tablas, o, peor an, a su diseo, todo lo hablado aqu no sirve para nada. Una vez conseguido esto, podemos abordar la utilizacin de macros de datos para que solo los usuarios autorizados puedan aadir, editar o borrar datos solo en las tablas para las que se les haya concedido permiso. Tenga en cuenta que solo son unos apuntes y que es su propia responsabilidad procurar que no queden agujeros en la seguridad. Grosso modo, lo que vamos a hacer con las macros es verificar si el usuario tiene permisos para la operacin que est pretendiendo hacer y, si no los tiene, abortarla. Un paso mas adelante, aprovechando de que conocemos el usuario, vamos a guardar en cada registro qu usuario lo crea, lo que aparte de un rudimentario seguimiento de cambios, nos permite dar permisos para que slo el autor de un registro pueda modificarlo.

Las macros de datos


Las macros de datos son nuevas en Access 2.010 y el editor de macros, de datos o no, tambin es nuevo, por lo que no es de extraar que haya muy poco publicado al respecto. Las macros de datos estn disponibles en la Vista Diseo de la tabla, en la pestaa Diseo de la cinta de opciones, en el grupo de Eventos de campo, registro y tabla

Es decir, en Access 2010 las tablas tienen eventos y podemos escribir macros en respuesta a estos eventos. Los evento son Despus de insertar, Despus de actualizar, Despus de eliminar, Validar eliminacin y Antes del Cambio. Desde el punto de vista de la seguridad por usuarios, los tres primeros son apropiados para registrar al usuario que produce el evento, y los dos ltimos para verificar si el usuario tiene los permisos necesarios y, en caso contrario, abortar la operacin. Vamos a empezar por algo muy, muy bsico, impedir que se pueda borrar un registro accidentalmente, pero antes debemos abrir el editor de macros.

geeks.ms/blogs/access/default.aspx

6/52

22/06/13

Access

El editor de macros
Da la sensacin de que el editor de macros en Access 2010 est a medio acabar, pues le faltan cosas tan elementales como un men contextual para copiar y pegar, que, sin embargo, ya existe en 2013, y la ayuda es mnima. No obstante, lo esencial funciona correctamente y sirve a la perfeccin para nuestro propsito. Pinchando en uno de los eventos del desplegable de la cinta de opciones que veamos antes, se abre el editor de macros. Las acciones disponibles varan segn el tipo de macro y el tipo de eventos. Es decir, las macros de datos tienen muchas menos acciones disponibles y los eventos Validar eliminacin y Antes del cambio, menos an. Y, sin embargo, con estas macros se pueden conseguir cosas antes impensables.

Hemos abierto el editor de macros para el evento Validar eliminacin. A la derecha se muestran todas las acciones disponibles, bien pocas, y a la izquierda una ventana de edicin, ms grande con un smbolo mas y un cuadro desplegable en el que podemos elegir la accin que queremos anotar. Si no se mostrara el catlogo de acciones, podemos hacerlo visible pulsado en el botn Catlogo de acciones de la cinta de opciones. Las acciones se eligen en el cuadro desplegable o se arrastran desde el Catlogo de acciones que tenemos a la derecha. No es un editor donde podamos escribir cdigo, solo elegir entre las opciones que tenemos y tan solo escribiremos algunas expresiones cuando sean parmetros de la accin que hemos elegido. Nuestra primera macro Vamos a crear nuestra primera macro. En el desplegable elegimos Provocar error.

Escribimos el valor de los parmetros que nos pide, el Nmero de error, que es el que queramos, y la Descripcin del error, que ser el mensaje que se muestre al producirse el error. Guardamos y ya tenemos nuestra primera macro de datos

geeks.ms/blogs/access/default.aspx

7/52

22/06/13

Access

Abra la tabla e intente borrar un registro. Imposible, nos sale el mensaje que hemos puesto en la descripcin del error: Prohibido borrar! y ni en un formulario, ni por cdigo, ni por consulta de eliminacin, ni directamente en la Vista Hoja de datos de la tabla podremos borrar ningn registro.

Bueno, nos hemos pasado, hemos de dar alguna posibilidad de borrar un registro. Por ejemplo, podemos aadir a la tabla un campo S/No que se llame Borrar, y, si es verdadero, s se puede borrar el registro. Ahora, lo que tenemos que hacer con la macro es comprobar el valor del Campo Borrar y, si no es verdadero, provocar el error. Vamos a la Vista Diseo de la tabla y abrimos la macro del evento Validar eliminacin. Arrastramos el grupo Si al editor e introducimos las expresiones, para lo cual contamos con la ayuda del estupendo generador de expresiones

geeks.ms/blogs/access/default.aspx

8/52

22/06/13

Access

En la condicin escribimos [Borrar] <> True Entonces, lo que tenemos que hacer es provocar el error, como hemos hecho antes. Pero el cdigo para provocar el error se encuentra despus de Finalizar si, es decir fuera del bloque If..,Endif. Vamos a arreglarlo.

Observe que el bloque donde estamos introduciendo las expresiones est marcado, delimitado por un cuadrado y con fondo mas oscuro. Si pinchamos con el ratn sobre el bloque de ProvocarError, es ste el que queda marcado y, si movemos el ratn mantenindolo pulsado, el bloque se mueve.

Pues bien, arrastramos el bloque de ProvocarError dentro del bloque SiFinalizar si y voil, ya tenemos nuestra macro:

Guardamos la macro, cerramos y comprobamos si podemos borrar. Podremos hacerlo si, previamente, para ese registro hemos marcado el campo Borrar como verdadero. Es sencillo y, tal como est, vale para cualquier tabla, por lo que vamos a copiarla para pegar en otras tablas y mandarnos el cdigo por correo al trabajo, para hacerlo tambin all. Editamos de nuevo la macro.

geeks.ms/blogs/access/default.aspx

9/52

22/06/13

Access

Como no tenemos marcado ningn bloque, el cdigo se queda mas limpio, mas claro. Podemos observar que nos ha cambiado True por Verdadero, que a las macros les gusta el castellano, incluso a veces no entienden el ingls. Arrastramos el ratn para seleccionar el texto, pero no se selecciona nada, en cambio, si pinchamos, se seleccionan los bloques que hemos visto antes. Si tenemos cuidado y/o pulsamos tambin Maysculas o Control al tiempo que el ratn, podemos seleccionar todos los bloques en un bloque nico. Buscamos un botn para copiar, pero no existe, pulsamos el botn derecho del ratn y no aparece ningn men (bueno, si tienes instalado tambin Access 2013, s aparece) Cmo copiamos? Pues como hacamos antes de los ratones, con Control+C. Probamos, abrimos otra macro y pegamos. Se pega correctamente y se replica el texto la macro que habamos copiado. Llegados a este punto de lectura, usted ya tiene ganas de probar el editor de macros, pero quiere darse prisa y empezar copiando el cdigo desde este blog Desde dnde, si todo son imgenes? Est bien, ah va el cdigo de la macro:
< ? x m lv e r s i o n = " 1 . 0 "e n c o d i n g = " U T F 1 6 "s t a n d a l o n e = " n o " ? > < D a t a M a c r o s x m l n s = " h t t p : / / s c h e m a s . m i c r o s o f t . c o m / o f f i c e / a c c e s s s e r v i c e s / 2 0 0 9 / 1 1 / a p p l i c a t i o n " > < D a t a M a c r o E v e n t = " B e f o r e D e l e t e " > < S t a t e m e n t s > < C o n d i t i o n a l B l o c k > < I f > < C o n d i t i o n > [ B o r r a r ] & l t ; & g t ; T r u e < / C o n d i t i o n > < S t a t e m e n t s > < A c t i o n N a m e = " R a i s e E r r o r " > < A r g u m e n t N a m e = " N u m b e r " > 1 0 0 0 < / A r g u m e n t > < A r g u m e n t N a m e = " D e s c r i p t i o n " > P r o h i b i d o b o r r a r ! < / A r g u m e n t > < / A c t i o n > < / S t a t e m e n t s > < / I f > < / C o n d i t i o n a l B l o c k > < / S t a t e m e n t s > < / D a t a M a c r o > < / D a t a M a c r o s >

Efectivamente, las macros se guardan como cdigo xml y, si usted copia ese texto y lo pega en el editor de macros, el resultado se mostrar como la macro original.

Verificar permisos de un usuario Ya tenemos nuestra primera macro de datos y consigue algo que resulta imposible en cualquier versin anterior de Access, pero de lo que trata este artculo es de la seguridad a nivel de usuarios y lo que queremos es poder discriminar qu usuarios pueden borrar y cules no. Para ello debemos empezar por una tabla con los permisos de los usuarios, buscar si el usuario actual tiene permiso de borrado y, en caso contrario, provocar un error. La cuestin ahora es cmo pasamos a la macro el nombre del usuario para que lo busque en la tabla permisos. Las macros de datos no pueden usar ninguna funcin personalizada, ni siquiera Variables Temporales (Variables Locales, que no son globales, s) ni existe ninguna propiedad o funcin incorporada que nos devuelva el usuario de Access o el de Windows y que sea accesible para la macro de datos. El truco est en que, aunque no se muestren en el generador de expresiones, se pueden hacer bsquedas en consultas y las consultas pueden utilizar una funcin personalizada como origen de un campo calculado y que las macros de datos pueden buscar en una consulta igual que en una tabla, aunque, para despistar, no se muestren en el generador de expresiones ni el Intellisense para las macros. O sea, que podemos tener una consulta que tenga una funcin que devuelva el nombre del usuario y la macro de datos lo lea como si fuera un campo. Las macros de datos y las consultas se ejecutan en el Front-End, aunque se alojen en el Back-End, por lo que la funcin que devuelva al usuario debe encontrarse en el Front-End y, si no queremos ir haciendo pruebas mientras diseamos la macro, conviene que el Back-End tenga una copia de esta funcin. Cmo se gestiona el login de cada usuario y cmo se obtiene la funcin que devuelve el nombre del usuario actual es cosa personal de cada cual y no se va a tratar aqu, aunque adelanto que para eso tambin se podran utilizar macros de datos. En resumen, la macro debe buscar en una consulta los permisos del usuario actual, obtenido en la consulta mediante una funcin, y si carece de permiso para borrar en esta tabla, producir un error. De momento, nos vale con una cosa muy sencillita, basta con que, para cada tabla que queremos proteger, recoja los permisos de cada usuario autorizado.

Se supone que cada cual tendr construido un slido sistema para el control de los usuarios que pueden entrar en nuestra aplicacin, con usuarios, contraseas, registro de logins, etc., y la forma de recuperar el usuario actual. Sin embargo, para las pruebas no vale cualquier cosa que nos devuelva un usuario, por ejemplo, el usuario de Windows; as que nos hacemos esta funcin.

geeks.ms/blogs/access/default.aspx

10/52

22/06/13
Public Function fUsuarioActual() fUsuarioActual = Environ("USERNAME") End Function

Access

Y con la tabla de permisos y la funcin que devuelve el usuario actual, nos podemos montar la consulta que nos devuelva los permisos del usuario actual: SELECT tblPermisos.Usuario, tblPermisos.Tabla, tblPermisos.Insertar, tblPermisos.Editar, tblPermisos.Borrar FROM tblPermisos WHERE (((tblPermisos.Usuario)=fUsuarioActual())); Y se ve as:

Macro Validar Eliminacin


Ahora en nuestra macro Validar eliminacin podemos consultar fcilmente si el usuario actual tiene permiso para borrar y, en caso contrario, se lo impedimos. Esto en una macro, se refleja as:

Estudiemos un poco la macro, pues hemos metido alguna cosa nueva y, aunque parezca muy sencilla, tiene su intrngulis. Est claro que hacemos una bsqueda en la consulta qPermisos con la condicin de que el campo Tabla sea Contactos. En vez de comprobar directamente el campo [Borrar], lo hemos pasado a una variable local de nombre PermisoBorrar, que es la que comprobamos despus Porqu? Fjese en tenemos en bloques distintos Buscar un registro en y Si Nz(PermisoBorrar. Ocurre que las macros son muy pueteras y hay que tener mucho cuidado con dnde va y qu va en cada bloque y, dependiendo de esto, la lgica cambia por completo. Fuera del bloque Buscar un registro en qPermisos, el campo [Permisos].[Borrar] no existe y por eso lo pasamos a una VariableLocal, PermisosBorrar, que tiene alcance en cualquier lugar de la macro. Observe que luego la forma de llamar a la variable es como a un campo, con el nombre entre corchetes. Podramos haber metido el bloque de Si Nz(PermisoBorrar. dentro del de Buscar un registro en y as nos ahorrbamos la VariableLocal? Efectivamente, pero ya hemos comentado que al meter un bloque en otro cambia la lgica. En un bloque Buscar un registro en las acciones que vayan dentro de l solo se ejecutan si se ha encontrado el registro buscado, de manera que, si no encuentra los permisos del UsuariActual, no se ejecutara el cdigo que provoca el error y el registro se borrara sin ningn problema. Puede tener su lgica que los usuarios para los que no se han establecido permisos para una tabla puedan borrar en sta, pero resulta mucho mas seguro al revs, que solo los usuarios a los que expresamente se ha dado permiso puedan borrar en la tabla. Tal como est la macro, si no existe el usuario para la tabla Contactos, no se ejecuta lo que hay dentro del bloque Buscar un registro en y, por tanto, no se establece la VariableLocal, de manera que en el siguiente bloque no la encuentra y Access provoca un error y muestra un msgbox con No se encontr el identificador [PermisoBorrar]., de forma que no

geeks.ms/blogs/access/default.aspx

11/52

22/06/13

Access

se puede borrar un registro. Es decir, si no existe el usuario, se produce un error de Access en la macro y no se puede borrar. Ya tenemos completa la macro Validar eliminacin y abajo pegamos el cdigo xml. Si quiere trasladar esta macro a cualquier tabla, cpielo al portapapeles, abra la tabla en Vista Diseo, edite la macro, posicione el ratn sobre la pestaa y pulse Control+V. Solo le falta cambiar en la Condicin Where el nombre de la tabla.

< ? x m lv e r s i o n = " 1 . 0 "e n c o d i n g = " U T F 1 6 " s t a n d a l o n e = " n o " ? > < D a t a M a c r o sx m l n s = " h t t p : / / s c h e m a s . m i c r o s o f t . c o m / o f f i c e / a c c e s s s e r v i c e s / 2 0 0 9 / 1 1 / a p p l i c a t i o n " > < D a t a M a c r o E v e n t = " B e f o r e D e l e t e " > < S t a t e m e n t s > < C o n d i t i o n a l B l o c k > < I f > < C o n d i t i o n > [ B o r r a r ] & l t ; & g t ; T r u e < / C o n d i t i o n > < S t a t e m e n t s > < A c t i o n N a m e = " R a i s e E r r o r " > < A r g u m e n t N a m e = " N u m b e r " > 1 0 0 0 < / A r g u m e n t > < A r g u m e n tN a m e = " D e s c r i p t i o n " > N os e p u e d eb o r r a rs i nh a b e rm a r c a d o p r e v i a m e n t ee lc a m p o [ B o r r a r ] < / A r g u m e n t > < / A c t i o n > < / S t a t e m e n t s > < / I f > < / C o n d i t i o n a l B l o c k > < L o o k U p R e c o r d > < D a t a A l i a s = " P e r m i s o s " > < R e f e r e n c e > q P e r m i s o s < / R e f e r e n c e > < W h e r e C o n d i t i o n > [ T a b l a ] = " C o n t a c t o s " < / W h e r e C o n d i t i o n > < / D a t a > < S t a t e m e n t s > < A c t i o n N a m e = " S e t L o c a l V a r " > < A r g u m e n t N a m e = " N a m e " > P e r m i s o B o r r a r < / A r g u m e n t > < A r g u m e n t

N a m e = " V a l u e " > N z ( [ P e r m i s o s ] . [ B o r r a r ] ) < / A r g u m e n t > < / A c t i o n > < / S t a t e m e n t s > < / L o o k U p R e c o r d > < C o n d i t i o n a l B l o c k > < I f > < C o n d i t i o n > N z ( [ P e r m i s o B o r r a r ] ) & l t ; & g t ; T r u e < / C o n d i t i o n > < N a m e = " R a i s e E r r o r " > < A r g u m e n t N a m e = " N u m b e r " > 2 0 0 0 < / A r g u m e n t > < A r g u m e n tN a m e = " D e s c r i p t i o n " > U s t e d n ot i e n ep e r m i s o sp a r a b o r r a r < / A r g u m e n t > < / A c t i o n > < / S t a t e m e n t s > < / I f > < / C o n d i t i o n a l B l o c k > < / S t a t e m e n t s > < / D a t a M a c r o > < / D a t a M a c r o s >

Macro Antes del cambio


Todo lo que hemos contado para la macro Validar eliminacin es vlido para la macro Antes del cambio, por tanto, copiar y pegar y corregir algunas cosillas nos puede valer para empezar, aunque en la macro Antes del cambio hay que tener en cuanta alguna cosa mas. Copiamos al portapapeles la macro Validar eliminacin, abrimos la macro Antes de cambio, nos posicionamos en la pestaa y pegamos pulsando Control+V. Borramos el bloque de If Borrar <> Verdadero... Dentro del bloque Buscar un registro en, cambiamos la variable local PermisoBorrar por PermisoEditar y la expresin Nz([Permisos].[Borrar]) por Nz([Permisos].[Editar]) y, despus, en el bloque If, [PermisoBorrar] por [PermisEditar] y en el mensaje de error borrar por editar, y el cdigo de error por un nmero distinto. La macro queda as:

Con esto debera valernos. Probamos y funciona. Sin embargo, falta algo Macro Antes de insertar? No. No existe la macro de datos Antes de insertar, pero tenemos que saber de alguna manera si estamos intentando insertar un nuevo registro. Para ello contamos con la propiedad EsInsertar

Propiedad EsInsertar
En la macro Antes del cambio (y tambin en la macro Despus de Actualizar) podemos consultar la propiedad EsInsertar. (La escasa informacin que hay sobre macros de datos de Access en internet est ingls, y en ingls es IsInsert, sin embargo, si tratamos de utilizar IsInsert en nuestro Access en Castellano, no lo reconocer)

geeks.ms/blogs/access/default.aspx

12/52

22/06/13

Access

Entonces, en nuestra macro Antes del cambio debemos comprobar tambin si se trata de insertar y, en ese caso, comprobar en la tabla permisos si hay permiso para insertar y actuamos en consecuencia. No es necesaria una nueva bsqueda. En la misma bsqueda aadimos una variable local mas, PermisoInsertar, y le asignamos el valor del campo insertar.. En un bloque siguiente, comprobamos la propiedad EsInsertar y, si es verdadera, verificamos el valor de PermisoInsertar y, si no, el de PermisoEditar y, si no lo hay, provocamos un error.

Lo probamos y funciona, as que ya podemos pegar el cdigo xml por si alguien mas lo quiere probar. <?xml version="1.0" encoding="UTF-16" standalone="no"?> <DataMacros xmlns="http://schemas.microsoft.com/office/accessservices/2009/11/application"><DataMacro Event="BeforeChange"> <Statements><LookUpRecord><Data Alias="Permisos"><Reference>qPermisos</Reference><WhereCondition>[Tabla]="Contactos" </WhereCondition></Data><Statements><Action Name="SetLocalVar"><Argument Name="Name">PermisoEditar</Argument><Argument Name="Value">Nz([Permisos].[Editar])</Argument></Action><Action Name="SetLocalVar"><Argument Name="Name">PermisoInsertar</Argument><Argument Name="Value">[permisos].[insertar]</Argument></Action></Statements> </LookUpRecord><ConditionalBlock><If><Condition>[IsInsert]</Condition><Statements><ConditionalBlock><If> <Condition>Nz([PermisoInsertar])&lt;&gt;True</Condition><Statements><Action Name="RaiseError"><Argument Name="Number">4000</Argument><Argument Name="Description">Usted no tiene permisos para Insertar</Argument></Action> </Statements></If></ConditionalBlock></Statements></If><Else><Statements><ConditionalBlock><If> <Condition>Nz([PermisoEditar])&lt;&gt;True</Condition><Statements><Action Name="RaiseError"><Argument Name="Number">3000</Argument><Argument Name="Description">Usted no tiene permisos para Editar</Argument></Action> </Statements></If></ConditionalBlock></Statements></Else></ConditionalBlock></Statements></DataMacro></DataMacros> Lo mismo que con la macro Validar eliminacin, podemos pegarlo en cualquier tabla y solo tendramos que cambiar en la Condicin Where el nombre de la tabla. Incluyendo estas dos macros en cualquier tabla, conseguimos que ningn usuario que no est expresamente autorizado pueda insertar, editar o borrar ningn registro. Obviamente, antes hay que asegurarse de que no tenga acceso directamente al back-end, pues podra modificar las macros o la tabla permisos, a la que tambin deberamos dar permisos, y de que contamos con un sistema de identificacin de usuario y verificacin del inicio de sesin suficientemente seguros, pero eso corresponde al lector y va mas all de lo que se puede tratar en este artculo. Identificar al usuario que crea cada registro Tal como hemos dejado las macros, son suficientes para asegurar una tabla, pero hemos afirmado que bamos a dar un paso mas y lo vamos a hacer. Primero, vamos a identificar en cada registro qu usuario lo ha creado y. luego, vamos a aadir un tercer tipo de permiso, aparte de s o no, que solo el usuario que ha creado el registro pueda editarlo o borrarlo. Lo de identificar al usuario es sencillo. Tenemos que aadirle un campo mas a nuestra tabla, que llamaremos CreadoPor. En la macro aadimos una VariableLocal mas, [Usuario], y, si EsInsertar asignamos a CreadoPor el valor de [Usuario] utilizando la accin de macro EstablecerCampo. As:

geeks.ms/blogs/access/default.aspx

13/52

22/06/13

Access

Pero surge una pega: cualquiera podra modificar el valor del campo CreadoPor y, por tanto editar o borrar el registro. Tenemos que evitarlo; si no EsInsertar y alguien intenta modificar el campo CreadoPor debemos provocar un error, pero Cmo saber si se intenta modificar un campo concreto?

Funcin Actualizado
En la macro Antes del cambio la funcin Actualizado (Nombre de campo) nos dice si el campo cuyo nombre pasamos en una cadena como argumento se ha cambiado. Entonces, en nuestra macro podemos comprobar, si no EsInsertar, si Actualizado (CreadoPor) es verdadero y, en ese caso provocamos un error para evitarlo. La parte final de la macro (no cabe entera en la pantalla para copiarla) queda as:

geeks.ms/blogs/access/default.aspx

14/52

22/06/13

Access

Objeto Antiguo Provocando un error hemos evitado que se cambie el valor de CreadoPor, pero resulta muy poco amable bloquear la edicin de todo un registro porque el usuario ha intentado modificar un campo que no deba A lo mejor ha sido sin querer! Lo que podemos hacer es, en vez de provocar el error, volver el valor del campo a su estado original, y para eso contamos con el objeto Antiguo. Basta con escribir Antiguo. en una expresin y el Intellisense nos muestra los campos a los que se puede aplicar

Si queremos se mas amables, podemos sustituir la accin de ProvocarError por una de EstablecerCampo en la que el valor original se sustituye por el Antiguo. El final de la macro modificada queda de la siguiente manera.

geeks.ms/blogs/access/default.aspx

15/52

22/06/13

Access

Y el cdigo xml: <?xml version="1.0" encoding="UTF-16" standalone="no"?> <DataMacros xmlns="http://schemas.microsoft.com/office/accessservices/2009/11/application"><DataMacro Event="BeforeChange"> <Statements><LookUpRecord><Data Alias="Permisos"><Reference>qPermisos</Reference><WhereCondition>[Tabla]="Contactos" </WhereCondition></Data><Statements><Action Name="SetLocalVar"><Argument Name="Name">PermisoEditar</Argument><Argument Name="Value">Nz([Permisos].[Editar])</Argument></Action><Action Name="SetLocalVar"><Argument Name="Name">PermisoInsertar</Argument><Argument Name="Value">[permisos].[insertar]</Argument></Action><Action Name="SetLocalVar"><Argument Name="Name">UsuarioActual</Argument><Argument Name="Value">[permisos].[Usuario]</Argument> </Action></Statements></LookUpRecord><ConditionalBlock><If><Condition>[IsInsert]</Condition><Statements><ConditionalBlock><If> <Condition>Nz([PermisoInsertar])&lt;&gt;True</Condition><Statements><Action Name="RaiseError"><Argument Name="Number">4000</Argument><Argument Name="Description">Usted no tiene permisos para Insertar</Argument></Action> </Statements></If></ConditionalBlock><Action Name="SetField"><Argument Name="Field">CreadoPor</Argument><Argument Name="Value">[UsuarioActual]</Argument></Action></Statements></If><Else><Statements><ConditionalBlock><If> <Condition>Nz([PermisoEditar])&lt;&gt;True</Condition><Statements><Action Name="RaiseError"><Argument Name="Number">3000</Argument><Argument Name="Description">Usted no tiene permisos para Editar</Argument></Action> </Statements></If></ConditionalBlock><ConditionalBlock><If><Condition>Updated("Contactos.CreadoPor")</Condition><Statements> <Action Name="SetField"><Argument Name="Field">CreadoPor</Argument><Argument Name="Value">[Old].[CreadoPor]</Argument> </Action></Statements></If></ConditionalBlock></Statements></Else></ConditionalBlock></Statements></DataMacro></DataMacros>

Permitir cambios solo al usuario que ha creado el registro


No tiene mucho sentido identificar al usuario que ha creado el registro y que luego lo pueda editar cualquiera. Una alternativa es identificar tambin al usuario que modifica el registro, para lo necesitaramos un nuevo campo, ModificadoPor, al que le daramos valor de la misma manera que a CreadoPor, solo que cuando no sea EsInsertar (estara bien aadir tambin campos de fecha para la creacin y la modificacin). Otra alternativa, que no es incompatible con la anterior, es crear un sistema de permisos en el que, en los que Borrar y Editar tengan valores equivalentes S, No y Slo los registros creados por m, que es lo que vamos a hacer ahora. Empezamos por modificar la tabla de permisos, cambiando Editar y Borrar de S/No a numrico con los valores 0,1,2 (No,S y Los propios)

geeks.ms/blogs/access/default.aspx

16/52

22/06/13

Access

Ahora, en la macro tenemos que comprobar, si no es EsInsertar, si tiene permisos para editar todo o solo para editar los registros propios y, en ese caso, verificar el creador del registro.

La parte de la macro que comprueba los permisos para modificar queda as:

Y el cdigo xml de la macro definitiva Antes del cmbio es el siguiente:

<?xml version="1.0" encoding="UTF-16" standalone="no"?> <DataMacros xmlns="http://schemas.microsoft.com/office/accessservices/2009/11/application"><DataMacro Event="BeforeChange"> <Statements><LookUpRecord><Data Alias="Permisos"><Reference>qPermisos</Reference><WhereCondition>[Tabla]="Contactos" </WhereCondition></Data><Statements><Action Name="SetLocalVar"><Argument Name="Name">PermisoEditar</Argument><Argument Name="Value">Nz([Permisos].[Editar])</Argument></Action><Action Name="SetLocalVar"><Argument Name="Name">PermisoInsertar</Argument><Argument Name="Value">[permisos].[insertar]</Argument></Action><Action Name="SetLocalVar"><Argument Name="Name">UsuarioActual</Argument><Argument Name="Value">[permisos].[Usuario]</Argument> </Action></Statements></LookUpRecord><ConditionalBlock><If><Condition>[IsInsert]</Condition><Statements><ConditionalBlock><If> <Condition>Nz([PermisoInsertar])&lt;&gt;True</Condition><Statements><Action Name="RaiseError"><Argument Name="Number">4000</Argument><Argument Name="Description">Usted no tiene permisos para Insertar</Argument></Action> </Statements></If></ConditionalBlock><Action Name="SetField"><Argument Name="Field">CreadoPor</Argument><Argument Name="Value">[UsuarioActual]</Argument></Action></Statements></If><Else><Statements><ConditionalBlock><If> <Condition>Nz([PermisoEditar])&lt;&gt;True</Condition><Statements><ConditionalBlock><If><Condition>[PermisoEditar]=0</Condition> <Statements><Action Name="RaiseError"><Argument Name="Number">3000</Argument><Argument Name="Description">Usted no tiene permisos para Editar</Argument></Action></Statements></If></ConditionalBlock><ConditionalBlock><If><Condition> [PermisoEditar]=2</Condition><Statements><ConditionalBlock><If><Condition>[Contactos].[CreadoPor]&lt;&gt;[usuarioActual] </Condition><Statements><Action Name="RaiseError"><Argument Name="Number">6000</Argument><Argument Name="Description">Slo puede modificar registros en la tabla 'Contactos' si es el creador del registro</Argument></Action></Statements> </If></ConditionalBlock></Statements></If></ConditionalBlock></Statements></If></ConditionalBlock><ConditionalBlock><If> <Condition>Updated("Contactos.CreadoPor")</Condition><Statements><Action Name="SetField"><Argument Name="Field">CreadoPor</Argument><Argument Name="Value">[Old].[CreadoPor]</Argument></Action></Statements></If> </ConditionalBlock></Statements></Else></ConditionalBlock></Statements></DataMacro></DataMacros>

Ya solo nos queda hacer los cambios en la macro Validar eliminacin para que pueda permitir borrar los registros propios. Como es similar a lo que hemos visto, me limito a pegar el cdigo xml. <?xml version="1.0" encoding="UTF-16" standalone="no"?> <DataMacros xmlns="http://schemas.microsoft.com/office/accessservices/2009/11/application"><DataMacro Event="BeforeDelete"> <Statements><ConditionalBlock><If><Condition>[Borrar]&lt;&gt;True</Condition><Statements><Action Name="RaiseError"><Argument Name="Number">1000</Argument><Argument Name="Description">No se puede borrar sin haber marcado previamente el campo [Borrar] </Argument></Action></Statements></If></ConditionalBlock><LookUpRecord><Data Alias="Permisos"> <Reference>qPermisos</Reference><WhereCondition>[Tabla]="Contactos"</WhereCondition></Data><Statements><Action Name="SetLocalVar"><Argument Name="Name">PermisoBorrar</Argument><Argument Name="Value">Nz([Permisos].[Borrar]) </Argument></Action><Action Name="SetLocalVar"><Argument Name="Name">UsuarioActual</Argument><Argument Name="Value">Nz([Permisos].[Usuario])</Argument></Action></Statements></LookUpRecord><ConditionalBlock><If> <Condition>Nz([PermisoBorrar])=False</Condition><Statements><Action Name="RaiseError"><Argument Name="Number">2000</Argument><Argument Name="Description">Usted no tiene permisos para borrar</Argument></Action>

geeks.ms/blogs/access/default.aspx

17/52

22/06/13

Access

</Statements></If></ConditionalBlock><ConditionalBlock><If><Condition>[PermisoBorrar]=2</Condition><Statements> <ConditionalBlock><If><Condition>[Contactos].[CreadoPor]&lt;&gt;[UsuarioActual]</Condition><Statements><Action Name="RaiseError"> <Argument Name="Number">5000</Argument><Argument Name="Description">Slo puede borrar aquellos registros creados por vd. </Argument></Action></Statements></If></ConditionalBlock></Statements></If></ConditionalBlock></Statements></DataMacro> </DataMacros>

Conclusin
Las macros en Access 2010 no seran difciles si las utilizramos con frecuencia, pero eso nunca va a ser ocurrir pues, para casi todo, es mas sencillo y mas cmodo utilizar VBA con el que, adems, podemos llegar mucho mas lejos. Sin embargo, las macros de datos nos permiten hacer cosas impresionantes, impensables en versiones anteriores de Access e imposibles de hacer con cdigo VBA, por lo tanto, merece la pena pagar el precio de trabajar, aunque sea torpemente, con estas macros pesadas y pueteras e ir aprendiendo algo. A las macros de datos les queda recorrido aparte de lo tratado aqu. No hemos vistos nada de las otras macros de datos, las de despus de, ni de las macros de datos con nombre. Desde el punto de vista de la seguridad a nivel de usuario, nos permitiran, por ejemplo, hacer un seguimiento de cambios, con registro del usuario que los realiza y del valor anterior. Algn da, espero no tardar tanto como en esta ocasin, escribir sobre ello. Publicado por Chea con no comments Archivado en: Access 2010,Macros de datos,Seguridad 30/5/2011 17:28 Apuntes para una seguridad a nivel de usuario en Access 2010. Proteger el back-end Las versiones de Access anteriores a la 2007 incluan un sistema de seguridad a nivel de usuario basado en grupos de trabajo bastante completo salvo por el hecho de que, al menos en los ltimos aos, no serva absolutamente para nada. Resultaba del todo intil identificar usuario y contrasea y asignar permisos en consecuencia si, con una sencilla bsqueda en intern, encontrbamos varias aplicaciones gratuitas con las que piratear las contraseas. En consecuencia, en Access 2007 se abandona esta seguridad tan insegura. A cambio, no se ha implementado ningn sistema de seguridad a nivel de usuario, aunque se afirma que la seguridad ha mejorado notablemente, pues ahora las bases de datos se pueden proteger por contrasea al tiempo que se cifran por un algoritmo muy seguro. A partir de ese cifrado con contrasea, cada uno debe implementar su propio sistema de seguridad por usuarios. Tambin podramos guardar los datos en SQL-Server o en Sharepoint, utilizar la seguridad de stos y olvidarnos de crear la nuestra propia, pero esto a menudo no es asequible. Con archivos accdb, que es de lo que vamos a tratar, una posibilidad interesante es crear un sistema basado en los eventos de datos de Access 2010, de esa manera la lgica de la seguridad se traslada al back-end y se centra en las tablas en vez de hacerlo en la aplicacin que las maneja. Pero, para que el sistema sea seguro, tenemos que conseguir que el back-end sea completamente inaccesible para quien no cuente con los permisos necesarios y que ello no le impida ser accesible desde el fornt-end. La solucin para esto ya est estudiada y vale lo mismo para Access 2007 que para Access 2010; ser de lo que tratemos en este artculo y dejaremos para otro posterior cmo usar las macros de eventos de datos de Access 2010 para asegurar nuestros datos y, en un tercero, veremos cn utilizar las macros de datos para hacer un archivo de seguimiento, un log, de los cambios en los datos del back-end. Proteger el back-end en Access 2007/2010 A partir de Access 2007, si protegemos nuestros datos con una contrasea, quedan a buen recaudo, puesto que la contrasea es mucho ms segura que en versiones anteriores y, adems, los datos se cifran. El problema est en cmo hacer que nuestra aplicacin acceda a esos datos sin que la contrasea quede expuesta. Podemos evitar tener tablas vinculadas y abrir los recordsets de todos los objetos mediante cdigo, pero eso resulta pesado y se pierde la sencillez, que es la principal ventaja de Access. Al vincular tablas de una BD protegida, Access pide la contrasea y la guarda en la propiedad Connect del objeto TableDef correspondiente a esa tabla, de manera que basta con leer la propiedad Connect de la tabla correspondiente para conocer la contrasea Es lo que se plantea en este hilo en UtterAccess http://www.utteraccess.com/forum/Access-2007-security-t1242310.html&p=1243573#entry1243573 y ah mismo proponen una solucin que, aunque luego se complica, es bastante sencilla y es de la que partimos: Las tablas se vinculan sin contrasea, lo cual al intentar abrirlas producira un error, pero al inicio de la aplicacin creamos, mediante cdigo en el que indicamos la contrasea, un recordset que se mantiene abierto toda la aplicacin y, al quedar abierta la conexin con la BD protegida, es innecesario indicarle de nuevo la contrasea, por lo que podemos abrir las tablas vinculadas. Ocurre algo parecido cuando utilizamos conexiones ODBC, que la contrasea se guarda y queda accesible, y la solucin es la misma, no guardar la conexin con contrasea, abrir una conexin mediante cdigo y mantenerla abierta durante toda la aplicacin. En http://blogs.office.com/b/microsoftaccess/archive/2011/04/08/power-tip-improve-the-security-of-database-connections.aspx, otra vez en guiri, nos cuentan cmo hacerlo. El cdigo puede hacerse inaccesible, por ejemplo, convirtiendo la aplicacin en ACCDE y/o protegiendo a su vez, previamente, el proyecto VBA con otra contrasea. De esta manera, las tablas slo se pueden abrir desde nuestra aplicacin y, desde ella, controlamos quin y cmo puede acceder a los datos. Cualquiera podra importar nuestras tablas vinculadas desde otra BD, pero no sabiendo la contrasea, no le servira de nada. Tambin podra, si es un usuario autorizado, abrir directamente a las tablas de nuestra aplicacin y saltarse as los permisos que damos mediante cdigo, pero eso tambin podemos evitarlo, por ejemplo, comprobando que la aplicacin se ejecuta en modo runtime justo antes de abrir el recordset que proporciana la clave al resto de la aplicacin y, cuando sepamos asegurar los datos con macros de datos, ni siquiera podrn modicar nada sin permiso, aunque accedan a las tablas. En resumen, los pasos para proteger nuestro back-end de una forma muy sencilla seran los siguientes: 1- Vincular las tablas del back-end antes de cifrarlo con contrasea (de esa manera la contrasea no se guardar en la propiedad Connect) 2 - Cifrar con contrasea el back-end

3 - Al inicio de nuestra aplicacin abrir un formulario invisible (o un mdulo de clase) en el que asignaremos la contrasea mediante cdigo, y que mantendr abierta la conexin con el back-end durante toda la aplicacin. Este ltimo punto puede parecer difcil, pero es sencillo hacindolo de la siguiente manera: Vinculamos una tabla con datos irrelevantes. Nos pedir contrasea y se guardar, pero ms tarde la borraremos. Como ya existira esa

geeks.ms/blogs/access/default.aspx

18/52

22/06/13

Access
misma tabla vinculada, se guardar con el mismo nombre y un ordinal, por ejemplo TablaTonta1.

A partir de la tabla recin vinculada, creamos el formulario con sus campos.

Cambiamos la propiedad Origen del registro del formulario para dejarla en blanco.

En el evento Load del formulario abrimos un recordset que tome los datos de la BD protegida y lo asignamos como recordset del formulario.
P r i v a t eS u bF o r m _ L o a d ( ) D i mr sA sD A O . R e c o r d s e t S e tr s=C u r r e n t D b . O p e n R e c o r d s e t ( " S E L E C TT a b l a T o n t a . *F R O MT a b l a T o n t aI N' '[ M SA c c e s s ; P W D = A n c h o a sd eS a n t o a ; D A T A B A S E = C : \ U s e r s \ C h e a \ D o c u m e n t s \ B a c k e n dp r o t e g i d o . a c c d b ] " ,d b O p e n D y n a s e t ) S e tM e . R e c o r d s e t=r s E n dS u b

Probamos que el formulario se abre correctamente y cambiamos la propiead Visible del formulario a No. Hay un truco para obtener fcilmente una cadena SQL correcta que abra un recordset de una tabla en una BD externa protegida por contrasea:

En el editor de VB abrimos la ventana de inmediato, decimos que nos imprima la propiedad Connect de la tabla que tenemos vinculada con contrasea y copiamos el texto de la propiedad connect al portapapeles

Abrimos el asistente para consultas para crear una nueva consulta y, antes de aadir una nueva tabla, copiamos el texto de la propiedad Connect a la propiedad de la consulta Cadena de conexin de origen

geeks.ms/blogs/access/default.aspx

19/52

22/06/13

Access

Aadimos ahora la tabla que queramos. Observe que lo que se muestra ahora son las tablas y consultas de la base protegida (S, he dicho consultas, se puede hacer un Select a una consulta de una BD externa) Seleccionamos los campos que queramos y copiamos el texto SQL resultante.

Con ese texto SQL podemos crear el recordset que asignaremos como origen de nuestro formulario. Borramos la tabla que acabamos de vincular con contrasea: Ya no la necesitas, la nica mencin a la contrasea que existe en nuestra aplicacin est oculta en el cdigo que asigna el recordset al formulario oculto. Ya tenemos la manera de abrir una conexin con el back-end protegido que, permaneciendo abierta durante toda la aplicacin, permita abrir otras tablas de ese back-end sin necesidad de indicar de nuevo la contrasea. Es decir, tenemos la llave para abrir los datos protegidos, slo queda verificar el usuario antes de usar esa llave, por ejemplo, en el mismo formulario oculto, antes de asignar el recordset, podemos comprobar el usuario y sus permisos y, si no son los adecuados, en vez de asignar el recordset del formulario cerramos la aplicacin. La manera de controlar usuario y permisos depende de cada cul y no tiene mayor complicacin, cuanto ms personal sea, ms segura, pero una forma muy sencilla podra ser tener una tabla con usuarios contraseas y permisos en el back-end, con la que abriremos, mediante cdigo, un recordset de la misma manera que hacamos con la tabla tonta, para verificar los permisos, procurando primero haber borrado cualquier vnculo a la tabla. Con estos sencillos pasos conseguimos que no se pueda acceder a nuestros datos directamente, sino solo a travs de nuestra aplicacin, de manera que podemos controlar quin y cmo lo hace. Es bastante seguro para lo fcil que resulta, pero en el propio hilo en UtterAccess que citbamos ms arriba, advierten de posibles grietas y posibles soluciones. La pega es que estamos protegiendo, o accediendo, a todo el archivo de back- end a la vez, y, si queremos dar permisos ppersonalizados por usuarios y tablas, debemos hacerlo por cdigo, que slo controla la edicin de datos cuanto se hace a travs de un formulario. El problema ms obvio es que desde una instalacin completa de Access, un usuario autorizado para abrir la aplicacin puede pulsaf F11 para hacer que se muestren las tablas y editar los datos, saltndose todo el sistema de autorizaciones que hayamos implementado mediante cdigo en los formularios. Si estamos usando Access 2007, se me ocurre la solucin de forzar a que la aplicacin se ejecute en modo runtime, que no muestra las tabla; simplemente bastara con verificar en el formulario de apertura si SysCmd(acSysCmdRuntime) es verdadero y, en caso contrario, cerrar la aplicacin. Otra opcin sera tener varios archivos de back-end agrupando las tablas por niveles de privilegios. En cambio, si usamos Access 2010, cabe otra posibilidad, utilizar macros de datos en el back-end que comprueben los permisos del usuario antes de insertar, modificar o borrar datos en la tabla y, si carece de ellos, provocar un error que impida la actualizacin. Toda la lgica de la seguridad por usuarios se traslada al back-end, se centraliza y se hace ms sencilla y, por tanto, ms segura. De ello trataremos en un prximos artculo. Lo que aqu se ha expuesto no es ms que unos apuntes que puedan servir de punto de partida para que cada cual desarrolle su propio sistema de seguridad; no obstante, sin complicar demasiado las cosas, podemos tomar algunas medidas adicionales: Verificar que UserControl sea verdadero para evitar automatizacin Comprobar que CodeProject es el mismo que CurrentProject para evitar la carga como librera Proteger con contrasea el proyecto VBA y convertirlo en ACCDE. Sustituir el formulario por un mdulo de clase en el que el recordset sea Friend. Ocultar las tablas utilizando el atributo dbHiddenObject. En un prximo artculo veremos, cmo utilizando un back-end cifrado con contrasea, podemos valernos de las macros de eventos de datos de Access 2010 para impedir que un usuario no autorizado pueda insertar, modificar o borrar datos, incluso aunque tuviera acceso a las tablas vinculadas del front-ed.

geeks.ms/blogs/access/default.aspx

20/52

22/06/13
Publicado por Chea con 2 comment(s) Archivado en: Access 2007,Access 2010,Macros de datos,Seguridad 23/5/2011 22:49 Gestin de turnos de trabajo con Access

Access

En determinadas empresas, o en determinados servicios, se trabajan muchas ms horas a las semana de las que puede hacer un trabajador. Servicios mdicos, polica, bomberos, fundiciones, funerarias, etc. dan servicio 24 horas al da 7 das a la semana y, como no hay ningn trabajador capaz de tanto, deben hacer distintos turnos que cubran todo el servicio. Tambin es necesario hacerlos en empresas, como centros comerciales, que sin abrir 24 horas abren ms horas, o durante ms das, de lo que corresponde a una jornada laboral normal. Los turnos son distintos dependiendo del tipo de trabajo, necesidades de la empresa, etc., por ejemplo, puede resultar que, dado el tipo de trabajo, por la noche se necesito menos personal, que se cierren los domingos o que no se cierre nunca, que se tenga derecho a ms o menos das de descanso, etc. Dependiendo de esas necesidades, cada empresa organiza sus turnos de una manera distinta pero los resultados tienen cosas en comn: Se elabora una secuencia de los distintos turnos o tipos de jornada que debe hacer un trabajador y se organiza a los trabajadores en grupos, de manera que empezando cada uno la secuencia en una fecha distinta, se solapen unos con otros y cubran toda la jornada. Supongamos un caso muy sencillo: Cuatro trabajadores deben cubrir maana tarde y noche y libran un da de cada cuatro. La secuencia sera maana, tarde, noche, libre MTNL y cada trabajador la iniciara con un da de diferencia. Trabajador 1: MTNLMTNLMTNLMTNLMTNL Trabajador 2: TNLMTNLMTNLMTNLMTNLM Trabajador 3: NLMTNLMTNLMTNLMTNLMT Trabajador 4: LMTNLMTNLMTNLMTNLMTN Cada columna representa un da y con este esquema se garantiza que todos los das haya un trabajador de tarde, otro de noche y otro librando. La mayor parte de los esquemas sern ms complejos que ste, pero lo normal es que todos tengan una secuencia de turnos fija comenzando en distinto momento para cada grupo de trabajadores. Tomando esas secuencias y esos grupos como punto de partida, vamos a proponer una serie de soluciones que faciliten la gestin de grupos de trabajo utilizando una aplicacin hecha en Access.

Averiguar el turno para una fecha


Necesitamos saber qu turno de trabajo le corresponde a un trabajador o grupo en determinada fecha. La primera tentacin puede ser recorrer un bucle partiendo desde un turno conocido, sin embargo, hay otro planteamiento que resulta familiar, pues es el del calendario, es decir, de la misma manera que ordenamos las fechas, que son nmeros consecutivos, en 7 columnas, una para cada da de la semana, y luego podemos mediante una funcin saber qu da de la semana es una determinada fecha, podemos ordenarlas en tantas columnas como tenga la secuencia. Enero: M T 1 4 8 12 16 20 24 28 4 9 13 17 21 25 29 N 2 6 10 14 18 22 26 30 L 3 7 11 15 19 23 27 31

Para averiguar la columna que corresponde a un determinado item, hace aos que descubr el Mediterrneo al hacerme esta funcin:

' 'P r o c e d u r e:f C o l u m n a 'D a t e T i m e :1 7 / 1 0 / 1 01 5 : 1 0 'A u t h o r :C h e a 'P u r p o s e :D a d au n ar e l a c i nd en m e r o sc o n s e c u t i v o so r d e n a d o se nc o l u m n a s ,d e v u e l v el a ' c o l u m n aq u el ec o r r e s p o n d eau nd e t e r m i n a d oi t e m ' ' P u b l i cF u n c t i o nf C o l u m n a ( i t e mA sL o n g ,C o l u m n a sA sL o n g )A sL o n g f C o l u m n a=1+( ( i t e m+C o l u m n a s-1 )M o d( C o l u m n a s ) ) E n dF u n c t i o n

La funcin vale para resolver muchos problemas si se pueden plantear a partir de nmeros consecutivos ordenados en columnas, pero es algo genrico que presupone que la primera columna es el nmero 1, lo cual, como en el ejemplo, no siempre es el caso y tenemos que considerar en qu columna se encuentra el nmero 1. Para eso con los turnos de trabajo he creado una funcin especfica.
' 'P r o c e d u r e:f T u r n o F e c h a 'D a t e T i m e :1 7 / 1 0 / 1 01 5 : 1 2 'A u t h o r :C h e a

geeks.ms/blogs/access/default.aspx

21/52

22/06/13

Access

'P u r p o s e :D a d au n ad e t e r m i n a d ac a d e n c i ad et u r n o se x p r e s a d ae nu n ac a d e n a ,s C a d e n a ,e nl aq u e ' l o st u r n o sv i e n e ns e p a r a d o sp o rc o m a s ,o b t i e n ee lt u r n oq u ec o r r e s p o n d eau n ad e t e r m i n a d a ' f e c h a ,F e c h a C a l c u l o .E sn e c e s a r i oc o n o c e ru n af e c h ad er e f e r e n c i a ,P r i m e r D i a T u r n o , ' q u ec o i n c i d ac o ne lp r i m e rd ad el ac a d e n c i a . ' U s a n d ou n af e c h af i j ac o m oP r i m e r D i a t u r n o , p o d e m o sp a s a ru np a r m e t r oo p c i o n a l , ' l D e s p l a z a m i e n t o ,p a r ai n d i c a rc u a n t o sd a sn o sd e s p l a z a m o sd e lP r i m e r D i a t u r n o . ' P o re j e m p l o ,p o d e m o st e n e rd i s t i n t o sg r u p o s ,c a d au n oe m p e z a n d oe nu nd a ' d i s t i n t o ,e lp r i m e r ot e n d r d e s p l a z a m i e n t o0 ,e ls e g u n d oe m p e z a r u nd am st a r d e ,e t c . ' ' P u b l i cF u n c t i o nf T u r n o F e c h a ( F e c h a C a l c u l oA sD a t e ,s C a d e n c i aA sS t r i n g ,P r i m e r D i a T u r n oA sD a t e ,O p t i o n a ll D e s p l a z a m i e n t oA sL o n g )A sS t r i n g D i mvA sV a r i a n t D i ml C o l u m n a sA sL o n g D i ml C o m p e n s a c i o nA sL o n g v=S p l i t ( s C a d e n c i a ," , " ) l C o l u m n a s=1+U B o u n d ( v ) l C o m p e n s a c i o n=f C o l u m n a ( I n t ( P r i m e r D i a T u r n o+l D e s p l a z a m i e n t o ) ,l C o l u m n a s )-1 f T u r n o F e c h a=v ( f C o l u m n a ( I n t ( F e c h a C a l c u l o )-l C o m p e n s a c i o n ,l C o l u m n a s )-1 ) E n dF u n c t i o n

A la funcin le pasamos FechaCalculo, que es la fecha para la que queremos obtener el turno, sCadencia, que es una cadena en la que indicamos la secuencia del turno, con los items separados por comas, por ejemplo M,T,N,L o Maana,Tarde,Noche,Libre. Tambin le pasamos PrimerDiaTurno que es una fecha de la que sepamos con certeza que se corresponde con el primer da de la secuencia o, de manera opcional, lDesplazamiento, que podemos utilizar para indicar cuantos das se desplaza de una fecha fija, por ejemplo 0, el primer da del turno, calculndolo por tanteo. Por ejemplo, el da en que, tras una ardua negociacin de empresa y trabajadores, se elaboraron las planillas, se comprob que el trabajador 2 deba iniciar su secuencia el 4 de enero del 2007 y se anot esta fecha para posteriores clculos, segn esto, para clcular cmo le toca la Nochebuena del 2010, el clculo en la ventana de inmediato sera:

? fTurnoFecha (#2010/12/24#,"Maana,Tarde,Noche,Libre",#2007/01/04#) Noche Aparte de para hacerle la pueta al trabajador 2, la funcin se puede utilizar en una consulta para obtener una relacin de todos los turnos de todos los trabajadores para todos los das de un periodo determinado.

Elaborar un calendario con turnos


Tomemos una tabla de empleados, con indicacin de a qu grupo pertenecen EmpleadosTurnos

Id Empleado Grupo 1 Pedro 1 2 Andrs 1 3 Jaime 1 4 Juan 2 5 Felipe 2 6 Bartolom 2 7 Toms 8 Mateo 9 Santiago 10 Judas 11 Simn 13 Matas 3 3 3 4 4 4

Aunque el ltimo ID sea 13, se trata de 12 empleados, pues despidieron a uno por conducta desleal. Estn organizados en 4 grupos cada uno de los cuales se inicia al da siguiente del grupo anterior. Vamos a crear el calendario correspondiente a octubre del 2010 utilizando una consulta. Sabemos que si disponemos de una tabla Numeros poblada de numeros consecutivos empezando por el 1, podemos obtener una secuencia de fechas a base de sumar una FechaInicial menos uno al campo Numero. Este truco y el de no relacionar tablas para que el resultado sea un producto cartesiano lo vamos a utilizar en la siguiente consulta.

geeks.ms/blogs/access/default.aspx

22/52

22/06/13

Access

El texto SQL es el siguiente:

S E L E C TE m p l e a d o s T u r n o s . E m p l e a d o ,[ N u m e r o ] + C D a t e ( " 0 1 1 0 1 0 " ) 1A SF e c h a V i r t u a l ,E m p l e a d o s T u r n o s . G r u p o ,f t u r n o f e c h a ( [ f e c h a v i r t u a l ] , " M a a n a , T a r d e , N o c h e ,L i b r e " , C D a t e ( " 0 4 0 1 0 7 " ) , [ G r u p o ] 1 ) F R O MN u m e r o s ,E m p l e a d o s T u r n o s W H E R E( ( ( [ N u m e r o ] + C D a t e ( " 0 1 1 0 1 0 " ) 1 ) < = C V D a t e ( " 3 1 1 0 1 0 " ) ) ) O R D E RB YE m p l e a d o s T u r n o s . E m p l e a d o ,[ N u m e r o ] + C D a t e ( " 0 1 1 0 1 0 " ) 1 ;

Y el resultado, resumiendo, porque seran 372 filas, mostrara algo parecido a lo siguiente completado hasta mostrar todos los empleados con todas las fechas de octubre del 2010 y el turno de cada fecha

qTurnosVirtuales

Empleado FechaVirtual Grupo Turno Andrs 01/10/10 1 Noche Andrs Andrs Andrs Andrs Andrs Andrs Andrs Andrs Andrs Andrs Andrs Andrs Andrs Andrs Bartolom Bartolom Bartolom Bartolom Bartolom Bartolom Bartolom

02/10/10 03/10/10 04/10/10 05/10/10 06/10/10 07/10/10 08/10/10 09/10/10 10/10/10 27/10/10 28/10/10 29/10/10 30/10/10 31/10/10 01/10/10 02/10/10 03/10/10 04/10/10 05/10/10 06/10/10 07/10/10

1 Libre 1 Maana 1 Tarde 1 Noche 1 Libre 1 Maana 1 Tarde 1 Noche 1 Libre 1 Maana 1 Tarde 1 Noche 1 Libre 1 Maana 2 Tarde 2 Noche 2 Libre 2 Maana 2 Tarde 2 Noche 2 Libre
..

geeks.ms/blogs/access/default.aspx

23/52

22/06/13

Access

La consulta la podemos personalizar para pasarle las fechas inicial y final del periodo como parmetros y tambin podemos tomarla como puento de partida para una consulta de datos anexado o de actualizacin que para cada da del ao y cada empleado deje anotado el turno de trabajo. Aunque no es necesario volcar los datos en una tabla, pues podemos utilizar la consulta con cualquier periodo de fechas, si resulta muy conveniente, pues adems de los distintos turnos pueden darse otras situaciones, como bajas, vacaciones, cambios de turno que hacen necesario trabajar con datos guardados. A menudo se pretende realizar una planilla que refleje los trabajadores que entran en cada turno cada da, utilizando los das como encabezado de columna.

qTurnosVirtuales_Tabla de referencias cruzadas

Empleado Grupo 01/10/10 02/10/10 Andrs 1 Noche Libre Jaime 1 Noche Libre Pedro 1 Noche Libre Bartolom 2 Tarde Noche Felipe 2 Tarde Noche Juan 2 Tarde Noche Mateo 3 Maana Tarde Santiago 3 Maana Tarde Toms 3 Maana Tarde Judas 4 Libre Maana Matas 4 Libre Maana Simn 4 Libre Maana

25/10/10 Noche Noche Noche Tarde Tarde Tarde Maana Maana Maana Libre Libre Libre

26/10/10 27/10/10 28/10/10 29/10/10 30/10/10 31/10/10 Libre Maana Tarde Noche Libre Maana Libre Maana Tarde Noche Libre Maana Libre Maana Tarde Noche Libre Maana Noche Libre Maana Tarde Noche Libre Noche Libre Maana Tarde Noche Libre Noche Libre Maana Tarde Noche Libre Tarde Noche Libre Maana Tarde Noche Tarde Noche Libre Maana Tarde Noche Tarde Noche Libre Maana Tarde Noche Maana Tarde Noche Libre Maana Tarde Maana Tarde Noche Libre Maana Tarde Maana Tarde Noche Libre Maana Tarde

Evidentemente es fcil de hacer con una consulta de referencias cruzadas.

El texto SQL sera:


T R A N S F O R MF i r s t ( q T u r n o s V i r t u a l e s . T u r n o )A SP r i m e r o D e T u r n o S E L E C Tq T u r n o s V i r t u a l e s . E m p l e a d o ,q T u r n o s V i r t u a l e s . G r u p o F R O Mq T u r n o s V i r t u a l e s G R O U PB Yq T u r n o s V i r t u a l e s . E m p l e a d o ,q T u r n o s V i r t u a l e s . G r u p o

geeks.ms/blogs/access/default.aspx

24/52

22/06/13
O R D E RB Yq T u r n o s V i r t u a l e s . G r u p o P I V O Tq T u r n o s V i r t u a l e s . F e c h a V i r t u a l ;

Access

Si nuestra consulta de referencias cruzadas la convertimos en un informe y usamos formato condicional, el resultado es la mar de vistoso (o la mar de hortera, segn gustos). En el ejemplo le hemos quitado columnas para que nos quepa bien en la pgina.

En fin, se trata de una serie de ideas que pueden servir a alguien que debe plantearse la gestin de turnos de trabajo, pero no pretende ser ni la solucin ni la forma cannica de plantearlo. Publicado por Chea con 8 comment(s) Archivado en: Access,Calendario 21/10/2010 20:00 Hola a Office 365, adis a Office Live Small Business Al tiempo que se anunciaba el lanzamiento de la beta de Office 365, el Access Team Blog anunciaba que Office 365 incluir Access Services y, por tanto, Access web Databases y en la comunidad online de Office Live Small Business (OLSB) daban la noticia de que, ante la llegada de Office 365, OLSB desaperecer en el plazo de un ao. Habr un periodo de transicin para migrar de OLSB a Office 365 para pequeas empresas a finales del 2011 o principios del siguiente, con un periodo gratuito de tres meses, pero despus habr que pagar por el servicio. Hay quien dice que a Manolete le mat el toro porque la corrida era de beneficencia y eso mismo ha debido pensar Microsoft. Para quienes migren desde OLSB, el precio parece que no ser muy caro, unos 6$ al mes por cuenta, muy poco para una empresa incluso pequea, pero bastante para sustituir a algo que se prometi como gratis de por vida (claro, de la vida del producto que ahora eliminan ). Para quienes queremos jugar con las posibilidades de las aplicaciones web de Access 2010 o utilizar Sharepoint como back end de nuestras aplicaciones Access de escritorio, el anuncio es realmente prometedor pues el rendimiento Access Services es muy superior al de las listas vinculadas en Sharepoint 2007, por el volumen de datos que es capaz de gestionar sin problemas y por la velocidad notablemente superior y porque, sencillamente, las aplicaciones web de Access 2010 son impensables en Sharepoint 2007. Hasta ahora, lo ms barato con Access Services era AccessHosting a partir de 19$ mes el pack developer, por lo que el precio de Office 365 para pequeas empresas resulta muy competitivo, menos de un tercio, y eso sin contar con que los Access Services son la parte ms pequea del paquete de Office 365, que incluye Office Professional, Exchange Online, Sharepoint Online y Lync Online. Para quienes hemos utilizado OLSB precisamente porque era un recurso gratuito de por vida, no deja de ser una faena. Algunas aplicaciones de escritorio en Access 2007 podan compartir unos pocos datos en la web de forma muy sencilla y sin coste alojndolos en OLSB. Algunos nos hemos entretenido en disear en OLSB pginas web sencillas para otros que no se pueden permitir un coste superior a gratis, el pequeo negocio del amigo que empieza, una actividad del colegio, etc., precisamente porque OLSB ofreca un alojamiento gratuito con una calidad aceptable. Unos y otros, en ambos casos yo, ahora se ven decepcionados, pues no necesitaban nada ms y ahora se lo quitan, ofrecindoles a cambio, de pago, lo que no han pedido. As que mi entusiasmo por lo uno frena mi decepcin por lo otro y viceversa y, de momento, ando ms bien perplejo. Tengo muy claro que contratar Office 365 para la pequea empresa por utilizar los Access Services y para seguir alojando mi pgina, pero para aquellas cosas en las que utilizaba OLSB por ser gratuito, empezar a irme pasando a Google Sites Habr valorado Microsoft que esta ltima decisin ser la lgica para miles de usuarios de OLSB? Publicado por Chea con 2 comment(s) Archivado en: Office Live,Sharepoint,Access,Access 2010,Office 365,Sharepoint 2010 10/1/2010 23:36 Algunas joyas escondidas en Access 2010

Access Services
Estoy impresionado. He aprovechado la oferta de Access Hosting que el otro da anunciaba el Access Team Blog para abrir una cuenta trial de Access Services. He probado a crear y subir una aplicacin web hecha con una plantilla de Access 2010 y, como era de esperar, ha funcionado a la perfeccin.

geeks.ms/blogs/access/default.aspx

25/52

22/06/13

Access

Las aplicaciones web funcionando en Sharepoint 2010 son la novedad estrella de Access 2010, sin embargo, lo que me ha impresionado ha sido algo mucho ms simple: He subido una sencilla aplicacin de escritorio y funciona de maravilla, a una velocidad equiparabla a la de cualquier aplicacin web; naturalmente, no se ejecuta en Sharepoint, sino que lo usa de Back End, pero hace mucho ms, pues no slo aloja y sirve datos, sino que tambin guarda todos los dems objetos de la aplicacin. Navegando por el sitio creado en Sharepoint para nuestra aplicacin, tenemos una opcin para modificar la base de datos:

Pinchas en ella y, en pocos minutos, se ha descargado una copia de la aplicacin perfectamente operativa que trabaja con los datos alojados en el sitio. La siguiente vez que pinches, slo tardar un poco ms de lo que tardaras en abrir la aplicacin en el escritorio. Para conseguir esto, durante el proceso de subida a Access Services se han ido sincronizando no slo tablas y consultas, sino todos los objetos; as, cuando realizamos una modificacin en nuestra BD, en cualquier objeto, no slo en los datos, el cambio se realiza tambin en el sitio Sharepoint, de manera que siempre est disponible desde la web la ltima versin. Una maravilla. Como la opcin para modificar la base de datos es un acceso directo, podemos copiarlo y usarlo directamente o, remitirlo a otros usuarios, en vez de andar navegando por el sitio. Esto me ha reconciliado con la proyeccin a la nube de Access 2010. Las listas vinculadas en Access 2007 son una opcin interesante, pero bastante ms limitada y lenta de lo que se prometa, para colmo, lo que tuviramos hecho con listas vinculadas ya no nos vale ahora para los Access Services, de manera que no estaba muy seguro de que el premio mereciera el trabajo de aprender a manejar las macros, el formulario de navegacin, etc.. Ahora, slo por esta posibilidad de tener los datos en la web de manera fcil u operativa, ya merece la pena subirlos y, ya puestos. Access 2010 viene con grandes novedades de las que, desde el inicio de la Vista Previa Tcnica, el Access Team Blog nos viene poniendo al da. Eventos y macros de datos, campos calculados en tablas, aplicaciones en la web, formularios de navegacin, control WebBrowser vinculado a datos son serias innovaciones que cambiarn la forma de trabajar con Access y que parecen todas orientadas a las aplicaciones web. Haba dejado para cuando estuviera con ms nimo el ir probando todo lo referente a esas novedades estrella, pero, mientras, he ido descubriendo cosas ms terrenales, mejoras sobre cosas que ya se venan usando, que o no se mencionan en los blogs, o lo hacen de pasada, pero que por s solas ya justificaran una nueva versin. A esas pequeas joyas voy a referirme ahora.

Formato condicional
Casi parece que no ha cambiado en nada, a simple vista, los asistentes parecen los mismos, pero uno se pone a meter hasta cuarenta y nueve formatos condicionales y no se queja, mientras que antes vena limitado a tres.

Si, adems, nos fijamos bien en el asistente, vemos que tiene un desplegable, Seleccionar tipo de regla con una opcin, comparar con otros registros.

Seleccionamos entre distintas opciones, y el resultado es una barra proporcional a los distintos valores de nuestro formulario o informe, un estilo a lo que ya exista en Excel

No slo funciona con informes y formularios continuos. Tambin se pueden usar, y funciona correctamente, en formularios estndar

geeks.ms/blogs/access/default.aspx

26/52

22/06/13

Access

Texto enriquecido en subformularios


Aunque parece que lo corregirn en breve, en Access 2007 no era posible editar el texto enriquecido en los subformularios. Ahora s, en cualquier lugar, incluso en subformulario continuos, aunque sean en vista Hoja de Datos.

SubInformes en formularios
Estamos tan acostumbrados a que no se puedan meter SubInformes en formularios que hasta cuesta pensar en la utilidad que pueden tener. Por ejemplo, haciendo un refrito, en muy pocos minutos hemos convertido el informe Listn de telfonos en panel de navegacin del formulario Detalle de clientes de la BD NorthWind.

Se me ocurre que navegar de manera semejante por un Diario o un Libro Mayor correctamente formateados en un subinforme, con sus Totales por asiento, Sumas Contnuas, etc., dentro de un formulario para editar los asientos, puede resultar muy vistoso, incluso muy til, y realmente fcil de hacer. Se trata de una Vista Informe por lo que faltan las opciones de impresin que tiene la Vista Previa, pero, a cambio, podemos disponer de eventos (Clic, doble-clic) filtros, etc.. Nada cuesta poner un botn en el informe o en el Ribbon para que nos muestre una vista previa En otros casos, como corresponde a un SubInforme, est vinculado al Formulario principal por las propiedades LinkChildFields y LinkMasterFields, de manera que, al cambiar de registro el formulario, el subinforme a la vista se filtra segn estos campos. Tambin existe la posibilidad contraria, la de mostrar subformularios en informes. El subformulario no es editable por lo que no le veo ninguna ventaja sobre un subinforme en vista informe, salvo ahorrarse el trabajo de crearlo, pero seguro que, entre las muchsimas barrabasadas que se harn con esta posibilidad, alguien le encontrar un uso brillante.

Plantilla de ajuste de controles


Se trata de que los controles se ajustan a una plantilla o tabla, como en las hojas de estilo en el diseo web, en la que podemos aadir o quitar filas y columnas, cambiar alto y ancho de celdas, dividir stas o combinar varias entre s. Access 2007 ya haba aportado algo a la colocacin de los controles, agrupndolos en formato tabular o apilado, que sigue siendo posible, pero, aunque era una forma muy rpida de poner cierto orden visual, no era una solucin muy lograda, ya que todos los controles apilados en el mismo grupo, tenan el mismo ancho. En Access 2010 cuando agrupamos controles, de forma apilada o tabular, podemos moverlos a un lado, encima o debajo, como si aadieramos filas y columnas a una tabla de word; de la misma manera, podemos combinar o dividir esas celdas y los controles que coloquemos se ajustarn a ellas. Es como si debajo de los controles hubiera una tabla o plantilla invisible. Verla es fcil utilizando otra de las novedades de Access 2010, las lneas de divisin tambin en formularios.

Botones con formas, colores y relieves


Los botones, incluidos los de los TabControls, pueden tener distintas formas colores y texturas. Como muestra, unos pocos:

geeks.ms/blogs/access/default.aspx

27/52

22/06/13

Access

El botn Estilos rpidos muestra una galera rpida, pero tambin podemos combinar Cambiar forma, Relleno de forma, Contorno de forma y Efectos de forma para conseguir un montn de posibilidades.

Las formas y colores de los botones no quitan para que puedan seguir teniendo imgenes y pie de imagen, por lo que podemos conseguir unos botones resultados muy vistosos en los que, adems, se sigue visualizando el efecto de apretar el botn:

Los botones con formas y colores se ven afectados por el Tema que hayamos elegido. Al cambiar de tema, cambia la galera de Estilos rpidos y, si ya lo hemos creado, tambin cambia la apariencia de nuestro botn.

Si queremos cambiar la imagen de un viejo formulario Access 2007, de entrada puede que no tengamos habilitadas estas opciones. Se soluciona fcilmente cambiando la propiedad Usar tema del control. Si nuestra aplicacin es en formato mdb, no existe esta propiedad y, por tanto, tendremos que conformarnos con los botones tradicionales.

Generador de expresiones
Cambia la interface del generador de expresiones.

geeks.ms/blogs/access/default.aspx

28/52

22/06/13

Access

Es ms completa y con grafa que diferencia los objetos, pero lo ms novedoso es que aplica el intellisense en aquellas propiedades en que se puede usar el generador.

Imgenes compartidas
Aunque ya en Access 2007 las imgenes se guardan en el tamao del formato original, no deja de ser un desperdicio de espacio repetir la misma imagen, por ejemplo el logotipo de la empresa, en cada formulario o informe. Aunque haba soluciones, sta sque es sencilla de manejar.

Una vez que para una imagen en la propiedad Tipo de imagen hemos elegido Compartidas, queda guardada y a disposicin de los dems objetos de la aplicacin en la galera que se despliega al pulsar el botn Insertar imagen.

Las imgenes compartidas se guardan como datos adjuntos en la tabla MSysResources, de manera que slo ocupan espacio una sla vez. Contiuar existiendo en nuestra BD, y ocupando ese espacio, mientras no la borremos de aqu. Si queremos cambiar el anagrama de nuestra empresa en todos los formularios e informes, basta con que lo cambiemos aqu.

Ttulo en la barra de navegacin


Un pequeo detalle, casi insignificante, pero que refleja cmo en Access 2010 nos encontramos con mejoras a cada paso. Con la propiedad Ttulo de navegacin podemos indicar qu queremos que ponga en la barra de navegacin en vez de Registro. Sin pasarse, eh, que el espacio reservado para ello no aumente ;-)

Publicado por Chea con 15 comment(s) Archivado en: Access 2010 12/6/2009 18:36 Magia Potagia II: El desenlace
En e l captulo ante rior habam os usado ingre die nte s m gicos de Acce ss 2007 para conse guir cre ar una se rie de cale ndarios sin ape nas usar cdigo. Hoy se trata de lice nciarnos com o apre ndice s de brujo hacie ndo que la m agia trabaje para nosotros re solvie ndo proble m as de la vida re al. Ne ce sitaba cre ar un subinform e que , para cada uno de los e le m e ntos de l inform e principal, m e m ostrara un conjunto de fe chas re pre se ntadas e n tantos cale ndarios m e nsuale s com o fue ran ne ce sarios para m ostrar todo e l pe riodo e ntre la prim e ra y la ltim a. Ms o m e nos, com o e n las im ge ne s.

geeks.ms/blogs/access/default.aspx

29/52

22/06/13

Access

Evide nte m e nte , ya lo he he cho y e l caso re al lle va tie m po funcionando corre ctam e nte . Hay una de m o, la de las im ge ne s, que se pue de de scargar e n A ccess siglo XXI . La m agia e n la vida re al tie ne un proble m a: que no hay quie n e ntie nda cm o funciona. Lo m gico de e stos cale ndarios e s que ape nas usan cdigo, pe ro e l cdigo se pue de le e r, e st e structurado, se autodocum e nta; e s com o un plano de la aplicacin. Sin cdigo e s m uy difcil ve r cm o e st he cho algo, tanto que , para que e l que quie ra pue da adaptar m i e je m plo, he te nido que incluir un pe que o asiste nte . No obstante , voy a inte ntar e x plicar cm o e st construido, aunque m e te m o que se r bastante pe sado. C uando e m pie ce s a aburrirte , salta dire ctam e nte al ltim o punto, al de se nlace . El punto de partida e s una tabla con un cam po de fe cha y un cam po ID num rico, e n e ste caso de usuario, e s de cir, con un conjunto de fe chas, que son las que que re m os m ostrar e n cale ndario, para cada usuario.

El idEm ple ado e s nm e rico y si se m ue stran nom bre s e n la im ge n e s porque uso un cam po de bsque da. En e l e je m plo de l captulo ante rior utilizaba una tabla tipo C ale ndar, con cam pos StartDate y EndDate , y m e diante una consulta, la conve rta e n un re sultado pare cido a ste . Sin e m bargo, aunque no lo de ca, trabajar dire ctam e nte con la consulta afe ctaba m ucho al re ndim ie nto y se ra pre fe rible volcar los re sultados e n una tabla te m poral.

Obtener todas las fechas de cualquier ao


El prim e ro de los ingre die nte s m gicos , e s una tabla Num e ros, con un cam po Num con nm e ro conse cutivos. La m a tie ne poco m s de m il.

A partir de e sta tabla, m e diante una consulta construim os todas las fe chas que se corre sponde n con las de l cale ndario de fondo

S E L E C T[ N u m e r o ] + D a t e S e r i a l ( n z ( T e m p V a r s ! j b A n y o I n i c i a l , Y e a r ( D a t e ( ) ) ) , 1 , 1 ) 1A SF e c h a ,F o r m a t ( [ N u m e r o ] + D a t e S e r i a l ( n z ( T e m p V a r s ! j b A n y o I n i c i a l , Y e a r ( D a t e ( ) ) ) , 1 , 1 ) 1 , " d d d d " )A SD s e m a n a ,( M o n t h F R O MN u m e r o s W H E R E( ( ( Y e a r ( [ N u m e r o ] + D a t e S e r i a l ( n z ( [ T e m p V a r s ] ! [ j b A n y o I n i c i a l ] , Y e a r ( D a t e ( ) ) ) , 1 , 1 ) 1 ) ) = n z ( [ T e m p V a r s ] ! [ j b A n y o I n i c i a l ] , Y e a r ( D a t e ( ) ) ) ) ) ;

Me diante e l proce dim ie nto de sum ar al cam po Num una fe cha inicial m e nos uno y hace r que se a m e nor o igual que una fe cha final, pode m os obte ne r cualquie r rango de fe chas que no supe re e l total de re gistros de nue stra tabla Numeros. Pe ro e n e l inform e pode m os supe rar e ste lm ite usando otro de los ingre die nte s m gicos de Acce ss 2007, Te m pVars. Al utilizar una variable Te m pVars e n e l clculo de la fe cha inicial, pode m os cam biar sta sobre la m archa e n e l inform e de m ane ra que la consulta se vaya re calculando las ve ce s que se a ne ce sario. Ya nos parare m os e n e llo m s ade lante ; de m om e nto, guardam os e sa consulta com o jbFechasVirtuales y los re sultados se ra algo as:

Resaltar los festivos de cada empleado


Sobre e se cale ndario de fondo se trata de re saltar las fe chas de nue stra tabla tblFechasEmpleados usando e l te rce r ingre die nte m gico de A2007, e l formato de texto enriquecido. C om param os tabla y consulta y e n las fe chas coincide nte s aadim os las e tique tas htm l ne ce sarias para m ostrar e l re sultado re saltado, e n nue stro caso e n rojo, tal com o habam os visto e n e l captulo ante rior. Sin e m bargo, ante s vam os a anticiparnos con un proble m a con e l que nos toparam os m s ade lante e n e l caso re al. El obje tivo e s pre se ntar los cale ndarios com o subinform e s, pe ro si construim os

geeks.ms/blogs/access/default.aspx

30/52

22/06/13

Access

y form ate am os com o cale ndarios todo e l conjunto de datos, al vincular por un cam po ID inform e y subinform e y, por tanto, filtrar los datos de ste , de strozam os e l form ato de cale ndario que he m os dado a todo e l conjunto. En re sum e n, que de be m os dar form a de cale ndario a cada subconjunto e n ve z de filtrar e l conjunto de datos total y para e llo la m e jor solucin que se m e ha ocurrido e s volve r a usar TempVars de m ane ra que , cam biando sobre la m archa la variable TempVars!jbID cada ve z que cam bie e l ID de l inform e principal se re calcula la consulta e n la que se basa e l subinform e cale ndario filtrndose por e se ID . As, e n ve z de usar dire ctam e nte la tabla tblFechasEmpleados, usar la consulta que he llam ado jbqFestivosVirtuales y que tie ne e l siguie nte SQ L.

S E L E C Tt b l F e c h a s E m p l e a d o s . i d E m p l e a d o ,t b l F e c h a s E m p l e a d o s . F e c h a F R O Mt b l F e c h a s E m p l e a d o s W H E R E( ( ( t b l F e c h a s E m p l e a d o s . i d E m p l e a d o ) = [ T e m p V a r s ] ! [ j b I D ] ) ) ;
Ahora ya pode m os juntar las dos ltim as consultas para re saltar con form ato de te x to e nrique cido los fe stivos de los e m ple ados.

S E L E C Tj b q F e c h a s V i r t u a l e s . * ,I I f ( N o tI s N u l l ( [ j b q F e s t i v o s F i l t r a d o s ] . F e c h a ) , " < f o n tc o l o r = r e d > "&D a y ( j b q F e c h a s V i r t u a l e s . f e c h a )&"< / f o n t > " , D a y ( j b q F e c h a s V i r t u a l e s . f e c h a ) )A SE x p r 1 F R O Mj b q F e c h a s V i r t u a l e sL E F TJ O I Nj b q F e s t i v o s F i l t r a d o sO Nj b q F e c h a s V i r t u a l e s . F e c h a=j b q F e s t i v o s F i l t r a d o s . F e c h a O R D E RB YI I f ( N o tI s N u l l ( [ j b q F e s t i v o s F i l t r a d o s ] . F e c h a ) , " < f o n tc o l o r = r e d > "&D a y ( j b q F e c h a s V i r t u a l e s . f e c h a )&"< / f o n t > " , D a y ( j b q F e c h a s V i r t u a l e s . f e c h a ) ) ;

Guardam os la consulta com o jbFechasyFestivosVirtuales y e l re sultado e s com o e n la im age n siguie nte (hasta 365 das) donde de staca un cam po que e n ocasione s pone algo com o < f o n t c o l o r = r e d > 1 0 < / f o n t >con e l que m s ade lante conse guire m s que e l nm e ro 10 se m ue stre e n rojo.

Ya te ne m os una se cue ncia con todas las fe chas de l ao para un de te rm inado usuario con los fe stivos form ate ados para que m s ade lante se m ue stre n e n rojo. Para que se pare zca a un cale ndario falta orde narlo e n colum nas por das de la se m ana. Dar a los datos

forma de calendario

Ya habam os visto e n e l captulo ante rior que para orde nar e n colum nas por das de la se m ana una se cue ncia de fe chas pode m os usar una Consulta de Referencias Cruzadas que voy a llam ar jbqCalendarioFormateado y que se r e l orige n de datos de l subinform e cale ndario:

T R A N S F O R MM i n ( [ j b q F e c h a s y F e s t i v o s V i r t u a l e s ] . E x p r 1 )A SM n D e E x p r 1 S E L E C T[ j b q F e c h a s y F e s t i v o s V i r t u a l e s ] . M e s ,[ j b q F e c h a s y F e s t i v o s V i r t u a l e s ] . A n y o ,[ j b q F e c h a s y F e s t i v o s V i r t u a l e s ] . F i l a F R O Mj b q F e c h a s y F e s t i v o s V i r t u a l e s G R O U PB Y[ j b q F e c h a s y F e s t i v o s V i r t u a l e s ] . M e s ,[ j b q F e c h a s y F e s t i v o s V i r t u a l e s ] . A n y o ,[ j b q F e c h a s y F e s t i v o s V i r t u a l e s ] . F i l a P I V O T[ j b q F e c h a s y F e s t i v o s V i r t u a l e s ] . D s e m a n aI n( " l u n e s " , " m a r t e s " , " m i r c o l e s " , " j u e v e s " , " v i e r n e s " , " s b a d o " , " d o m i n g o " ) ;

El re sultado, algo pare cido a e sto:

El subinforme calendario Es pe que ito, para que m e que pan m s cale ndarios e n una hoja, que hay que ahorrar pape l,

El O rige n de Datos e s la consulta jbaCalendarioFormateado y e l truco principal e s que los cam pos Lunes, Martes, Mircoles e stn ocultos (e n la im age n e n am arillo) y sobre e llos se supe rpone n se ndos cam pos calculados dLunes, dMartes, dMircoles que tie ne n por orige n e l cam po que e st de bajo. Al se r cam pos calculados, pue de n te ne r form ato de Texto enriquecido, que no e s posible e n cam pos de te x to, de m ane ra que e l cam po que ante s habam os construido con e tique tas htm l de l e stilo < f o n tc o l o r = r e d > 1 0 < / f o n t > , ahora se m ostr com o 10.

geeks.ms/blogs/access/default.aspx

31/52

22/06/13
Este subinform e no tie ne ni una sola lne a de cdigo. El subinforme Meses-A o

Access

Tam bi n e stn ocultos los cam pos Mes y A nyo, que nos van a se rvir para vincular con e l subinform e Me se sAnyos.

El subinform e ante rior m ue stra un solo cale ndario, pe ro ne ce sitam os que nos m ue stre tantos cale ndarios com o se an ne ce sarios e n e l subinform e . Por e so lo incrustam os e n otro subinform e Me se sAo que tie ne todos los m e se s ne ce sarios para m ostrar las fe chas de cada e m ple ado.

El orige n de l subinform e e s la consulta jbqMesesA nyos y tie ne por obje tivo obte ne r tantos re gistros ide ntificados por m e s y ao com o se an ne ce sarios para m ostrar todas las fe chas de un e m ple ado:

S E L E C T( ( ( [ N u m e r o ] 1 ) \ 1 2 ) )A SF i l a ,1 + ( [ N u m e r o ] 1 )M o d1 2A Sn u m M e s ,M o n t h N a m e ( [ N u m M e s ] )A SN o m b r e M e s ,( ( [ N u m e r o ] 1 ) \ 1 2 ) + Y e a r ( D M i n ( " [ F e c h a ] " , " j b q F e s t i v o s F i l t r a d o s " ) )A SA n y o ,D a t e S e r i a l ( ( ( ( [ N u m e r o ] 1 ) \ 1 2 ) ) + Y e a r ( n z ( D M i n ( " [ F e c h a ] " , " j b F R O MN u m e r o s W H E R E( ( ( D a t e S e r i a l ( ( ( ( [ N u m e r o ] 1 ) \ 1 2 ) ) + Y e a r ( n z ( D M i n ( " [ F e c h a ] " , " j b q F e s t i v o s F i l t r a d o s " ) ) ) , 1 + ( [ N u m e r o ] 1 )M o d( 1 2 ) , 1 ) )B e t w e e nn z ( D M i n ( " [ F e c h a ] " , " j b q F e s t i v o s F i l t r a d o s " ) ) 3 0A n dn z ( D M a x ( " [ F e c h a ] " , " j b q F e s t i v o s F i l t r a d o s " ) )A n d

La consultita se las trae , pe ro, re sum ie ndo, obtie ne los m e se s y ao de l subconjunto de fe chas de un e m ple ado a partir de la tabla Num e ros y usando com o filtro las fe chas m ayor y m e nor de la consulta jbqFestivosFiltrados. Ade m s, obtie ne e l cam po jbID , por e l que se vincula con e l inform e principal, de la Variable Te m poral TempVars!jbID . En la se ccion de talle te ne m os e l subinform e jbSubR ptC ale ndarioForm ate ado y, cada ve z que se form ate a e sa se ccin, cam biam os m e diante cdigo la variable te m poral Te m pVars!jbAnyoInicial que , com o vim os se usaba e n la prim e ra consulta, jbFechasVirtuales, de m ane ra que al cam biarse , e sto s que e s m agia, se se re calcula toda la consulta y se re fre sca e l subinform e jbSubRptCalendarioFormateado. Este e s e l todo cdigo de l subinform e : O p t i o nC o m p a r eD a t a b a s e O p t i o nE x p l i c i t P r i v a t eS u bD e t a l l e _ F o r m a t ( C a n c e lA sI n t e g e r ,F o r m a t C o u n tA sI n t e g e r ) T e m p V a r s ! j b A n y o I n i c i a l=M e . A n y o . V a l u e M e . S u b R p t C a l e n d a r i o . R e q u e r y E n dS u b P r i v a t eS u bR e p o r t _ C l o s e ( ) T e m p V a r s . R e m o v e( " j b A n y o I n i c i a l " ) E n dS u b

P r i v a t eS u bR e p o r t _ O p e n ( C a n c e lA sI n t e g e r ) T e m p V a r s ! j b A n y o I n i c i a l=Y e a r ( D M i n ( " F e c h a " ," j b q F e s t i v o s F i l t r a d o s " ) ) E n dS u b El informe principal En e l inform e principal incrustam os e l subinform e jbSubRptMesesA nyo y ne ce sitam os un cam po ID por e l que vincular con ste .

geeks.ms/blogs/access/default.aspx

32/52

22/06/13

Access

Es ne ce sario que te ngam os una agrupacin por e se cam po ID y que e se cam po se e ncue ntre e n la se ccin e ncabe zado de e se grupo. Por qu ? Por que e s la nica form a que he conse guido que m e funcione e l abracadabrante rizado de l rizo: Los cam pos por los que se vinculan inform e y subinform e son re spe ctivam e nte id y jbid.

En e l evento Format de la seccin EncabezadoDelGrupo0 le doy a la variable te m poral TempVars!jbID e l valor de e se cam po ID y, com o re sulta que e l cam po jbID de l subinform e lo tom a de e sa variable te m poral, e stoy asignando sobre la m archa y m e diante cdigo e n e l inform e principal e l valor de l cam po de l subinform e por e l que ste se vincula con e l inform e principal C on dos c! Para m s m agia potagia, cam biar por cdigo TempVars!jbID , com o form a parte de la prim e ra consulta, jbFechasVirtuales, hace que sta se re fre sque y haga los clculos slo para e l e m ple ado de l ID . C om o tam bi n e st e n la consulta jbqFestivosFiltrados y de l m x im o y m nim o de sta de pe nde la consulta jbqMesesA nyo, no slo se re stringe n los fe stivos a los de l e m ple ado, sino que se re calcula jbqMesesA nyo, que e s pre cisam e nte e l orige n de l subinform e . Todo e l cdigo ne ce sario e s e l siguie nte : O p t i o nC o m p a r eD a t a b a s e O p t i o nE x p l i c i t P r i v a t eS u bE n c a b e z a d o D e l G r u p o 0 _ F o r m a t ( C a n c e lA sI n t e g e r ,F o r m a t C o u n tA sI n t e g e r ) T e m p V a r s ! j b I D=M e . I D . V a l u e M e . s u b R p t M e s e s A n y o . R e q u e r y E n dS u b P r i v a t eS u bR e p o r t _ C l o s e ( ) T e m p V a r s . R e m o v e( " j b I D " ) E n dS u b P r i v a t eS u bR e p o r t _ O p e n ( C a n c e lA sI n t e g e r ) T e m p V a r s ! j b I D=D F i r s t ( " i d " ,M e . R e c o r d S o u r c e ) E n dS u b El desenlace Yo ya adve rt que iba a se r aburrido. R e sum ie ndo, usando TempVars y consultas basadas e n una tabla Numeros, se pue de n hace r cosas inim aginable s de otra m ane ra. Es m agia e m paque tada. No e s ne ce sario e nte nde rla toda ni se guir com plicados rituale s para usarla e n una aplicacin propia pue s, de todos los obje tos y consultas que utiliza slo e s ne ce sario cam biar e l inform e principal y la consulta jbqFestivosFiltrados. En A ccess siglo XXI pue de s de scargarte la aplicacin de e je m plo que , ade m s, tie ne un asiste nte e le m e ntal para m odificar e sa consulta y e l cdigo de l inform e principal. De dnde he sacado yo e stas cosas de m gia? Ni ide a, supongo que andar he chizado, aunque algo de inspiracin se m e habr pe gado de R am n Poch o de Julin Snche z, aficionados tam bi n a jugar con una tabla Num e ros. Por cie rto Dom ingun iba a las sie te de la m aana A contarlo!

Publicado por Chea con no comments Archivado en: Access 2007,Informes,Campos Memo,TempVars,Calendario 17/5/2009 19:36 Access 2010- Hermenutica sobre un volcado de pantalla
Ya tenemos, como un pastel en un escaparate, sin tocar, sin oler, sin probar, slo ver, las primeras imgenes de Access 2010. Son una parte de un pqueo conjunto de volcados de pantalla sobre Office 2010 que podemos ver en Leaked: Office 2010 Technical Preview screenshots. Es poco lo que se muestra, pero lo imagino delicioso.

geeks.ms/blogs/access/default.aspx

33/52

22/06/13

Access

Sobre lo que vemos, unido a algunos comentarios que se han ido desgranando casi desde que sali 2007, podemos hacer un ejercicio de hermenutica para interpretar qu nos puede traer de nuevo Access 2010, que, por si alguno no lo sabe ya, presentar su Technical Preview, slo por invitacin, junto con el resto del paquete de Office, en julio de este ao. Sabemos que VBA seguir existiendo Sabemos que funcionar con Windows XP SP3, Vista y Windows 7 y que tendr versiones de 32 y 64 bits. Sabemos que no formar parte de las Office Web Apps. Desentraemos ahora esos volcados de pantalla en busca de nuevos augurios, fijndonos primero en los que muestran distintos Ribbons: - Cambia el botn de Office. A muchos no les gustaba por ostentoso; a m s. Ahora es ms pequeo, discreto y deja de ser redondo, aparentando una pestaa ms, aunque destacada (y ms fea). - El Tab Home apenas muestra diferencias respecto al actual - En Create tenemos un nuevo grupo, Templates, y, dentro de l, el botn desplegable Aplication Parts. A cambio, ha desaparecido el botn Plantillas de tablas, que es de suponer que estar incluido en el primero. Por los comentarios de Access Team Blog y sus peticiones a los usuarios para que reportaran los formularios ms usados, convenciones de nombre o ejemplos de expresiones, formularios e informes reusables, es de esperar que Access 2010 venga cargado de plantillas de todo tipo, incluido cdigo al estilo del Administrador de fragmentos de cdigo de Visual Studio Algo que pasa desapercibido a primera vista es que el botn de Macro, que tiene el mismo icono de antes, ya no se llama Macro a secas, sino Client Macro Significa este calificativo que va a haber tambin algo como un Server Macro? Despus de observar las imgenes de los Ribbons siguientes, yo no lo descartara. - En External Data, en el grupo Import, nos encontramos con un botn Web Service. Ya lo conocamos; era de lo poco que se haba dejado ver de Office 14, tambin en Ars Technica. Yo apostara por que est en relacin con la Plataform de Servicios Windows Azure, y ms en concreto con los SQL Services, aunque no habra que descartar otros. Quizs slo sea que mi imaginacin se deja llevar por mis deseos. - Y la gran sorpresa para el final. Bajo el supertab Table Tools, en el Tab Modify Fields, aparece un Ribbon desconocido y sorprendente. Unos pocos botones, como los del grupo Formatting, son previsibles y, al parecer no hacen ms que poner en el Ribbon accesos a funcionalidades que ya existan, pero otros son completamente novedosos Un botn Calculate Field En el diseo de tabla! y un grupo Table logic, con los botones Create Table Events, desplegable, y Manage Table Events, nos hablan de un nueva dimensin de Access que, si es lo que parece a muchos nos va a dejar con la boca abierta. Ya no es cuestin de si un Evento de Tabla se parecer a un Trigger, o a un Flujo de Trabajo, ms fcil, o si ser algo distinto y propio de Access, sino, ms bien, cmo co o (crcholis) puede producirse un evento de tabla en un ACCDB si es un simple archivo. Tenemos dos meses hasta la Technical Preview para jugar haciendo conjeturas; por ejemplo, que las tablas con eventos no puedan ser ledas por versiones anteriores del motor de Access (que sera el encargado de disparar los eventos) o, con mucha imaginacin, que dispusiermos de un WSS local. Los campos calculados en las tablas y los eventos de tablas recuerdan mucho a las listas de Sharepoint, y en nombre Sharepoint se repite y se repite cada vez que leemos algo de Office 2010; que si Groove ahora va a ser Sharepoint Workspace, que si las Office Web Apps estarn integradas en Sharepoint Oh! No lo haba visto! Volviendo al primero de los volcados de pantalla de Access, el que est antes de los de los Ribbons y se corresponde con la ventana de apertura de Access, disimuladamente, en el primer apartado, Avalaible Template, junto al icono de Blank Database, tenemos el de Blank Web Database. Qu significa esto es pronto para decir, pero, si es lo que parece, promete ser la novedad ms importante de Access 2010. Seguro que tambin tiene que ver con Sharepoint.

Publicado por Chea con 6 comment(s) Archivado en: Access 2010 2/2/2009 18:38 Filtros en Access 2007
Access 2007 incorpora importantes herramientas para facilitar que el usuario pueda realizar filtros complejos sobre formularios, incluso sobre informes, de una manera manera muy sencilla, tanto que uno se pregunta si merece la pena continuar con los procedimientos que, durante aos, hemos ido aadiendo a nuestras aplicaciones para filtrar. Para muestra vale un botn (el de filtro):

geeks.ms/blogs/access/default.aspx

34/52

22/06/13

Access

Con slo posicionarnos en un campo de un formulario, en este caso de fecha, y pulsar el botn de Filtro que encontramos en la Cinta de Opciones, Access despliega una abrumadora relacin de opciones para filtrar el formulario por el campo en el que nos encontramos. Las opciones que se despliegan varan segn el campo por el que vamos a filtrar sea numrico, de texto o de fecha.

Varias maneras de acceder a las herramientas de filtro


Usando el men contextual
Pulsando con el botn derecho del ratn sobre un control del formulario, se despliega un men contextual que, adems de las opciones de edicin y orden, muestra las de filtro. Son muy parecidas a las que hemos visto antes con el botn de filtro de la cinta de opciones, pero falta el combo multivalor y se aade la opcin de filtro por seleccin, es decir, el valor actual del control como opcin de filtro igual, distinto, mayor o menor.

Dos posibilidades de herramientas de filtro casi iguales, pero distintas. El caso es que el men contextual no est disponible con la runtime de Access y el Ribbon no es accesible en los formularios emergentes :-( Sin embargo, podemos invocar el men de filtro (el del Ribbon) posicionndonos el cualquier control y usando el cdigo:

DoCmd.RunCommand acCmdFilterMenu
Y, si lo queremos que se mueste es el men contextual, podemos usar:

CommandBars("Column Filter").ShowPopup
Usando el Ribbon
En el grupo de la Cinta de Opciones Ordenar y Filtrar, no slo tenemos el botn de filtro que veamos antes. Los botones Seleccin y Avanzadas despliegan una serie de opciones que ya existan en versiones anteriores de Access.

geeks.ms/blogs/access/default.aspx

35/52

22/06/13

Access

Las opciones de Seleccin ya existan en versiones anteriores, salvo la ltima, Entre , tambin disponible en el men contextual y en el botn de filtro, bastante novedosa y til: muestra un cuadro de dilogo con dos cuadros de texto para indicar los lmites de un rango por el que filtrar.

La imagen es para un rango de fechas, pero tambin existe para un rango de nmeros. No existe para texto, aunque para texto hay otras alternativas. Desplegando el botn Avanzadas encontramos Filtro por formulario y Filtro avanzado/Ordenar. Son viejos conocidos de versiones anteriores; el primero presenta el formulario en una vista especial para introducir criterios y el segungo muestra la cuadrcula QBE para editar el text SQL correspondiente al filtro. Son herramientas mas complicadas de usar que las nuevas de 2007, pero siguen siendo necesarias si queremos manejar cierta complejidad. Mediante las herramientas del botn de Filtro del Ribbon o del men contextual, los distintos criterios de filtro se van concatenando con AND sin opciones de usar OR y sin mostrar una vista conjunta de los distintos criterios que se estn aplicando. No es necesario elegir entre una y otras, pues se pueden ir complemantando: el filtro que hayamos creado con el men desplegable podemos editarlo con Filtro por formulario o con Filtro avanzado/Ordenar para hacerlo ms complejo.

Alternar el filtrado
Al filtrar, se resalta en naranja un nuevo botn poniendo Filtrado en la barra de navegacin del formulario :

Pulsando sobre l, se desactiva el filtro y cambia el texto del botn a Sin filtrar. Si volvemos a pulsar, se vuelve a activar el filtro y a cambiar el texto. Es decir, el botn sirve para alternar la propiedad FilterOn del formulario.

Pero an afina ms. Como hemos visto, los criterios de filtro se van acumulando con AND, de manera que un formulario puede estar filtrado por varios criterios; pues bien, ir eliminando selectivamente esos criterios es tan sencillo, como volver a posicionarse sobre el control con el que habamos filtrado y pulsar de nuevo el botn derecho del ratn, se mostrar entonces una opcin en el men desplegable para quitar ese criterio.

Filtros en hojas de datos


Los mens de filtro tambin estn disponibles en las vistas de hojas de datos de tablas y consultas, sin necesidad de que se trata de un subformulario. Adems, estn directamente accesibles ambos mens de filtro, el contextual y el que veamos desde el Ribbon, para el primero usando el botn derecho del ratn y, para el segundo, pulsando sobre el pequeo tringulo con un vrtice hacia abajo que aparece junto al nombre de cada campo.

geeks.ms/blogs/access/default.aspx

36/52

22/06/13

Access

Al aplicar el filtro, junto nombre del campo que hemos usado aparece un minsculo icono de filtro

Y, si pulsamos en l se despliega el men de filtro con, entre otras, la opcin para quitar el filtro por ese campo.

Filtros en informes
Algo sorprendente en Access 2007 es que los informes tambin pueden filtrarse dinmicamente de la misma manera que hacemos en un formulario. Como veamos en un artculo anterior, existen Nuevas vistas de informe en Access 2007 distintas de la Vista Preiliminar.

Si abrimos nuestro infrome como Vista Informe, se presenta de una forma peculiar, sin opciones de impresin o vista previa y sin saltos de pgina, pero con algunas opciones propias de los formularios, como la posibilidad de seleccionar y copiar texto, etiquetas inteligentes o las opciones de filtro, todas las que hemos visto antes para filtrar informe. Una vez filtrado, podemos imprimirlo directamente utilizando Botn de Office | Imprimir o pasar a la Vista Preliminar desde la opcin Vistas del Ribbon.

geeks.ms/blogs/access/default.aspx

37/52

22/06/13

Access

Un poco de cdigo
Men de filtro en formularios emergentes
La cinta de opciones no est disponible si estamos utilizando un formulario emergente, por lo tanto, no podemos usar el men de filtro propio de esa cinta, salvo que lo hagamos por cdigo: P r i v a t eS u bF i l t r o _ C l i c k ( ) D i mc t r lA sC o n t r o l O nE r r o rG o T oF i l t r o _ C l i c k _ E r r o r S e tc t r l=S c r e e n . P r e v i o u s C o n t r o l c t r l . S e t F o c u s D o C m d . R u n C o m m a n da c C m d F i l t e r M e n u O nE r r o rG o T o0 E x i tS u b F i l t r o _ C l i c k _ E r r o r : M s g B o x" E r r o r"&E r r . N u m b e r&"( "&E r r . D e s c r i p t i o n&" )i np r o c e d u r eF i l t r o _ C l i c ko fD o c u m e n t oV B AF o r m _ D e t a l l e sd ee m p l e a d o s " E n dS u b

El mismo botn sirve para filtrar en el formulario principal o en un subformulario. Slo es cuestin de posicionarse previamente en el campo por el que queremos filtrar

geeks.ms/blogs/access/default.aspx

38/52

22/06/13
Aprender de Access

Access

Resulta un ejercicio interesante ver cmo los mens de filtro de Access construyen los criterios de filtro. Para ello, en un formulario para ensayos aadimos un cuadro de texto txtFiltro y el siguiente cdigo: P r i v a t eS u bF o r m _ A p p l y F i l t e r ( C a n c e lA sI n t e g e r ,A p p l y T y p eA sI n t e g e r ) M e . t x t F i l t r o=M e . F i l t e r E n dS u b De esta manera, cada vez que apliquemos un filtro, veremos el criterio que se ha generado.

( ( [ P r o d u c t o s ] . [ C a t e g o r a ] = " B e b i d a s " ) ) A N D( [ P r o d u c t o s ] . [ C o s t oe s t n d a r ] < = 1 3 . 5 )

Observamos que, a medida que vamos filtrando, se van aadiendo cadenas de filtro unidas por AND, lo cual era perfectamente previsible. Claro, que slo cabe unir los distintos criterior con AND y a lo mejor nos interesa unir alguno con OR. Con un par de lneas ns de cdigo podemos hacer que, si editamos el texto que nos muestra el filtro, ste se convierta en el nuevo filtro de nuestro formulario. P r i v a t eS u bt x t F i l t r o _ A f t e r U p d a t e ( ) M e . F i l t e r=M e . t x t F i l t r o M e . F i l t e r O n=T r u e E n dS u b Desplegable Multivalor para filtrar Resulta curioso observar cmo la sintxis va cambiando segn la cantidad y proporcin de elementos que vayamos seleccionando para filtrar en el desplegable multivalor del men de filtro.

Las distintas selecciones provocan distintos criterios de filtro segn se haya seleccionado un slo elemento o unos pocos, o todos menos uno o todos menus unos pocos. Los criterios generados son las siguientes.

( [ E m p l e a d o sa m p l i a d o s ] . [ A p e l l i d o s ] = " A c e v e d o " ) ( [ E m p l e a d o sa m p l i a d o s ] . [ A p e l l i d o s ]I n( " A c e v e d o " , " B o n i f a z " , " J e s sC u e s t a " ) ) ( [ E m p l e a d o sa m p l i a d o s ] . [ A p e l l i d o s ] < > " C h a v e s "O r[ E m p l e a d o sa m p l i a d o s ] . [ A p e l l i d o s ]I SN u l l ) ( [ E m p l e a d o sa m p l i a d o s ] . [ A p e l l i d o s ]N o tI n( " C h a v e s " , " J e s sC u e s t a " )O r[ E m p l e a d o sa m p l i a d o s ] . [ A p e l l i d o s ]I SN u l l ) Filtrando campos multivalor Nada de todo esto nos resulta novedoso, as que vamos a ver cmo se generan los filtros con campos multivalor, especficos de Access 2007.

geeks.ms/blogs/access/default.aspx

39/52

22/06/13

Access

En el men contextual de filtro elegimos el valor actual de nuestro campo multivalor: Contiene Proveedor D; Proveedor F . Filtramos y vemos que el filtro generado es el siguiente: ( [ L o o k u p _ S u p p l i e rI D s ] . [ C o m p a a ] = " P r o v e e d o rD " A N D[ L o o k u p _ S u p p l i e rI D s ] . [ C o m p a a ] = " P r o v e e d o rF " )

LookUP Es decir, que ha concantenado con AND los distintos valores de nuestro campo multivalor, algo previsible. Sin embargo, si nos fijamos, nuestro campo se llama [Supplier IDs] mientras que el nombre que aparece es [Lookup_Suplier IDs], o sea, lo mismo pero con un LookUp_ delante. Eso me suena de versiones anteriores utilizando Filtro por formulario Utilizando la herramienta de filtro Avanzadas | Filtro avanzado/Ordenar vamos a verlo por dentro. Esa herramienta se encuentra en el Ribbon y, como estamos en un formulario emergente, no podemos acceder a ella, de manera que, o bien quitamos la propiedad Emergente al formulario y seleccionamos la opcin correspondiente en el Ribbon

O bien aadimos un botn que llame a la herramienta mediante cdigo: P r i v a t eS u bF i l t r o A v a n z a d o _ C l i c k ( ) D o C m d . R u n C o m m a n da c C m d A d v a n c e d F i l t e r S o r t E n dS u b De cualquiera de las dos maneras el resultado ser que se muestre el diseador grfico de consultas con el filtro actual

geeks.ms/blogs/access/default.aspx

40/52

22/06/13

Access

Observamos que a la tabla origen de nuestro formulario, Productos, se le ha relacionado una tabla o consulta llamada Lookup_Supplier IDs y que coinciden con los campos que se encuentran en el Origen de la Fila del cuadro combinado que usamos para la bsqueda de Id de Proveedores. Recordemos que, para que un campo sea Multivalor, en el diseo de la tabla, en la pestaa Bsqueda debemos usar un cuadro combinado con un origen vlido y Permitir varios valores. Por lo tanto, el filtro con Lookup se usa en los campos multivalor porque son cuadros combinados. La sintxis, si queremos crear nuestro propios criterios con Lookup_ , sera algo as: ([Lookup_NombreControl].[NombreColumnaMostrada]="Criterio filtro") Usando el operador "=" no deja de ser una chorradita, pues para eso podemos buscar directamente por el campo dependiente. Pero si usamos "Like" o cualquier otro operador en su lugar, la cosa cambia, pues el filtro se hace por la columna mostrada que no est en el origen de datos del formulario filtrado. Evidentemente, esto es una gran ventaja a la hora de construir un filtro. Si utilizamos esa sintaxis al montar nuestra propia cadena de filtro, funciona perfectamente, aadindole potencia de una forma muy sencilla. En resumen, que es una herramiento muy maja y que funciona muy bien y, sin embargo, no he encontrado nada en la ayuda ni en ningn otro lado. Todo lo que he encontrado, y con ayuda de Emilio Sancha, es este enlace de Allenbrowne que lo usa, para bsquedas, en una aplicacin de ejemplo: http://www.allenbrowne.com/AppFindAsUType.html. Prometo que profundizar en el asunto y publicar los resultados, aunque todo el mundos sabe ya que, para estas cosas, soy hombre de poca palabra ;-)

ApplyFilter
Entre las novedades en Access 2007 se cita la nueva sintxis de AppliFilter Sintaxis anterior VOID ApplyFilter (OPTIONAL VARIANT FilterName, OPTIONAL VARIANT WhereCondition) Sintaxis nueva VOID ApplyFilter (OPTIONAL VARIANT FilterName, OPTIONAL VARIANT WhereCondition, OPTIONAL VARIANT ControlName) Sencillamente se le ha aadido un parmetro ControlName y, probando, nos encontramos con que slo es vlido el nombre de un control de subformulario o subinforme, por lo que es fcil deducir que sirve para filtrar directamente el subformulario o subinforme desde el principal. Por ejemplo, si queremos filtrar el subformulario Child22, podemos poner en el formulario principal un botn con el siguiente cdigo. P r i v a t eS u bM i b o t n _ C l i c k ( ) D o C m d . A p p l y F i l t e r," T r a n s a c c i n = ' C o m p r a ' " ," c h i l d 2 2 " E n dS u b Tenindolo en mente, esto puede facilitar un poco las cosas en determinadas ocasiones, pero no pasa de ser una insignificancia Para qu se han tomado la molestia? Me imagino que ser para facilitar el uso de macros. Las macros ejecutan comandos y, si slo aadiendo un parmetro, el filtro se puede aplicar a un subformulario, la macro se simplifica notablemente.

Publicado por Chea con 14 comment(s) Archivado en: Access 2007,Filtros 21/1/2009 12:05 Online: Mejora de las aplicaciones Access 22/01/09

Mejora de las aplicaciones Access con SQL Server y Sharepoint


El e ve nto lo vam os a grabar y lo transm itire m os online , os paso los datos de cone x in para que prob is e l acce so:

Evento Online 1era parte sesin maana


Eve nt UR L :

Evento Online 2da parte sesin tarde


Eve nt UR L :

Publicado por Chea con 3 comment(s) Archivado en: Eventos,Access,SQL Server 17/1/2009 21:52 Access Developer Extensions en espaol

geeks.ms/blogs/access/default.aspx

41/52

22/06/13

Access

En el grupo de noticias de Access, Freddy M. Aragn nos ha informada que ya estn disponibles para su descarga las Access Developer Extensions en espaol. Las Developer Extensions aaden una nueva opcin Programador al men de Office que nos permite crear un paquete de instalacin y guardar como plantilla. Si ya tenamos instalada la versin en ingls, sencillmanente sustituya una por otra.

Publicado por Chea con 6 comment(s) 14/1/2009 14:01 El uso de las Cintas de Opciones (Ribbon) y XML (Lenguaje de Marcado Extensible). RibbonAndXML_01
Captulo 1 La pretensin de este artculo (se incluye demo) es aprender a cambiar de Cinta de Opcin (Ribbon) haciendo uso del XML (Lenguaje de Marcado Extensible). Sin nimo de ser exhaustivo la sintaxis es muy similar a la del HTML, es otro lenguaje basado en marcas pero estas son ms estrictas, contiene propiedades que la hacen que tenga un formato de datos til para poder ser ledo por varios programas e incluso sistemas. Las reglas bsicas de la especificacin XML son las siguientes: Slo se permite un nico elemento raz. Deben de existir etiquetas de inicio y fin para cada elemento, <elemento></elemento>. Es sensible a maysculas y minsculas. Los atributos deben estar entrecomillados. El texto comentado tiene la siguiente estructura <!-- --> y ms, pero dejo a San Google para complementar la informacin.

Primeros conceptos del cdigo XML que genera la Cinta de Opciones (Ribbon). < c u s t o m U Ix m l n s = h t t p : / / s c h e m a s . m i c r o s o f t . c o m / o f f i c e / 2 0 0 6 / 0 1 / c u s t o m u i > < r i b b o ns t a r t F r o m S c r a t c h = " t r u e " > < / r i b b o n > < / c u s t o m U I >

La primera etiqueta a utilizar siendo necesaria para las personalizaciones del Ribbon, es tambin el elemento raz. < c u s t o m U Ix m l n s = h t t p : / / s c h e m a s . m i c r o s o f t . c o m / o f f i c e / 2 0 0 6 / 0 1 / c u s t o m u i " > La siguiente etiqueta hace referencia al objeto Cinta de Opciones y que cuenta con el atributo que puede tener dos valores true y false. Si su valor es true se quitarn todas las fichas predetermiadas por Office y la personalizada es la que quedar visible. False para no modificar las existentes dejando a la derecha la nueva. < r i b b o ns t a r t F r o m S c r a t c h = " t r u e " > Importante conocer que este modo tambin oculta los comandos que tiene el nuevo men Office excepto Nuevo, Abrir, Guardar como y Cerrar base de datos, tal como veremos a continuacin en la imagen. As de sencillo, con tan slo una lnea hemos modificado toda la Cinta preparndola para usar nuestras propias fichas y grupos. El modo startFromScratch est diseado para ser compatible con las futuras versiones de Office, es decir, si se agrega una nueva ficha o elemento del men Office, el modo startFromScratch debera ocultarlos automticamente. Por estos motivos es ms conveniente usar startFromScratch que no ir ocultando uno a uno los elementos del men Office y las diferentes fichas y grupos de la Cinta de Opciones. Usando estas cinco lneas ya podemos conseguir un efecto significativo en la ventana de Access y que se presenta en la imagen siguiente.

geeks.ms/blogs/access/default.aspx

42/52

22/06/13

Access

En caso de querer modificar la visibilidad de los comandos que estn incluidos en el Botn de Office hay que usar la etiqueta < o f f i c e M e n u > Para ocultar el comando Nuevo utilizar el identificador de Office "F i l e N e w D a t a b a s e " y cambiar su atributo visible a " f a l s e " < c u s t o m U Ix m l n s = " h t t p : / / s c h e m a s . m i c r o s o f t . c o m / o f f i c e / 2 0 0 6 / 0 1 / c u s t o m u i " > < r i b b o ns t a r t F r o m S c r a t c h = " t r u e " > < o f f i c e M e n u > < b u t t o ni d M s o = "F i l e N e w D a t a b a s e "v i s i b l e = " f a l s e "/ > < / o f f i c e M e n u > < / r i b b o n > < / c u s t o m U I > Analicemos la nueva etiqueta button para entender un poco ms como penetrar en este nuevo mundo del XML y del Ribbon. < b u t t o ni d M s o = " F i l e N e w D a t a b a s e "v i s i b l e = " f a l s e "/ > Los controles de la Cinta deben de contener como mnimo un elemento que los identifique como nicos y puede ser uno de los siguientes de esta lista: idMso: es el identificador de un men que contenga Office, nombre interno. id: Identificador para los controles personalizados y debe de ser nico. idQ: Identificador cualificado cuyo contenido debe de ser una abreviatura del espacio de nombres.

El siguiente elemento de la etiqueta es un atributo y que en este caso que se llama visible. Modificando su valor (entrecomillado) conseguimos ocultarlo ("false") o hacerlo visible ("true"). Para conocer una lista de los nombres internos que ha establecido Microsoft para los comando podemos descargarnos un archivo desde la url siguiente, http://www.microsoft.com/downloads/details.aspx?FamilyID=4329d9e9-4d11-46a5-898d-23e4f331e9ae&displaylang=en. Conseguiremos un montn de libros de Excel organizados por producto, Access, Excel, Outlook, Word, etc. Continuamos con los comandos que todava nos quedan visibles, Abrir, Guardar como y Cerrar base de datos, as como la lista de Documentos recientes. Para ocultar el comando Abrir, "F i l e O p e n D a t a b a s e " y el botn desplegable Guardar como, "F i l e S a v e A s M e n u A c c e s s " podemos usar el siguiente cdigo, < b u t t o ni d M s o = " F i l e O p e n D a t a b a s e "v i s i b l e = " f a l s e "/ > < s p l i t B u t t o ni d M s o = " F i l e S a v e A s M e n u A c c e s s "v i s i b l e = " f a l s e "/ >

Por ltimo de esta serie est Cerrar base de datos, "F i l e C l o s e D a t a b a s e " < b u t t o ni d M s o = " F i l e C l o s e D a t a b a s e "v i s i b l e = " f a l s e "/ > Quedando de este modo si queremos desactivar las cuatro acciones. < o f f i c e M e n u > < b u t t o ni d M s o = " F i l e N e w D a t a b a s e "v i s i b l e = " f a l s e "/ > < b u t t o ni d M s o = " F i l e O p e n D a t a b a s e "v i s i b l e = " f a l s e "/ > < s p l i t B u t t o ni d M s o = " F i l e S a v e A s M e n u A c c e s s "v i s i b l e = " f a l s e "/ > < b u t t o ni d M s o = " F i l e C l o s e D a t a b a s e "v i s i b l e = " f a l s e "/ > < / o f f i c e M e n u > Pero es posible que queramos hacer visible alguno de los comandos para poder imprimir un objeto o mandar por correo electrnico, para ello usaremos las siguientes lneas a continuacion de las anteriores, < b u t t o ni d M s o = " P r i n t D i a l o g A c c e s s "v i s i b l e = " t r u e " / > < b u t t o ni d M s o = " F i l e S e n d A s A t t a c h m e n t "v i s i b l e = " t r u e " / >

geeks.ms/blogs/access/default.aspx

43/52

22/06/13

Access

Doy por finalizado este captulo primero, espero poder presentar otros sucesivos en los que podremos encontrar el modo de deshabilitar el botn de ayuda, minimizar, restaurar, cerrar e incluso los botones de Opciones de Access y Salir. McPegasus, 14/01/2008

Publicado por McPegasus con 6 comment(s) Archivado en: Access 2007,Ribbon,XML 30/12/2008 22:00 Vincular Vistas de Sharepoint desde Access 2007 Si desde Access 2007, en vez de vincular una Lista de Sharepoint, vinculamos una Vista de sta, obtenemos claras ventajas, la ms evidente limitar el trfico de datos por la red a los que realmente queremos, pero tambin otras bastante interesantes, como restringir los datos a los del usuario registrado en el sitio Sharepoint. Sin embargo, los asistente de Access slo facilitan vincular Listas, debiendo recurrir al mtodo TransferSharePointList para poder conseguirlo. La misma ayuda de Access sobre TransferSharePointList nos informa de cmo obtener algunos de los paramtros necesarios: Para obtener el identificador GUID de una lista o una vista del sitio de SharePoint puede utilizar el procedimiento siguiente: 1. Abra la lista de Windows SharePoint Services. 2. Si no se muestra la vista que desea, haga clic en la flecha desplegable Ver y, a continuacin, seleccione la vista deseada. 3. Haga clic en la flecha desplegable Ver y, a continuacin, seleccione Modificar esta vista. La direccin de la barra de direccin del explorador contiene los identificadores tanto de la lista como de la vista. El identificador GUID de la lista sigue a List=, y el de la vista sigue a View=. Sin embargo, en la direccin, cada carcter { (abrir llave) se representa mediante la cadena %7B, cada carcter - (guin) mediante la cadena %2D, y cada carcter } (cerrar llave) mediante la cadena %7D. Por ejemplo:
h t t p : / / M y S i t e 1 2 / _ l a y o u t s / V i e w E d i t . a s p x ? L i s t = % 7 B 2 A...7 D & V i e w = % 7 B 3 5 7 B 4 F E 6...1 5 7 9 B % 7 D

Para poder utilizar los identificadores GUID de la direccin como argumentos de esta accin de macro, primero debe reemplazar cada cadena %7B por el carcter {, cada cadena %2D por el carcter - y cada cadena %7D por el carcter }. No incluya el carcter & (y comercial) que sigue a la cadena %7D en el identificador GUID de la lista. (Me he permitido recortar la URL que la ayuda usa de ejemplo para que me quepa mejor y porque, en el mismo ejemplo de la ayuda, ya la URL est truncada al final) Le faltan unas imgenes que ayuden un poco no? Pues se las ponemos:

Seguir las instrucciones a mano alzada, cortando y pegando con el ratn y editando una cadena tan larga, se hace aguantando la respiracin y, al final, casi seguro que sale mal (a m nunca me ha salido bien). Pero para seguir instrucciones al pie de la letra est la programacin y en Access contamos con VBA, as que me he hecho el siguiente procedimiento que slo necesita que copiemos la URL y se la pasemos como cadena de texto:

' 'P r o c e d u r e:V i n c u l a r V i s t a W S S 'D a t e T i m e :3 0 / 1 2 / 0 82 0 : 3 6 'A u t h o r :C h e a 'P u r p o s e :V i n c u l au n aV i s t ad eS h a r e p o i n tap a r t i rd eu n aU R L ' P a r av i n c u l a ru n aV i s t ad eS h a r e p o i n t ,d e b e m o s ,e np r i m e rl u g a r ,i ra l ' s i t i od eS h a r e p o i n t ,al ap g i n ad ec o n f i g u r a c i nd ed i c h av i s t ayc o p i a r ' l aU R Lc o m p l e t a :E s aU R L ,d e l i m i t a d ap o rc o m i l l a s ,e se la r g u m e n t oq u e ' d e b e m o sp a s a rae s t af u n c i ne ne lp a r m e t r oC a d e n a U R L ' ' P u b l i cS u bV i n c u l a r V i s t a W S S ( C a d e n a U R LA sS t r i n g ,O p t i o n a lN o m b r e T a b l a ) D i mG U I D L i s tA sS t r i n g

geeks.ms/blogs/access/default.aspx

44/52

22/06/13
D i mG U I D V i e wA sS t r i n g D i ms t r S i t eA sS t r i n g D i mvA sV a r i a n t ,V 2A sV a r i a n t ,V 3A sV a r i a n t ,iA sI n t e g e r D i ms t T m pA sS t r i n g '" T r a d u c i m o s "c a r a c t e r e sd el ac a d e n aU R L C a d e n a U R L=R e p l a c e ( C a d e n a U R L ," % 7 b " ," { " ) C a d e n a U R L=R e p l a c e ( C a d e n a U R L ," % 7 d " ," } " ) C a d e n a U R L=R e p l a c e ( C a d e n a U R L ," % 2 5 2 E " ," . " ) C a d e n a U R L=R e p l a c e ( C a d e n a U R L ," % 2 5 2 F " ," / " ) C a d e n a U R L=R e p l a c e ( C a d e n a U R L ," % 2 5 3 A " ," : " ) C a d e n a U R L=R e p l a c e ( C a d e n a U R L ," % 2 D " ," " ) 'O b t e n e m o sl as e g u n dp a r t ed el aU R L ,d e s d ee la s p x ? v=S p l i t ( C a d e n a U R L ," a s p x ? " ) s t T m p=v ( 1 ) ' O b t e n e m o sl a sd i s t i n t a ss e c c i o n e s ,q u ev a ns e p a r a d a sp o r" & " v=S p l i t ( s t T m p ," & " ) F o ri=0T oU B o u n d ( v ) V 2=S p l i t ( v ( i ) ," = " ) I fT r i m ( V 2 ( 0 ) )=" L i s t "T h e n G U I D L i s t=V 2 ( 1 ) E n dI f I fT r i m ( V 2 ( 0 ) )=" V i e w "T h e n G U I D V i e w=V 2 ( 1 ) E n dI f I fT r i m ( V 2 ( 0 ) )=" S o u r c e "T h e n s t r S i t e=V 2 ( 1 ) V 3=S p l i t ( s t r S i t e ," / L i s t s / " ) s t r S i t e=V 3 ( 0 ) E n dI f N e x ti 'V i n c u l a m o sl av i s t a D o C m d . T r a n s f e r S h a r e P o i n t L i s ta c L i n k S h a r e P o i n t L i s t ,s t r S i t e ,G U I D L i s t ,G U I D V i e w ,N o m b r e T a b l a E n dS u b

Access

Publicado por Chea con 2 comment(s) Archivado en: Access 2007,Sharepoint 1/12/2008 22:34 Office Live Small Business en espaol Desde hace tiempo est disponible una versin de Office Live Small Business en espaol, concretamente para Mxico. Los servicios de pago estn disponibles para empresas mexicanas, pero la parte free es de libre acceso, lo cual es una gran noticia para los hispanohablantes. Yo ya me haba acostumbrado a las opciones y mens en lengua hereje, pero sigue sin gustarme que en mi sitio web determinados mdulos, por ejemplo formularios, muestren irremediablemente encabezados,expresiones y formatos en ingls. La nueva versin lo traduce todo al espaol. Al entrar en la pgina de Office Live Samll Business, la opcin de pas predeterminada es Unites States, pero al lado tenemos un botn Change. Al pulsarlo, podemos elegir pas entre une breve relacin de ellos en la que, slo recientemente, aparece Mxico.

Lo haba observado hace no s si una o dos semanas, pero, al cambiar, slo la pgina de presentacin se mostraba en espaol y, al entrar en mi sitio, todo segua en ingls. Prob con una de esas viejas cuentas de prueba, cancel la cuenta de Office Live y, con el mismo Live ID cre una nueva, que segua con todo en ingls. Ayer cre una cuenta nueva de Hotmail y, esta vez s, al crear una cuenta de Office Live en Mxico, todo apareca en espaol. Es decir, por cambiarnos de pas no se traduce nuestro sitio, ni si seguimos usando el Live ID que haba usado previamente, pero si creamos una cuenta nueva con un ID sin estrenar, podremos tener nuestro sitio completamente en espaol. No todo son buenas noticias. Intento hacer un backup desde mi sitio en ingls y restaurarlo en espaol y obtengo un mensaje de error de que no es posible hacer un Restore con una configuracin de idioma distinta. Publicado por Chea con 5 comment(s) Archivado en: Office Live,Sharepoint 1/11/2008 0:38 Presentaciones Seminario Microsoft Access SQL Server del 17/10/2008

El viernes 17 de octubre se celebr en las oficinas de Microsoft en Madrid un seminario sobre la migracin de aplicaciones Access a SQL Server, organizado e impartido por Serra GTS (www.SerraGTS.com) . El seminario era gratuito pero solo haba 25 plazas disponibles que se completaron dos semanas antes del evento. Asistieron responsables de informtica de la Administracin pblica y empresas privadas, y desarrolladores de aplicaciones Access.

geeks.ms/blogs/access/default.aspx

45/52

22/06/13

Access

La primera presentacin realizada por Valentn Play, director general de Serra GTS, con el ttulo "Access y SQL Server, que es mejor en cada caso" se centr en los distintos usos de las bases de datos dentro de una organizacin y la mejor arquitectura de las aplicaciones Access para cada caso. A continuacin Mario Play, director de desarrollo de Serra GTS, present el tema "De Access a SQL Server, paso a paso", exponiendo detalladamente las formas de realizar la migracin tanto de los datos como del cdigo. Durante la ltima parte del seminario, Alejandro Leguizamo de Solid Quality Mentors y MVP de SQL Server, expuso las funcionalidades de SQL Server y respondi a las preguntas que le plantearon los asistentes. Aqu estn las presentaciones:
http://jbchea.net/Documents/Seminario20081017Agenda.pdf http://jbchea.net/Documents/SerraGTSAccessCuandoDonde.pdf http://jbchea.net/Documents/SerraGTSDeAccessaSQLSERVER2005.pdf http://jbchea.net/Documents/SerraGTSGrupoUsuariosAccessEspaol.pdf

Publicado por Chea con no comments 6/10/2008 18:15 Seminario de SQL Server para desarrolladores de Access Acaba de anunciarse este seminario gratuito sobre SQL Server para desarrolladores de Access que tendr lugar en las intalaciones de Microsoft http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032391507&Culture=es-ES el viernes, 17 de octubre de 2008 de 9:0 a 13:30. Publicado por Chea con no comments 29/8/2008 20:26 Evento NotInList en Access 2007 En Access 2007, el evento NotInList puede funcionar exactamente igual que en versiones anteriores, pero dos nuevas propiedades de los cuadros combinados y listas, Permitir ediciones de la lista de valores y Formulario de edicin de la lista, pueden hacer innecesario escribir una sola lnea de cdigo para este evento. Fue empezar a escribir estas lneas antes de las vacaciones y verme explicando en algn foro a algn no tan principiante cmo se utiliza NotInList , as que no est de ms empezar repasando la manera ms cannica de usarlo, pues an hay gente que no lo entiende y se complica haciendo cosas raras; luego contaremos como, modificando un par de propiedades, en Access 2007 puede ser innecesario. El evento NotInlist en cualquier versin de Access Manejar el evento NotInList suele resultar complicado a los principiantes. A pesar de su simplicidad aparente, se manejan algunos conceptos con los que posiblemente no estn familiarizados. Aunque est claramente explicado en la ayuda, suele obviarse que el evento NotInList cuenta con dos parmetros con un cometido muy especfico: NewData nos proporciona el valor que hemos introducido y que no est en la lista y Response espera que le demos un valor de entre una serie de opciones (acDataErrDisplay , acDataErrContinue o acDataErrAdded) para que la aplicacin acte en consecuencia, mostrando mensaje de error o no o aceptando el nuevo valor y haciendo un requery del combo. A veces no basta con meter un dato directamente a una tabla, sino que es necesario abrir un formulario para aadir ese y otros datos. La cuestin aqu es cmo esperar a que se introduzca, o no, el nuevo dato y luego darle el valor apropiado al parmetro Response. Es fcil si se tienen las claves: Si al abrir un formulario DoCmd.Openform utilizamos la constante acDialog en el parmetro WindowMode, ste se abrir en modo dilogo, de manera que cualquier otro cdigo se detiene hasta que cerremos el formulario. DoCmd.OpenForm "Detalles de clientes", , , , acFormAdd, acDialog Ahora, el problema est en pasar informacin entre el formulario que est abierto y el que ha detenido el cdigo hasta que se cierre el otro. A m me gusta dimensionar una variable como pblica en la seccin de declaraciones del formulario que contiene el cuadro combinado. Al declararla como pblica ser accesible desde cualquier lugar de la aplicacin, como si fuera una propiedad del formulario, con la ventaja de que morir con el formulario. Podemos asignarle un valor desde el formulario abierto en modo dilogo y luego comprobarlo al cerrar ste. El cdigo completo en el formulario del evento NotInList sera el siguiente: Option Compare Database Option Explicit Public Respuesta As Integer Private Sub Id_de_cliente_NotInList(NewData As String, Response As Integer) DoCmd.OpenForm "Detalles de clientes", , , , acFormAdd, acDialog, NewData Response = Me.Respuesta End Sub Y, en el formulario dilogo, bastara con una cosa as: Private Sub cmdAceptar_Click() Forms!Pedidos.Respuesta = acDataErrAdded End Sub Private Sub cmdCancelar_Click() Forms!Pedidos.Respuesta = acDataErrContinue End Sub Es decir, al Aceptar o Cancelar, damos a la variable pblica Respuesta del primer formulario el valor que luego tomar Response. Normalmente, querremos que en el formulario de edicin ya se haya insertado el nuevo valor introducido en la lista en su cuadro de texto correspondiente. Para eso, en el ltimo parmetro de la instruccin Docmd.OpenForm, OpenArgs, he pasado el valor de NewData: DoCmd.OpenForm "Detalles de clientes", , , , acFormAdd, acDialog, NewData En el formulario para aadir el nuevo dato comprobamos si estamos en un nuevo registro y si hemos pasado algn valor en OpenArgs, en cuyo caso, nos posicionamos en el control correspondiente con SetFocus y ponemos en la propiedad Text el valor que hemos recibido en OpenArgs. Option Compare Database Option Explicit

geeks.ms/blogs/access/default.aspx

46/52

22/06/13
Private Sub Form_Load() If Me.NewRecord And Nz(Me.OpenArgs, "") <> "" Then Me.Apellidos.SetFocus Me.Apellidos.Text = Me.OpenArgs End If End Sub El Evento NotInlist en Access 2007

Access

En Access 2007, dos nuevas propiedades de los cuadros combinados y listas, "Permitir ediciones de la lista de valores" y "Formulario de edicin de la lista", pueden suplir al evento NotInlist.

Propiedad Permitir ediciones de la lista de valores


Si el Tipo de origen de la fila es Lista de valores y el cuadro combinado o lista tiene una sola columna, si establecemos el valor de la propiedad Permitir ediciones de la lista de valores a S, podremos modificar sus valores en tiempo de ejecucin. Tenemos dos posibilidades:
Editar directamente la lista

Al desplegar un cuadro combinado o lista que tenga Permitir ediciones de la lista de valores, se muestra al final de la lista un icono flotante.

Si pulsamos sobre el icono, se despliega un formulario para editar los valores de la lista, incluso podemos editar el valor predeterminado.

Al no estar en lista

Funciona de la misma manera que el evento NotInList, de hecho, en primer lugar se disparara ese evento. Es decir, si la propiedad Limitar a Lista es S e introducimos en ella un valor inexistente, Access 2007 nos informar de que no existe el valor y nos preguntar si deseamos modifcar los elementos de la lista, en cuyo caso nos abrira el mismo formulario para editar valores que en el caso anterior.

Ambas posibilidades slo funcionan si la lista o cuadro combinado slo tiene una columna. Si tiene ms de una columna, tendramos que recurrir a los mismos mtodos de versiones anteriores.

Propiedad Formulario de edicin de la lista


La propiedad Formulario de edicin de la lista indica el nombre del formulario que queremos usar para editar los valores de un cuadro combinado o lista cuando cuando la propiedad "Tipo de origen de la fila" es Tabla o Consulta.

geeks.ms/blogs/access/default.aspx

47/52

22/06/13

Access

Lo mismo que veamos cuando el tipo de origen de la fila era "Lista de valores", podemos editar los valores en tiempo de ejecucin, bien pulsando directamente sobre el icono flotante al final de la lista desplegada, bien al introducir un valor que no existe; la diferencia es que el formulario de edicin ser uno que nosotros hayamos creado para editar la tabla subyacente al combo o lista. Nuestro formulario se abrir en modo dilogo (no necesariamente emergente) deteniendo la ejecucin del cdigo de los dems formularios. Al cerrarse, si se han modificado los datos, se actualizar el origen de datos del combo o lista. y si el texto que habamos introducido coincide con un nuevo valor, se dar por vlido y no se producir error. O sea, ms o menos lo que nosotros habramos hecho editando el evento NotInList.
Aadiendo un poco de cdigo

Pero este formulario se comportar exactamente igual si hemos pulsado el icono flotante para editarlo que si se ha abierto al no estar en la lista, es decir, se abre en modo edicin en el primer registro. Seguramente querremos que se comporte como hemos hecho mediante cdigo en versiones anteriores, o sea, que vaya directamente a un registro nuevo y que posicione en el cuadro de texto correspondiente el valor que hemos introducido en la lista Cmo conseguimos esto? Tendremos que usar un mnimo de cdigo. Si en el formulario de edicin de la lista ponemos el siguiente cdigo Private Sub Form_Load() Debug.Print Me.OpenArgs End Sub Al no estar en lista, en la venta de inmediato del editor de VBA nos encontraremos algo as: [Detalles de pedidos de compra]![Supplier ID]=Ramirez Es decir, que al abrirse el formulario el formulario de edicin de la lista, sin necesidas de ninguna intervencin por nuestra parte, Access 2007 ha pasado un argumento OpenArgs con el nombre del formulario y el del cuadro combinado o de lista y el valor que hemos dado a ste. Podemos utilizar OpenArgs para, si existe, ir a un registro nuevo y rellenar el cuadro de texto correspondiente: Private Sub Form_Load() Dim v As Variant If Nz(Me.OpenArgs, "") <> "" Then If InStr(Me.OpenArgs, "=") <> 0 Then v = Split(Me.OpenArgs, "=") DoCmd.GoToRecord , , acNewRec Me.Apellidos.SetFocus Me.Apellidos.Text = v(1) End If End If End Sub
Pero Qu pasa con el evento NotInlist en Access 2007?

Podemos usar el evento NotInList junto con la propiedad Formulario de edicin de la lista. En primer lugar se disparar el evento y luego, dependiendo del valor que en ste demos a Response, se abrir automticamente, o no, el formulario de edicin de la lista. Publicado por Chea con 7 comment(s) Archivado en: Access 2007,Combos 24/6/2008 21:43 Quin dijo memos? Los memos en Access 2007 ya no parecen tan memos. Ahora vienen con un par de caractersticas que les hacen ms interesantes: Soportan formato de texto enriquecido y la posibilidad de slo permitir anexar, no modificar. Un ao despus del lanzamiento de la versin 2007, esto ya no es novedad, pero an cabe jugar con ellos para explorar posibilidades que quizs se escapen a primera vista. Este artculo fue publicado en el Rincn del experto del mes de abril.

Formato de texto enriquecido


TextFormat en controles de texto
sta, que es la novedad ms vistosa, no supone ningn cambio en el tipo de datos, sino que el mrito se lo lleva el nuevo control de texto que es capaz de

geeks.ms/blogs/access/default.aspx

48/52

22/06/13

Access

manejar el "Rich text format". Los campos memos siguen guardando texto plano, pero dependiendo de cmo est establecida la propiedad "Formato de texto", Textformat, mostrar el formato enriquecido o las etiquetas HTML de ste. Es decir, si en el cuadro de texto TexFormat = acTextFormatHTMLRichText, podramos ver algo as:

Muestra
Pero, si en el cuadro de texto TexFormat = acTextFormatPlain, lo que veramos sera: <div align=center><font size=5 style="BACKGROUND-COLOR:#FFFF00"><strong><em><u>Muestra</u></em></strong></font></div> Como la propiedad lo es del cuadro de texto, se aplica no slo a los memos de 2007, sino tambin a los de versiones anteriores de Access. Si usamos el formato enriquecido con campos de un archivo en formato MDB desde Access 2007, se comportar igual que un ACCDB, pero, si lo vemos desde una versin anterior de Access, por ejemplo, 2003, se mostraran las etiquetas HTML.

TextFormat en campos memo


Pero no slo los controles de texto tienen la propiedad "Formato de texto" o TextFormat , tambin la tienen los campos memo. A simple vista, da la impresin de que esto afecta de alguna manera a los datos, pero no parece que sea as; sigue siendo texto plano, con o sin etiquetas HTML. Bueno, en cierto modo s que afecta a los datos: si en un memo con texto enriquecido cambiamos la propiedad TexFormat a acTextFormatPlain, desaparecern de manera irreversible todas las etiquetas HTML, lo cual puede ser til para hacerlo legible en versiones anteriores de Access, pero un poco peligroso si andamos jugando con datos reales. Si mostramos los datos de la tabla y el formato de texto es enriquecido, se muestra como tal, dando la apariencia de que se ha guardado de una forma especial, pero si en una consulta o en un formulario, creamos un campo calculado cuyo origen sea = MiMemo , veremos que el contenido sigue siendo un archivo de texto con etiquetas HTML. Al aadir un campo memo a un formulario o informe en modo diseo, el cuadro de texto hereda la propiedad TextFormat del campo, pero podemos cambiarle la propiedad a la contraria y, si no hay datos, sta prevalecer. Si existen datos, tambin prevalecer la propiedad pero el resultado inmediato sobre los datos existentes seguramente ser chocante, pues hay que tener en cuenta que las etiquetas HTML no dejan de ser texto.

Resumiendo
La propiedad Formato de Texto en un campo memo en el diseo de la tabla sirve para determinar cmo se muestran los datos en la vista Hoja de Datos de la tabla y para ser heredada por los controles que tengan por origen ese campo. La propiedad Formato de Texto en un cuadro de texto determina la forma en que se muestra ste. No tiene por qu coincidir la propiedad TextFormat de un control con la de del campo memo del que dependa, aunque con datos existentes se pueden producir resultados chocantes. Juguemos un poco

Busquemos usos distintos:

Una forma muy sencilla de mostrar "etiquetas" en texto enriquecido es crearnos una tabla con un memo con formato enriquecido que editamos a nuestro gusto. Para el equivalente de una etiqueta podemos usar un campo calculado con un dLookUp() que busque el registro que queramos. Para que se comporte como una etiqueta, basta con poner las propiedades Bloqueado a S y Activado a No. Sustituir a un msgbox puede ser algo casi tan sencillo como eso o darle toda la complejidad que queramos.

Concantenando variables
Es muy frecuente concatenar campos o variables con cadenas de texto para mostrar los resultados en un informe o formulario. Podemos usar, por ejemplo: = "Estimado Sr. " & [PrimerApellido] & ":" Para obtener el resultado: Estimado Sr. Fernndez: Pero nos faltaba una posibilidad sencilla de poder formatear ese campo calculado, por ejemplo, poner en negrilla el apellido. Cmo hemos visto que se trata de etiquetas HTML, basta con aadir stas a la cadena para conseguir el resultado: ="Estimado Sr. <strong>" & [PrimerApellido] & "</strong>" Y el resultado que obtendramos sera: Estimado Sr. Fernndez No hace falta saber HTML para hacer esto. Podemos crearnos un formulario auxiliar con dos cuadros de texto, uno con formato enriquecido y otro sin l cuyo origen sea el primero. Cualquier formato que demos en el primer cuadro, se reflejar en cdigo en el segundo. Slo hay que copiar y pegar, teniendo en cuenta que <div> y </div> son las marcas de inicio y fin de prrafo y que puede que no necesitemos.

geeks.ms/blogs/access/default.aspx

49/52

22/06/13

Access

An as sigue siendo pesado, de manera que tendremos que ingeniarnos una herramienta distinta. Son slo tres pasos:

1. Nos creamos una tabla con un campo de Formato, de texto, y otro Muestra, memo, y un formulario para editarla en el que al campo Muestra le ponemos como valor predeterminado, "Muestra" y como Formato de texto,"Texto enriquecido".

1. Le damos a Muestra los formatos que queramos y en Formato ponemos un texto descriptivo para despus localizar el formato. 2. Nos creamos una funcin que busque Formato, lea el contenido de Muestra y en l sustituya la palabra "Muestra" por el contenido que queremos formatear Public Function FormatoHtml(Cadena As String, Formato As String) As String Dim vTmp As Variant, sTmp As String vTmp = DLookup("Muestra", "LocalFormatos", "Formato = '" & Formato & "'") If Not IsNull(vTmp) Then sTmp = vTmp sTmp = Replace(sTmp, "<div>", "") sTmp = Replace(sTmp, "</div>", "") 'Quitamos las marcas de prrafo que nos sobran sTmp = Replace(sTmp, "Muestra", Cadena) 'Cambiamos el texto Muestra por nuestra cadena Else sTmp = Cadena 'Si no encontramos el formato, devolvemos la cadena sin formato End If FormatoHtml = sTmp End Function Probando en la ventana de inmediato, tendramos: ? FormatoHtml ("Hola mundo","negrita") <strong>Hola mundo</strong> ? FormatoHtml(FormatoHtml("Hola mundo","negrita"),"Cursiva") <em><strong>Hola mundo</strong></em> De la misma manera, en el primer ejemplo, podramos poner algo as: ="Estimado Sr. " & FormatoHtml([PrimerApellido];"negrita") & ":" y el resultado sera: Estimado Sr. Fernndez : Ahora le toca jugar a cada uno. Evidentemente, la funcin es un apao que tendramos que mejorar. Un DLookUp () en cada registro de una consulta, bajara notablemente el rendimiento; en su lugar podramos cargar la tabla de formatos en una matriz o en un objeto Dictionary y buscar ah. Tambin nos podra interesar una composicin ms compleja abriendo y cerrando formatos. Nos seguira valiendo la misma tabla y la misma bsqueda; haciendo un Split() del resultado usando como separador la palabra "Muestra", tendramos en el primer elemento de la matriz resultante las etiquetas de apertura, y en el segundo, las de cierre.

Publicado por Chea con 3 comment(s) Archivado en: Access 2007,Campos Memo 22/5/2008 19:53

geeks.ms/blogs/access/default.aspx

50/52

22/06/13
Reunin de usuarios de Access el 13 de junio de 2008

Access

Se ha organizado una reunin de usuarios de Access en Madrid para el prximo 13 de junio. La idea es que podamos conocernos personalmente y ver alguna presentacin de temas de inters relacionados con Access. La vocacin es que algn puede acabar siendo el inicio de un grupo de usuarios de Access. Si te interesa el tema, sigue el enlace: http://reunionaccessmadrid20080613.googlepages.com/

Publicado por Chea con no comments 30/4/2008 15:01 El uso de las Cintas de Opciones (Ribbon) y VBA (Visual Basic for Application). RibbonAndVBA
En este artculo se va a tratar a un nivel bsico de las Cintas de Opciones (Ribbon) y su uso con VBA. Ribbon a nivel de base de datos. Si uno est acostumbrado a usar Barras de Herramientas Personalizadas deber de cambiar el chip bueno jejeej cambiar no, olvidarse totalmente de ese concepto para entrar a un nuevo mundo del Ribbon que supera a las Barras pero que incomoda al tener que aprender varios conceptos nuevos y los siguientes son alguno de ellos, El Ribbon va asociado a un formulario o informe o a la aplicacin. El Ribbon que est asociado a un formulario slo est activo cuando dicho formulario al estar abierto no sea emergente y est visible, cualquier cambio de valor de estas dos ltimas propiedades hace que el Ribbon desaparezca. En caso de asociar el Ribbon a la base de datos este estar en cache mientras dure la sesin de la aplicacin pudiendo ser sustituido por otra al abrir un formulario o informe volviendo a ser visible al cerrar los objetos comentados.Usando la interface de Access se puede establecer el Ribbon del siguiente modo, Botn Office | Opciones de Access | Base de datos actual | Opciones de barra de herramientas y de la cinta de opciones | Nombre de banda de opciones:

Con cdigo de VBA usando la propiedad CustomRibbonID del objeto Database. CodeDb.Properties("CustomRibbonID") = "rbbInicio" O para crearla, CodeDb.Properties.Append CodeDb.CreateProperty("CustomRibbonID", dbText, "rbbInicio") En todos los casos hace falta reiniciar la base de datos para hacer visible el Ribbon.

Ribbon a nivel de objetos formulario (form) o informe (report). Sencillo, sencillo, no hay ms que rascar de lo que se indica aqu y de modo parecido a la seccin anterior hay un mtodo visual y otro a travs de cdigo VBA.Usando el mtodo visual y en modo edicin de un form o report, Hacer visible la Hoja de propiedades (Alt + Entrar) | Solapa: Otras | Nombre de banda de opcin.

geeks.ms/blogs/access/default.aspx

51/52

22/06/13

Access

Con cdigo de VBA usando la propiedad RibbonName del objeto Form o Report. Me.Properties("RibbonName") = "rbbNombreRibbon"

Ribbon, planteamiento de uso. A la conclusin que he llegado trasteando con esta nuevo bicho de Access 2007 es sencilla pero para llegar a ella me he tenido que pelear unas cuantas horas con l, en realidad es como se aprende y salen un montn de notas!!.Para obtener una aplicacin con Ribbon hace falta los siguiente, Usar un Ribbon (rbbPrincipal) a nivel de base de datos, tal como se ha comentado en la seccin anterior Ribbon a nivel de base de datos . Usar Ribbon independientes para los formularios e informes (rbbFormA, rbbFormB, rbbSub1FormA, rbbSub2FormA, rbbReportA, etc.) que se irn activando y desactivando conforme el objeto tome el foco, tal como se comenta en la seccin Ribbon a nivel de formulario (form) o informe (report). As de sencillo, no hay ms. Si uno es observador y est familiarizado con las convenciones de nombre podr comprobar en los nombres de ejemplo de las Cintas de Opciones, como tambin se indica Sub de subformulario. Si dentro de un formulario existen uno o ms subformularios estos tambin tienen (como formulario que es) la propiedad RibbonName para activar un Ribbon, al activar subFormA se dispara el Ribbon rbbSub1FormA, al tomar el foco subFormB el anterior desaparece y queda activo rbbSub1FormB, genial! Como efecto visual es muy bueno y atractivo.

Ribbon ejemplo prctico. Vayamos a visualizar lo comentado hasta ahora, descargar el ejemplo propuesto al final del artculo llamado test.RibbonAndVBA en Attachment. Al abrir la base de datos se inicia con un formulario inicial de presentacin, al pulsar el botn Aceptar se presenta un nuevo form llamado frmTest con dos grandes botones y un tercero para cerrarlo. Antes de continuar hay que indicar que previo a abrirse los formularios se activa la Cinta de Opciones llamada rbbPrincipal y es la nica visible en estos momentos.Volvemos a frmTest y pulsamos el primer botn grande, Activar Cinta de Opciones y se puede apreciar como ha desaparecido rbbPrincipal y se ha hecho visible rbbAyuda.

Ribbon y sus particularidades. Continuando con la base de datos de test nos encontramos con dos formularios el z01_frmEmergente y z02_frmInvisible que sirven para observar dos particularidades imaginables por su nombre. z01_frmEmergente es un formulario con su propiedad emergente a True, al activar la cinta de opciones rbbAyuda y tras clicar el botn se observa que esta cinta aparece y desaparece inmediatamente por lo que no se aconseja usar este tipo de formularios si debe de usarse una cinta. z02_frmInvisible es visible al abrirlo, activamos la cinta rbbAyuda usando el botn y a continuacin clicamos Cambiar el estado de este formulario en invisible, voila, desaparece el form y la cinta. Es comprensible ya que el formulario pierde el foco y por tanto vuelve el Ribbon principal. McPegasus, 30/04/2008

Publicado por McPegasus con 5 comment(s) Archivado en: Access 2007,Ribbon Ms artculos Pgina siguiente >

geeks.ms/blogs/access/default.aspx

52/52

Вам также может понравиться