Una alternativa al control Calendario en Excel 2010 – Monthview

lunes, enero 21, 2013

Como mencionamos en el pasado el control Calendar (mscal.ocx) fue removido del paquete Office 2010. Esto genera problemas en aplicaciones y modelos de Excel que fueron desarrollados en versiones anteriores y queremos usarla en Excel 2010.

En la nota mencionada sugerimos tres alternativas posibles: usar el Data Picker, el complemento desarrollado por Sam Radakovitz o descargar e instalar el control. Esta última alternativa implica tener que registrar el control para poder usarlo. El problema con esta última solución es que no podemos registrar el control en Windows 8.

Para los que, como a mí, no les gusta el Data Picker, existe la posibilidad de usar el control Monthview (para las versiones 2007 y 2010 de Excel).

¿Cuándo queremos usar el control? Cuando necesitamos asegurarnos que el usuario ingrese fechas en el rango y en el formato necesarios, librándolo al mismo tiempo de tener que ingresar los separadores (”/” o “-“) de la fecha.

En esta nota mostraré como implementar un modelo sencillo: al elegir una celda determinada aparece el calendario y al elegir una fecha en él, ésta aparece en la celda y el calendario desaparece



Paso 1 – Crear un Userform

En el editor de VB (Alt+F11) creamos un userform que contendrá el control



Cambiamos la propiedad Name a “UfFecha” (no es indispensable pero es una buena práctica) y cambiamos Caption a “Elija una fecha”.

Paso 2 - Insertar el control Monthview

Apuntamos al cuadro ToolBox y abrimos el menú contextual con un clic en el botón derecho del mouse



Elegimos al opción Aditional Controls y marcamos el Microsoft Monthview Control



Este aparecerá ahora en la parte inferior del cuadro ToolBox. Con un clic lo seleccionamos y lo insertamos en el Userform



Paso 3 – Definiciones del control

Al seleccionar el control podemos ver el cuadro de propiedades en el editor. Esto nos permite definir su apariencia y comportamiento. Por ejemplo, definimos la propiedad ShowTodat como True, de manera que al abrirse el control muestre la fecha corriente.



Paso 4 – Códigos de los controles.

Ahora necesitamos escribir los códigos que manejen el uso del control. En nuestro modelo queremos que cuando el usuario seleccione la celda C3 (hemos creado un nombre definido que se refiere a la celda: “clFecha”) aparezca el calendario. Esto lo hacemos usando el evento Worksheet_SelectionChange de la hoja

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

    If Union(Target, Range("clFecha")).Address = Range("clFecha").Address Then
        ufFecha.Show
    End If

End Sub


El código lo ponemos en el módulo de la hoja (abrimos el módulo de la hoja con la opción Ver Código del menú contextual que se abre al hacer clic derecho en la pestaña de la hoja o con un doble clic sobre el icono de la hoja en el editor de Vb)



Ahora necesitamos un código para pasar el valor elegido en el calendario a la celda

Private Sub MonthView1_DateClick(ByVal DateClicked As Date)
    ActiveCell.Value = DateClicked
    Unload ufFecha
End Sub


Este código va en el módulo del Userform que se abre haciendo un doble clic en el Userform (o apretando Ctrl+Tab hasta llegar al módulo)

Para que el control aparezca junto a la celda de la fecha y no en el centro de la hoja, agregamos el evento UserForm_Activate

Private Sub UserForm_Activate()
    With Me
        .Left = ActiveCell.Left + ActiveCell.Width + 25
        .Top = ActiveCell.Top + 150
    End With
End Sub


El modulo del Userform se verá así



Un tip para el final: si hacemos unn clic sobrel el nombre del mes en el control aparecerán unas flechas que nos permiten saltar de año en año



El archivo con el ejemplo puede descargarse aquí.

29 comments:

Vic 22 enero, 2013 00:34  

Magaso!nuevamente otro Post de Genial!

Anónimo,  25 enero, 2013 20:26  

Mi estimado Jorge esto es muy bueno, podemos tambien cambiar de año, pero NO podemos cambiar de mes para seleccionar el dia que necesitamos. Estoy en lo correcto?

Jorge L. Dunkelman 26 enero, 2013 09:02  

Si se puede. Los meses se cambian con las flechas (triángulos) a los lados de la casilla mes/año.

Anónimo,  12 febrero, 2013 19:19  

Gracias Jorge,
Una única cuestión:
¿Si queremos que el calendario aparezca en todas las celdas de una misma columna cómo deberiamos modificar el código actual?.
Gracias por adelantado,
Héctor.

Jorge L. Dunkelman 13 febrero, 2013 07:27  

