miércoles, 23 de enero de 2013

A - Control calendario en Excel 2010 con VBA

Control MonthView


Comentarios

Como ya es sabido, en MS Excel 2010 fue removido el Control Calendar, conocido como mscal.ocx, este ya no existe en el paquete de ofimática de Microsoft Office 2010, por tanto, es necesario tomar otras alternativas y/o caminos diseñados por Microsoft para solventar esta falencia, que a pesar de todo resultó en una herramienta útil al trabajar con fechas en Excel y más si trabajamos con formularios desde el entorno VBA.

Ahora, existen tres alternativas posibles para poder trabajar con Calendarios en MS Excel 2010, la primera, consiste en utilizar el Control Data Picker desarrollado por Sam Radakovitz; la segunda, es descargar el control mscal.ocx e instalarlo en nuestra PC, pero además de ello es necesario registrar dicho control para poder usarlo sin ningún problema, el único inconveniente es que en Windows 8 este control ya no permite ser registrado, por lo que en última instancia ya no puede ser usado; y la tercera, que a mi parecer suele ser la mejor opción por ser un control de fácil uso y además muy comprensivo y entendible a la hora de programarlo, es utilizar el control MonthView.

Veamos a través de un ejemplo muy sencillo como ingresar fechas en una Hoja de Trabajo de Excel (Hoja de cálculo) usando un calendario para realizar la selección de la fecha y posteriormente se inserte en la celda actual o celda seleccionada.


Nota: para el desarrollo de esta ayuda, asumo que el lector (participante y/o usuario) tiene pleno conocimiento o nociones mínimas de como activar la Pestaña Programador de su MS Excel 2010, además de como activar y entrar en el entorno de desarrollo de VBA, es decir el Editor de VBA.

En caso de no saberlo, por favor diríjase a este video de corta duración (2 Minutos) en el cual se explica de manera clara estos requerimientos mínimos.


Título del Video: Activar la pestaña programador y el editor de VBA en Excel.


continuación se describen los pasos a seguir...


1.   Activar el Control Microsoft MonthView Control 6.0 (SP6).

Inicialmente y es claro que lo primero que debemos hacer es abrir un Archivo de Excel nuevo y guardarlo en una ubicación conocida, con un nombre conocido.

Estando ya en el documento de MS Excel 2010 en blanco, procedemos a activar el Editor de VBA.

a) Ahora insertamos un Formulario (UserForm) en nuestro proyecto, a través del Menú Insertar y dando Click en el comando UserForm.

b) Observe como el formulario se ha insertado y se ha desplegado automáticamente un pequeño cuadro de controles llamado Cuadro de herramientas.

c) Con el cuadro de herramientas seleccionado colocamos el puntero del mouse en la parte interna de dicho cuadro, y damos Click derecho para mostrar el menú contextual, donde seleccionamos la opción Controles adicionales de dicho menú y damos Click en él.

d) Con esto nos debería aparecer el cuadro de dialogo Controles adicionales, en el cual debemos buscar el control Microsoft MonthView Control 6.0 (SP6), seleccionarlo (Activar) y dar Click en Aceptar. Ver Figura 1.

e) Vemos como aparece un nuevo control en el Cuadro de herramientas el cual ya tenemos a disposición para usarlo en nuestros Formularios. Ver Figura 2.


Figura 1. Vista de los cuadros de diálogo: Controles adicionales y Cuadro de herramientas.

Figura 2. Nuevo control en el Cuadro de herramientas.


Me siguen…


2. Dar nombre al Formulario (UserForm1) e Insertar un Objeto de Tipo MonthView.

A esta altura ya hemos superado la parte más complicada del ejemplo, ahora lo que haremos es dar un nombre a nuestro formulario que de momento se llama UserForm1, para ello debemos modificar las Propiedades (Name y Caption) del Formulario a través de la Ventana de propiedades. Es necesario recordar que debemos tener activo el Formulario para cambiar sus propiedades, es decir tenerlo seleccionado.

En la Ventana de propiedades he cambiado estas dos propiedades así:

En la propiedad Name he colocado frmCalendario, y en la propiedad Caption he colocado Calendario. Es claro y evidente que la propiedad Caption es la que nos permite visualizar el nombre que se mostrara al usuario final y la propiedad Name es el nombre mediante el cual llamaremos al formulario u objeto durante la programación del mismo con VBA. Ver Figura 3.

