jueves, 30 de octubre de 2014

Artículo: Activar y Desactivar Botones en Tiempo de Ejecución de la Cinta de Opciones de Excel. 2ª Parte.

Al situarnos en la plantilla se desactiva el botón.
Al situarnos en la plantilla se desactiva el botón.
Seguimos con la segunda parte del artículo dedicado a explicar como activar y desactivar botones en la Cinta de Opciones de Excel. En el artículo anterior explique el uso de la propiedad enabled y empecé a explicaros el uso de la función "getEnabled" para activar y desactivar los botones en tiempo de ejecución. Con "getEnabled" conseguimos que al abrir el documento el botón se activará o desactivará dependiendo de en que hoja estábamos situados en el momento de abrirlo. En este artículo vamos a seguir con "getEnabled" y continuaremos donde lo dejamos hasta conseguir que el botón para eliminar facturas se active o se desactive dependiendo de en que hoja nos situemos. Así ya tendremos controlado ese botón en toda las situaciones posibles que se pueden dar: Al abrir el documento y mientras estamos trabajando con él.

Parte del trabajo ya lo tenemos hecho del artículo anterior, pero nos faltan algunos "detalles". Si alguien empieza por esta parte en lugar de por el artículo anterior, le recomiendo que lo deje y que primero realice los pasos anteriores. No voy a repetir todo lo que ya hemos visto y quizás os sintáis un poco perdidos. Para seguir este artículo podéis utilizar el documento finalizado del artículo anterior o bien descargarlo en el siguiente enlace.


Entonces, nuestro objetivo es hacer algo para que cuando se cambie de una hoja a otra del documento, el botón se active o se desactive según le toque. Antes de ponernos con el trabajo os voy a intentar explicar a grandes rasgos que vamos a tener que hacer para conseguir lo que quiero, así no vais tan a ciegas con lo que os voy explicando. Como ya os comenté el control de la Ribbon desde VBA es un poco complicado y lo que vamos a ver hoy lo confirma mucho más. Ya os dije que no hay una orden tipo "botonEliminar.Enabled = False", de nuevo vamos a tener que usar la función "getEnabled" y algún que otro "truco" más. Abrimos el documento en el Custom UI Editor y os sigo comentado.

Código XML artículo anterior.
Código XML artículo anterior.

<button id="botonEliminarFactura" label="Eliminar" 
getEnabled="ModuloRibbon.ActivarDesactivarBotonEliminar" 
onAction="ModuloFacturas.EliminarFactura"/>

En el código del artículo anterior, en "getEnabled", indicamos que Excel debía llamar a un procedimiento de VBA para decidir que estado debía tener el botón, activado o desactivado. El procedimiento estaba situado en un módulo llamado "ModuloRibbon" y se llamaba "ActivarDesactivarBotonEliminar". Este procedimiento es llamado cuando se crea el botón en la Ribbon, al cargar la personalización que estamos creando, Excel se da cuenta que para mostrar este botón debe llamar a ese procedimiento y así se decidirá si está activado o no. En el artículo anterior nos aprovechamos de esto para que al abrir el documento en Excel el botón de eliminar facturas esté en el estado correcto. Como al abrir el documento se carga la personalización, Excel llama a ese procedimiento para ver como tiene que quedar el botón.

Procedimiento VBA para activar y desactivar el botón.
Procedimiento VBA para activar y desactivar el botón.

¿Que es lo que vamos hacer ahora? Bueno pues básicamente, vamos a obligar a cargar de nuevo el botón cuando cambiemos de una hoja a otra y al hacer esto, se volverá a llamar a ese procedimiento para decidir que estado debe tener el botón. Recordad que en el procedimiento "ActivarDesactivarBotonEliminar" se controlaba en que hoja del documento estábamos y en función de eso se decidía si se activaba o no el botón. Bueno pues al volver a cargar de nuevo el botón en la Ribbon, esa comprobación se volverá a realizar y se activará o desactivará el botón según la hoja en la que estemos en ese momento. Vamos a conseguir que el botón se cree de nuevo en la Ribbon.