Hola Héctor,
en el evento hay que cambiar la referencia. Por ejemplo, podemos cambiar el rango al que se refiere el nombre definido "clFecha" a toda la columna o cambiar la sentencia del evento a

If Target.Column = 3 Then...

Esta hace que el evento se dispare cada vez que se elija una celda de la columna C.

ignacio javier caro aguilera 04 marzo, 2013 18:10  

no me aparece el microsoft monthview 6.0 como lo agrego en excel 2010

Jorge L. Dunkelman 05 marzo, 2013 07:06  

Siguiendo las mismas instrucciones que pongo en la nota anterior sobre el uso de calendario. El archivo del control es MSCOMCT2.OCX y lo puedes descargar aquí

Unknown 10 marzo, 2013 21:22  

Es posible poder validar la fecha en el calendario, que este no sea menor a cuerta fecha por ejempl

Jorge L. Dunkelman 11 marzo, 2013 07:17  

Se puede hacer estableciendo los valores de las porpiedades MaxDate y MinDate del control.

fofo 11 marzo, 2013 17:02  

hola he visto tu tutorial muy bueno!!

me gustaria saber si es posible que teniendo dos userform cada uno con un textbox llame al control que esta en un userform independiente e inserte la fecha al textbox desde donde se activo por ejemplo

en userform1 esta el textbox1 llama al control e inserta la fecha
pero si desde el userform2 que esta un textbox1 tambien llama al mismo control e inserta la fecha es posible?como se haria?

Jorge L. Dunkelman 11 marzo, 2013 18:00  

Fofo, no me ued clara tu consulta. Veamos, el TextBox está siempre en una UserForm y no al revés.
Ahora, el calendario es un control que está en un userform, así que tendrías un calendario en Userform1 y otro en Userform2. Lo cual no es inngpun problema ya que todo lo que hacemos con el calendario es determinar la fecha.
Si querés, podés crear un userform que contiene el control calendario y éste es llamado por los otros dos userform (pero me parece un complicaciónn innecesaria).

Luis Felipe Londoño 12 marzo, 2013 23:03  

Excelente tutorial,

Tengo una pregunta, si quiero que el calendario aparezca en un rango de celdas específico, como se modifica el código?

Muchas gracias!

Jorge L. Dunkelman 13 marzo, 2013 07:06  

Hola Luis,
fijate en la nota donde muestro el código del evento Worksheet_SelectionChange.
La sentencia
Union(Target, Range("clFecha")).Address = Range("clFecha").Address
determina las celda que al ser activadas disparan el código. El rango Range("clFecha") se refiere al rango definido en el nombre clFecha. En nuestro ejemplo este nombre se refiere a una celda, pero podés definirlo de manera que se refiera a una colección de celdas. También podés poner el rango de celdas en forma explícita, opr ejemplo:

Union(Target, Range("A2:A100")).Address = Range("A2:A100").Address

Anónimo,  16 abril, 2013 22:20  

no me funsiona el data pic ni el mont view mi office es 2010 me dice element no found

que hago

Jorge Dunkelman 17 abril, 2013 16:28  

Tienes que descargar el archivo del control e instalarlo como muestro en esta nota

MAPER 16 mayo, 2013 02:01  

Buen día, esto no se aplica a Excel 2013?
Pues estuve probando y no esta el control ActiveX para habilitarlo.

Jorge Dunkelman 16 mayo, 2013 06:54  

esta nota explico cómo usar los controles ActiveX en Excel 2003.

Adler 20 junio, 2013 21:27  

Excelente, muchas gracias

JORGE SANTIN 13 julio, 2013 00:41  

Buen tarde
Les solicito de su apoyo, ya que estoy aprendiendo a programar en VBA, estoy haciendo un ejercicioy en el cual estoy creando un formulario de captura de datosen donde en mi primer columna en mi editor de VBA estoy capturando una fecha, pero descubri que puedo usar en Microsoft Monthview para insertar las fechas que estoy capturando, este es mi codigo en mi modulo de trabajo

Sub Ingresarinformacion()

Dim n As Long
Hoja1.Select

n = 4

Do While (Cells(n, 1) <> Empty Or Cells(n, 2) <> Empty Or Cells(n, 3) <> Empty Or Cells(n, 4) <> Empty Or Cells(n, 5) <> Empty Or Cells(n, 6) <> Empty Or Cells(n, 7) <> Empty Or Cells(n, 8) <> Empty Or Cells(n, 9) <> Empty Or Cells(n, 10) <> Empty Or Cells(n, 11) <> Empty Or Cells(n, 12) <> Empty)
n = n + 1
Loop

If (frmingresodatos.rbtHombre.Value = True Or frmingresodatos.rbtMujer.Value = True) Then