A continuación,

Insertamos un Objeto de tipo MonthView en nuestro Formulario, para ello solo arrastramos el control MonthView del Cuadro de herramientas y lo soltamos en el interior del Formulario. Como vemos, aparece un pequeño calendario dentro del Formulario.

Ahora solo nos resta colocar un nombre al Objeto MonthView y alterar la Propiedad ShowToday (Para mostrar la fecha actual del ordenador en el calendario), para ello seleccionamos el objeto recién insertado y en la Ventana de propiedades alteramos la Propiedad Name que de momento se encuentra como MonthView1, y establecemos en True la Propiedad ShowToday.
Yo le he puesto mvMiCalendario a la propiedad Name.

Lo último que nos queda es ajustar el tamaño de mi " mvMiCalendario" dentro del Formulario. Ver Figura 4.


Figura 3. Alteramos la Propiedad Name y Caption del Formulario.

Figura 4. Alteramos la Propiedad Name y ShowToday del mvMiCalendario.


Ahora, a lo que vinimos, manos al código.


3.  Lanzar el Formulario "frmCalendario" cuando seleccionemos cualquier celda de la columna "E" de nuestra Hoja de trabajo (Hoja de cálculo).

Para hacer más didáctico el ejercicio, solo nos ocuparemos de la Columna "E" de nuestra Hoja de trabajo, es decir, programaremos el Formulario de manera que cuando nos ubiquemos en cualquier celda de la Columna "E" nuestro Formulario se dispare y nos permita seleccionar una fecha que posteriormente será insertada en la celda seleccionada.

Para ello, utilizaremos el Evento Worksheet_SelectionChange de la Hoja1.

¿Cómo se hace eso? En la Ventana del Explorador de proyectos del Editor de VBA, seleccionamos la Hoja1, a continuación damos Click derecho para mostrar el menú contextual, y seleccionamos la Opción Ver código. Damos Click en él. Ver Figura 5.

Si ha hecho esto correctamente, se desplegara la ventana de código correspondiente a la Hoja1 (Es decir, la que corresponde a la primera Hoja de trabajo).
Ahora nos ubicamos dentro de dicha ventana, y hacemos Click en la primera Lista desplegable ubicada en la parte superior de dicha ventana, es decir, la que lleva el nombre de General, como vemos, solo aparecen dos elementos, (General) y Worksheet, este último se refiere al Objeto de la Hoja de trabajo el cual referencia a la Hoja1, si hacemos Click en él se cargara automáticamente el evento por default asociado a la Hoja1, el cual corresponde a (Worksheet_SelectionChange). Ver Figura 6.

Dentro de estas dos líneas de código que aparecieron nuevas, y que corresponden al Evento (Worksheet_SelectionChange), cuya ejecución se da cuando realizamos un movimiento de celda en la Hoja1, o dicho de una mejor manera, cada vez que ocurre un cambio de selección en las celdas, el evento es ejecutado.

Escribimos el siguiente código:

Option Explicit 'Permite declarar variables obligatoriamente

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If ActiveCell.Column = 5 Then
        frmCalendario.Show
    End If
End Sub

Ver Figura 7.


Figura 5. Menú contextual que muestra la opción Ver código.


Figura 6. Cargamos el Evento por default que corresponde a una Hoja de trabajo.


Figura 7. Código para lanzar el Formulario cuando se seleccione una celda de la Columna "E".


Figura 8. Si seleccionamos una celda de la Columna "E" se despliega el Formulario con el calendario.


Por seguridad, salvamos el proyecto y continuamos…



4.    Ahora pasaremos el valor que elegimos en el calendario, a la celda.

Este paso comprende la programación del Evento (mvMiCalendario_DateClick) asociado por default al Objeto mvMiCalendario, el cual corresponde a un Evento del control MonthView insertado en el Formulario.

Para ello, damos Click derecho sobre el Objeto mvMiCalendario insertado en el Formulario, esto con el fin de desplegar el menú contextual del cual elegiremos la opción Ver código, hacemos Click para ver la Ventana de código. Ver Figura 9.

Si hacemos todo correctamente, entonces se cargara la Ventana de código correspondiente, y además de eso se cargara automáticamente el Evento (mvMiCalendario_DateClick) que se asocia por default al Objeto mvMiCalendario. Ver Figura 10.