En realidad es mucho más retorcido lo que vamos hacer, porque seguro que más de uno estará pensando... ¿Y como le vamos a decir que cargue de nuevo el botón? Bueno pues es que en realidad no le vamos a decir que cargue el botón, le vamos a decir que lo invalidamos... Y al hacerlo, Excel lo vuelve a cargar porque ya no es válido. Es decir yo no puedo cargar de nuevo un control, pero si puedo indicar que ya no es válido para que Excel se encargue de cargarlo de nuevo y así provocaremos que se llame otra vez al procedimiento que hemos indicado en "getEnabled". Este es el proceso que hemos seguido hasta ahora y el que vamos a seguir:

  • Abrimos el documento en Excel y se carga la Ribbon personalizada.
  • Al cargar la Ribbon personalizada debe crear el botón para eliminar facturas y ahí se da cuenta que para establecer el estado del botón, se llama desde "getEnabled" a una macro que hemos creado con VBA.
  • Se ejecuta esa macro y se activa o se desactiva el botón dependiendo de la hoja en la que aparecemos situados al abrir el documento.
  • A partir de aquí empieza lo nuevo. Cuando cambiemos de una hoja a otra mientras trabajamos en el documento, usaremos el evento SheetActivate para invalidar el botón de eliminar facturas. Ese evento salta cuando se activa una hoja, al cambiar de una hoja a otra se activa en la que nos situamos.
  • Al invalidar el botón, Excel lo intentará crear otra vez y de nuevo llegará a la misma conclusión. Para establecer el estado del botón hay que llamar a la macro que apunta "getEnabled" y así en función de la hoja en la que estamos en ese momento se activará o se desactivará el botón.

Esta es la idea, ya os había dicho que no es fácil y que el acceso a la Ribbon no es directo, hay que dar unas "pocas vueltas". Bueno, vamos a empezar con el trabajo de codificación. En este paso vais a tener que hacer un pequeño acto de fe, ya que el código que vamos a escribir no va tener una representación visual en la Ribbon. Tenemos que hacer una modificación a la primera línea, la línea en la que indicábamos el espacio de nombres que queríamos usar en este documento. Al final de la línea debemos añadir lo siguiente:

<customUI
xmlns="http://schemas.microsoft.com/office/2009/07/customui" 
onLoad="ModuloRibbon.AlCargarRibbon">

La parte nueva en la línea anterior es en la que usamos la función "onLoad". La idea de esta función es muy similar a lo que os he explicado sobre "getEnabled".  En ella he indicado un procedimiento de VBA, una macro, que será ejecutada cuando la personalización que estamos creando se cargue. Es decir, ahí le he indicado que cuando se cargue la personalización que está definida en el customUI que estamos creando, debe ejecutar una macro llamada “AlCargarRibbon”, que está guardada en un módulo llamado “ModuloRibbon”.
¿Por qué hacemos esto? Bueno pues porque en el interior de ese procedimiento o macro, que se ejecuta justo en el momento en el que se cargue la personalización, vamos a tener acceso a la Ribbon, a la Cinta de Opciones…  Y eso nos va permitir hacer algo que después nos facilitará el acceso continuo a la Ribbon, para poder hacer con ella lo que necesitemos en cualquier momento. En este caso concreto activar o desactivar el botón a nuestro gusto. Ya se que suena muy raro pero tenéis que hacer unos pocos actos de fe en este artículo.

Ya está, esto es todo lo que teníamos que hacer en el Custom UI Editor, como muy bien os imaginaréis, ahora el siguiente paso es ir a Excel y desarrollar la macro que acabamos de indicar en “onLoad”.

lunes, 20 de octubre de 2014

Vídeo: Depurar y Encontrar los Errores en el Código XML que personaliza la Interface de Usuario de Excel.



En los primeros vídeos dedicados a la personalización de la Interface de Usuario de Excel, hemos ido creando unas personalizaciones básicas de la Ribbon de Excel. Aunque han sido personalizaciones muy simples, es muy fácil confundirse a la hora de escribir código XML y la verdad es que luego no es tan fácil encontrar donde están los errores. Si no conocéis las dos posibilidades para encontrar errores que os voy a explicar en este vídeo, os acabaréis volviendo locos.

Para depurar y encontrar los errores tenemos estas dos opciones. Primero podemos utilizar la validación del código XML que se puede realizar en el Custom UI Editor. Esta validación puede ser interesante usarla mientras vamos desarrollando el código, para ir corrigiendo errores rápidamente. Antes de abrir el documento en Excel y encontrarnos con problemas la podemos usar para ver si todo está bien. Con el tiempo os daréis cuenta que esta validación tiene algunas limitaciones y puede que se le pasen errores en el código XML.

Para identificar los errores que se le pasen al Custom UI Editor podemos usar la depuración de código XML que ofrece Excel. Activando una opción de Excel, el programa nos avisará de los errores que encuentra al cargar las personalizaciones... Y a esta posibilidad sí que no se le pasará ningún error. En el vídeo vamos a utilizar las dos provocando diferentes errores y viendo cómo funcionan ambas posibilidades ante los mismos errores. Acabaréis viendo como la opción de Excel es mucho más completa en cuanto a identificar errores y dar información sobre ellos.

Para realizar los pasos que veréis en el vídeo os podéis descargar el siguiente archivo de Excel:



Todos mis vídeos son Gratis, pero si te gusta mi trabajo, puedes realizar una donación para que pueda continuar con este proyecto. Cualquier cantidad desde 1€/1$ es bienvenida. Gracias!!!!!!!!!!!!!!

 