Cells(n, 1).Value = frmingresodatos.txtFecha.Text
Cells(n, 2).Value = frmingresodatos.txtPaterno.Text
Cells(n, 3).Value = frmingresodatos.txtMaterno.Text
Cells(n, 4).Value = frmingresodatos.txtNombre.Text
Cells(n, 5).Value = frmingresodatos.txtEdad.Text
Cells(n, 6).Value = frmingresodatos.txtDia1.Text
Cells(n, 7).Value = frmingresodatos.txtTelefono.Text
Cells(n, 8).Value = frmingresodatos.txtDia2.Text
Cells(n, 9).Value = frmingresodatos.txtAvisual.Text
Cells(n, 10).Value = frmingresodatos.txtPio.Text
Cells(n, 11).Value = frmingresodatos.txtCosto.Text

If frmingresodatos.rbtHombre.Value = True Then
Cells(n, 12).Value = "Hombre"
frmingresodatos.rbtHombre.Value = False
Else
If frmingresodatos.rbtMujer.Value = True Then
Cells(n, 12).Value = "Mujer"
frmingresodatos.rbtMujer.Value = False
End If
End If

frmingresodatos.txtFecha.Text = ""
frmingresodatos.txtPaterno.Text = ""
frmingresodatos.txtMaterno.Text = ""
frmingresodatos.txtNombre.Text = ""
frmingresodatos.txtEdad.Text = ""
frmingresodatos.txtDia1.Text = ""
frmingresodatos.txtTelefono.Text = ""
frmingresodatos.txtDia2.Text = ""
frmingresodatos.txtAvisual = ""
frmingresodatos.txtPio = ""
frmingresodatos.txtCosto = ""

MsgBox "Ingresado un registro con èxito en la fila numero " & n & ".", vbInformation + vbOKOnly, "información de registro."

frmingresodatos.txtFecha.SetFocus

Else

MsgBox "Debe selecionar una opcion." & vbCrLf & "Para el trabajo actual", vbCritical + vbOKOnly, "Alerta..."

End If










End Sub
y quiero dustituir el txtFecha para poder usar el Monthview, agradezco de antemano su ayuda.

Saludos

Jorge Dunkelman 13 julio, 2013 20:18  

Tienes que crear un segundo Userform que contenga el calendario; este userform es llamado desde el primer Userform (frmingresodatos), el usuario ingresa la fecha, y esta pasa a la celda.

JORGE SANTIN 16 julio, 2013 01:29  

MUCHAS GRACIAS POR EL TIP Y LA AYUDA!!! SALUDOS

Anónimo,  28 agosto, 2013 21:12  

Un gran tutorial sin duda, lo adapte para usarlo en un UserForm y funciono genial, gracias.
Solo tengo una pregunta, como hacer para que cada que habra el calendario me aparesca el mes y la fecha actual, por que aun que lo marca con rojo, sigue abriendo con el valor que le pusiste en el mes de julio.

Jorge Dunkelman 28 agosto, 2013 22:16  

En el cpodigo del evento UserForm_Activate tienes que agregar la línea en negrita

Private Sub UserForm_Activate()
With Me
.Left = ActiveCell.Left + ActiveCell.Width + 25
.Top = ActiveCell.Top + 150
.MonthView1.Value = Date
End With
End Sub

Anónimo,  04 septiembre, 2013 00:25  

HOLAA SUPER BUENO EL POST, PERO HAY FORMA DE QUE CUANDO SE ABRA, LO HAGA EN EL MES ACTUAL

Jorge Dunkelman 04 septiembre, 2013 07:12  

Fijate en mi comentario del 28 de agosto

Anónimo,  16 enero, 2014 19:18  

Hola Jorge,

funciona perfecto pero tengo un problema. Lo tengo puesto para que me salga en toda una columna. Pero conforme voy bajando filas, la ventana del calendario se me abre cada vez mas abajo hasta terminar por desaparecer de la pantalla y no poder utilizarla. ¿Alguna solución?

Saludos y gracias.

Jorge Dunkelman 17 enero, 2014 18:21  

Te sugiero eliminar el evento UserForm_Activate y definir la propiedad StartUpPosition del Userform a "Centrar en Pantalla".
¿Qué versión de Excel estás usando?

Gisela GTH 18 marzo, 2014 18:14  

Al tratar de colocarlo en el form me da un mensaje de "no se encuentra el elemento"

Jorge Dunkelman 18 marzo, 2014 21:11  

Fijaate en mi comentario del 5 de marzo. Si no tenés el control se puede descargar e instalar.

Publicar un comentario

Seguidores

Google+ Followers

Google+ Badge

Términos Legales

  © Blogger template On The Road by Ourblogtemplates.com 2009

Back to TOP