Dentro de estas dos líneas de código que aparecieron nuevas, y que corresponden al Evento (mvMiCalendario_DateClick), cuya ejecución se da cuando realizamos un Click en alguna fecha del calendario, o dicho de una mejor manera, cada vez que hacemos Click en una fecha, el evento es ejecutado.

Escribimos el siguiente código:

Option Explicit 'Permite declarar variables obligatoriamente

Private Sub mvMiCalendario_DateClick(ByVal DateClicked As Date)
    ActiveCell.Value = DateClicked
    Unload frmCalendario
End Sub

Ver Figura 11.


Figura 9. Menú contextual que muestra la opción Ver código del objeto mvMiCalendario.

Figura 10. Ventana de código del Objeto mvMiCalendario y Evento cargado por default.

Figura 11. Código para pasar el valor de fecha del calendario a la celda activa o seleccionada.

Figura 12. Al hacer Click en una fecha del calendario esta se carga en la celda activa o seleccionada.

Figura 12. Al hacer Click en una fecha del calendario esta se carga en la celda activa o seleccionada.


Salvamos el proyecto y continuamos…



5. Hacemos aparecer el Formulario (frmCalendario) junto a la celda de la Columna "E" que seleccionemos.

Para hacer aparecer el Formulario (frmCalendario) al lado de la celda que activemos o seleccionemos, es necesario invocar al Evento UserForm_Activate del Formulario.

Para ello, seleccionamos de la lista desplegable que se encuentra en la parte superior de la Ventana de código del paso anterior (Literal 4), el elemento UserForm, vemos como se inserta el Evento por default para el Formulario, llamado (UserForm_Click). Ver Figura 13.

Como este Evento no nos sirve para el objetivo al cual queremos llegar, debemos cambiar o invocar al Evento UserForm_Activate. Para ello debemos hacer Click en la segunda lista desplegable que aparece en la parte superior de la Ventana de código y hacer Click en el elemento Activate, vemos como aparece el evento antes mencionado. Ver Figura 14.

En este Evento, escribimos el siguiente código:

Option Explicit 'Permite declarar variables obligatoriamente

Private Sub UserForm_Activate()
    With frmCalendario
        .Left = ActiveCell.Left + ActiveCell.Width + 25
        .Top = ActiveCell.Top + 75
    End With
End Sub


Ver Figura 15.


Figura 13. Seleccionamos el Objeto UserForm y se carga el Evento por defecto asociado a este Objeto.

Figura 14. Selección del elemento Activate de la segunda lista desplegable de la Ventana de código.


Figura 15. Código para mostrar el Formulario junto a la celda seleccionada de la columna "E".

Figura 16. El Formulario con el Calendario aparece justo al borde derecho de la celda seleccionada y además al hacer Click en el, se inserta la Fecha del calendario.


Figura 16. El Formulario con el Calendario aparece justo al borde derecho de la celda seleccionada y además al hacer Click en el, se inserta la Fecha del calendario.

Es necesario aclarar que para desplazarse por los años, simplemente basta con hacer un Click sobre el año que aparece en el calendario, con lo cual nos aparecen unas flechas de desplazamiento donde podemos aumentar, disminuir o desplazarnos por los años para seleccionar la fecha que más nos convenga.


Espero este manual aclare sus dudas sobre el uso del control MonthView para el manejo de fechas en MS Excel 2010.


Click Aquí para obtener el artículo en .pdf
Click Aquí para obtener el archivo de Excel

¡Saludos!