Como siempre aquí tenéis el enlace para ver el vídeo, espero que os guste:

  • Nombre: Depurar y Encontrar los Errores en el Código XML que personaliza la Interface de Usuario de Excel.
  • Versión de Excel: ES/Español.
  • Audio: Español.
  • Subtítulos: Español.
  • Duración Vídeo: 19m 15s.



Nada más por hoy. Para mañana intentaré tener lista la segunda parte del artículo dedicado a desactivar y activar botones de la Cinta de Opciones en tiempo de ejecución ;)

martes, 14 de octubre de 2014

Artículo: Cómo Activar y Desactivar Botones en la Cinta de Opciones de Excel con enabled y getEnabled. 1ª Parte.

Botón desactivado en la Cinta de Opciones.
Botón desactivado en la Cinta de Opciones.
Seguimos profundizando en la personalización de la "Cinta de Opciones" de "Excel" y en este artículo os voy a explicar cómo activar y desactivar los botones que creemos en ella. Os voy a explicar cómo hacerlo tanto en tiempo de diseño como en tiempo de ejecución. Empezaremos el artículo hablando de la propiedad "enabled" que nos permite indicar si un control aparece activado o desactivado. Esta opción es interesante si por ejemplo queremos que los controles aparezcan siempre de inicio desactivados. Esta sería la opción que tenemos para controlar el estado de los botones en tiempo de diseño, cuando estamos creando el código XML que define el botón. Pero no es la opción más interesante y potente que tenemos para activar o desactivar controles. La otra posibilidad que tenemos es la de activar o desactivar los botones mientras se usan los documentos de Excel. Es decir dependiendo de condiciones que nosotros necesitemos controlar, decidiremos si los controles se activan o se desactivan. Para esto usaremos la función "getEnabled" y código VBA. El uso de esta función os lo voy a explicar en dos artículos, si lo haría todo en este quedaría un artículo muy largo y creo que así se entenderá mejor ya que su uso es un poco "extraño". Cuando empecemos con esta función os daré más detalles.

Para seguir los pasos de este artículo necesitáis descargaros el siguiente documento de Excel que he preparado. Es una modificación de los que he usado en artículos anteriores y en los vídeos que estoy publicando del mismo tema. Cuando lo tengáis lo abrís en el "Custom UI Editor".


Este documento tiene una ficha personalizada llamada "FACTURACIÓN" en la que hay tres botones, pero de entada ya os digo que sólo funciona uno, el botón para eliminar facturas. La idea es que con esos botones podemos crear, guardar y eliminar facturas pero los dos primeros botones tienen mucho trabajo y voy a dejar la explicación para los vídeos. Aquí me voy a centrar sólo en la parte importante, en cómo podemos activar o desactivar botones de la Ribbon. Para la primera parte de este artículo usaré el botón de crear nuevas facturas y para la segunda utilizaré el de eliminar facturas.

Botones personalizados de la Ribbon con los que vamos a trabajar.
Botones personalizados de la Ribbon con los que vamos a trabajar.

Vamos con la parte del artículo en la que os hablo de la propiedad o atributo "enabled". Esta propiedad también la tienen otros controles pero de momento en el curso estamos centrados en los botones que son los controles más sencillos de usar. La propiedad "enabled" establece si el control, en este caso el botón, está activado o no. Se le pueden asignar dos valores a esta propiedad, "true" o "false", verdadero o falso. Con true se activa el botón y con false de desactiva. Por ejemplo vamos a desactivar el primer botón que tenemos definido en nuestra ficha personalizada, el de crear nuevas facturas. Añadimos a la definición de ese botón esa propiedad.

<button id="botonNuevaFactura" label="Nueva" size="large" image="Nueva" enabled="false"/>

Igual que con el resto de propiedades escribimos el nombre de la propiedad y entre comillas dobles le asignamos su valor, en este caso "false" para desactivar el botón. Vamos a probar que hemos conseguido con esto, cerramos guardando los cambios y abrimos el documento en Excel. Al abrirlo, como lo habéis descargado de Internet seguramente os pedirá que habilitéis la edición y que habilitéis las macros, lo hacéis. Y como podemos ver en la siguiente imagen el botón aparecerá desactivado. Esta difuminado y si intentamos pulsar encima de él no podemos.

El primer botón de la ficha personalizada está desactivado con el atributo enabled.
El primer botón de la ficha personalizada está desactivado con el atributo enabled.

Bueno pues esta es la idea, con esa propiedad podemos establecer si un control está activado o no. Esto que os acabo de explicar está muy bien, lo que pasa que es muy limitado. Esto nos puede servir si queremos que algún control esté siempre desactivado al abrir un documento, pero si necesitamos que el botón este activado o desactivado dependiendo de algo, no lo podemos hacer con "enabled". Eso lo tendríamos que hacer con la función "getEnabled", vamos con ella.