34 comentarios:

  1. se puede configurar tambien la hora

    ResponderEliminar
    Respuestas
    1. Estimado, la hora si es posible colocarla, tocaría modificar un poco el código y sacarla del mismo ordenador. Esto se haría con la función Time (Función). Lee la ayuda el VBA y solo concatenando los dos códigos es posible hacerlo.

      Saludos!

      Eliminar
  2. Hola JARMONCADA, cómo estás? Primero que todo, muchas gracias por tan útil post. Tengo una planilla que estoy automatizando y esta información me ha sido de mucha utilidad. Sin embargo, tengo una consulta. La planilla deben usarla muchas personas. Yo la hice en mi PC, con Excel 2007. Sin embargo, al copiar en los computadores de las otras personas, la planilla se cae, porque Excel (también 2007) no encuentra el control MonthView. Yo abrí el editor de VBA del Pc de un compañero y no encontré el control en la lista de controles adicionales. ¿Qué puedo hacer?

    Agradezco muchísimo tu ayuda.

    Tavo

    ResponderEliminar
    Respuestas
    1. Estimado, el control MonthView es nativo de Excel 2010 y algunas versiones de Excel 2007, como la Ultimate...

      Para eso, tienes que bajarte el control de internet e instalarlo en cada PC al cual quieres que corra tu planilla. Es la única manera, o la otra es cambiar el Office a 2010...

      Saludos.

      Eliminar
  3. Hola JARMONCADA, espero que estés muy bien, excelente artículo, muchas gracias por compartir tu conocimiento, después de ejecutar todas tus indicaciones y de verificar tu archivo, observo que aún cuando se implementa la última parte del código para lograr que el calendario aparezca junto a la celda activa no siempre ocurre esto (puedes probar con la celda E28 o E35 te consulto: a ti te funciona para bien para todas las celdas? Es algo de mi PC o Excel 2010? Una vez MUCHAS GRACIAS...

    ResponderEliminar
    Respuestas
    1. Estimado,

      He probado nuevamente el código en mi archivo y funciona a la perfección, verifica que todo está como lo he expuesto en el articulo.

      Saludos.

      Eliminar
  4. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  5. Hola, muy buen aporte, pero me puedes ayudar, es que ya he echo todos estos pasos, pero mi pregunta es, como hago para que si cierro el libro de excel y en otro momento que lo necesite lo abra se ejecute lo que hice con anterioridad. Porque no me guarda lo que hice, que debo hacer para se ejecute. Mejor dicho como salvo mi proyecto. Por favor necesito ayuda. Mil gracias.

    ResponderEliminar
    Respuestas
    1. La verdad, solo con guardar el Archivo (Proyecto) el quedará guardado en tu disco o unidad seleccionada.

      Intenta usar el comando Ctrl+G

      Saludos y espero te funcione.

      Eliminar
  6. Ayuda por favor, el ejemplo me sirve muy bien para un formulario que estoy realizando pero sólo quiero que me aparezca el formulario al dar clic en una celda en específico.

    Agradezco su ayuda

    ResponderEliminar
    Respuestas
    1. Estimado(a), eso se puede configurar desde el evento de la hoja de trabajo (Worksheet_SelectionChange) donde quiere que aparezca el calendario.

      Es decir, si desea que un Formulario (frmCalendario) aparezca al pasar o hacer Click en la celda D9 por ejemplo, entonces el código genérico podría ser algo así:

      Private Sub Worksheet_SelectionChange(ByVal Target As Range)
      If ActiveCell.Address = "$D$9" Then
      frmCalendario.Show
      End If
      End Sub

      De cualquier modo, si programa el evento de esa manera, debe entender que pasar a la celda activa con el teclado o hacer click en esa celda, ejecutara el procedimiento completo.

      Sin embargo debe entender que, cada vez que haga un movimiento en esa hoja, el evento se correrá, pero la única diferencia es que el procedimiento no se ejecuta completo, ya que la condición no se cumple.

      Saludos.

      Eliminar
  7. HOla me gusta mucho programar y me parecio muy bueno tu aporte te quería consultar como podemos darle un rango al calendario asi como que empieza a correr abajo de un titula de una columna para poner fechas no se si me entiendes pero darle un rango de columna ejemplo solo a cinco celdas de la columna

    Saludos Desde Chile

    ResponderEliminar
    Respuestas
    1. Estimado(a), la verdad que no le comprendo lo que quiere comunicarme, puede ser mas especifico.

      Saludos.

      Eliminar
  8. Porque el calendario se abre en la columna E,
    no hay un rango en especifico, yo necesito abrir el calendario
    en unas pocas celdas seleccionadas de una columna como podemos hacer eso?

    ResponderEliminar
    Respuestas
    1. Mas arriba de esta respuesta hay una pregunta similar de otro usuario, la cual respondí con un fragmento de código que da solución a su problema.

      Por favor, revise...

      Saludos.

      Eliminar
  9. Muy bueno tu aporte. Solo te quería comentarte que si elegís la celda E35 o E40 por ejemplo el formulario no aparece en pantalla, ya que se va corriendo para abajo debido a que cuando se activa el valor que devuelve para el .Top es demasiado alto. Si lo probas te vas a dar cuenta, o si tenes mucha resolución de pantalla proba en una el E90 por ejemplo.
    Gracias nuevamente por tu aporte

    ResponderEliminar
    Respuestas
    1. Si claro, eso lo había contemplado, la idea era no llenar de código innecesario el modulo.

      Aunque tu sugerencia es bastante valida, la única solución que le veo, es jugar con la Propiedad "Top" del Userform.

      Saludos y gracias por el concejo.

      Eliminar
  10. Hola master excelente pagina la empezare a recomendar a mis amigos.
    Podemos ver esta aplicación de calendario en hoja de registros tienes algunas que nos puedas compartir a todo el publico de esta pagina

    saludos campeón

    el estudiante

    ResponderEliminar
    Respuestas
    1. De momento no tengo algo parecido...

      Pero en algunos días, publicare un vídeo sobre el uso de calendarios en UserForm. Este hará parte del curso: Programación del Excel con VBA.

      Saludos.

      Eliminar
  11. Chaval que aplicación esta la pude probar solo que me arroja un error mientras mayor es la celda se empieza a bajar el calendario pero esta requetecontrabuenaaaa la aplicación no había visto una macros asi espero puedas reforzar este código
    por que no se como hago para que no se baje el calendario cuando voi avanzando con las celdasssss
    jarmoncada excelente pagina felicitacionesss


    titan!

    ResponderEliminar
    Respuestas
    1. Para que el UserForm que despliega el calendario baje, es necesario jugar con el objeto Window y las propiedades Top y Left del UserForm.

      No creo que sea muy complejo realizar los cambios. En unos días estaré publicando por el canal de YouTube un vídeo que hace parte del Curso: Programación del Excel con VBA.
      En el trabajaremos con el control MonthView, pero aplicado a un Formulario.

      Saludos.

      Eliminar
  12. hola, oye y para que el calendario solo sea seleccionable en un rango de celdas y no en toda la columna?

    ResponderEliminar
  13. oye y como le hago para que el calendario este disponible solo en un rango especifico? ejemplo: E8:E250

    ResponderEliminar
  14. Excelente articulo ya lo he probado en un formulario y funciona a la perfecccion pero tengo una duda como podria hacer para que el calendario me muestre el mes anterior al de la fecha actual????

    ResponderEliminar
    Respuestas
    1. Modificando su propiedad "Value", de esta manera usted puede controlar en que mes salta o se muestra el Calendario.

      Como medio para saber la fecha, utilice la función interna de VBA "Date", para asignar una fecha al control.

      Saludos.

      Eliminar
  15. Excelente Tema y muy bien explicado pero tengo una duda como podria hacer para que el calendario muestre el mes anterior a la fecha actual????

    ResponderEliminar
  16. Me sale un error de automatización.. como puedo arreglarlo

    ResponderEliminar
  17. Hola qué tal, tengo un problema ,espero contar con tu pronta ayuda:
    Coloqué el control en un formulario, guardo la fecha elegida en un textbox, sin embargoal querer tomarla me cambia el formato, ya intenté de todo con los formatos. Ejemplo. tecleo 04-10-2014 y me coloca 10-04-2014 y no puedo manipularlas, que es lo que puedo hacer?

    ResponderEliminar
    Respuestas
    1. Le recomiendo utilice, las funciones: Day, Month, Year para extraer cada elemento de la fecha y luego los una con DateSerial.

      Saludos.

      Eliminar
  18. Ayuda!! puedo hacer el calendario perfectamente y guardarlo pero no puedo lograr insertarlo en una celda y que se despliegue.

    ResponderEliminar
  19. Hola, muchas gracias por el tutorial ya que está super explicado, mi dude es para activar la selección multiple que tendría que hacer?

    ResponderEliminar
  20. Hola que tal, quiero hacer esto pero solo me aparece la opción de calendar control y no puedo activar la de MonthView, como le hago?? :(

    ResponderEliminar
  21. urgente .....
    Realice todo y salió bien ... pero necesito repetir la misma acción para la celda de al lado, al realizar nuevamente los pasos me da el siguiente error: señala que la siguiente expresión no puede se igual para ambas celdas
    Private Sub Worksheet_SelectionChange(ByVal Target As Range)

    ResponderEliminar

Recuerde, los comentarios a las publicaciones de este Blog deben ser constructivos, con el fin de enriquecer el conocimiento acerca de un tema especifico. Gracias por su comprensión.