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í.
Magaso!nuevamente otro Post de Genial!
ResponderBorrarMi 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?
ResponderBorrarSi se puede. Los meses se cambian con las flechas (triángulos) a los lados de la casilla mes/año.
ResponderBorrarGracias Jorge,
ResponderBorrarUna ú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.
Hola Héctor,
ResponderBorraren 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.
no me aparece el microsoft monthview 6.0 como lo agrego en excel 2010
ResponderBorrarSiguiendo 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í
ResponderBorrarEs posible poder validar la fecha en el calendario, que este no sea menor a cuerta fecha por ejempl
ResponderBorrarSe puede hacer estableciendo los valores de las porpiedades MaxDate y MinDate del control.
ResponderBorrarhola he visto tu tutorial muy bueno!!
ResponderBorrarme 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?
Fofo, no me ued clara tu consulta. Veamos, el TextBox está siempre en una UserForm y no al revés.
ResponderBorrarAhora, 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).
Excelente tutorial,
ResponderBorrarTengo una pregunta, si quiero que el calendario aparezca en un rango de celdas específico, como se modifica el código?
Muchas gracias!
Hola Luis,
ResponderBorrarfijate 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
no me funsiona el data pic ni el mont view mi office es 2010 me dice element no found
ResponderBorrarque hago
Tienes que descargar el archivo del control e instalarlo como muestro en esta nota
ResponderBorrarBuen día, esto no se aplica a Excel 2013?
ResponderBorrarPues estuve probando y no esta el control ActiveX para habilitarlo.
Eמ esta nota explico cómo usar los controles ActiveX en Excel 2003.
ResponderBorrarExcelente, muchas gracias
ResponderBorrarBuen tarde
ResponderBorrarLes 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
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.
ResponderBorrarMUCHAS GRACIAS POR EL TIP Y LA AYUDA!!! SALUDOS
ResponderBorrarUn gran tutorial sin duda, lo adapte para usarlo en un UserForm y funciono genial, gracias.
ResponderBorrarSolo 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.
En el cpodigo del evento UserForm_Activate tienes que agregar la línea en negrita
ResponderBorrarPrivate Sub UserForm_Activate()
With Me
.Left = ActiveCell.Left + ActiveCell.Width + 25
.Top = ActiveCell.Top + 150
.MonthView1.Value = Date
End With
End Sub
HOLAA SUPER BUENO EL POST, PERO HAY FORMA DE QUE CUANDO SE ABRA, LO HAGA EN EL MES ACTUAL
ResponderBorrarFijate en mi comentario del 28 de agosto
ResponderBorrarHola Jorge,
ResponderBorrarfunciona 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.
Te sugiero eliminar el evento UserForm_Activate y definir la propiedad StartUpPosition del Userform a "Centrar en Pantalla".
ResponderBorrar¿Qué versión de Excel estás usando?
Al tratar de colocarlo en el form me da un mensaje de "no se encuentra el elemento"
ResponderBorrarFijaate en mi comentario del 5 de marzo. Si no tenés el control se puede descargar e instalar.
ResponderBorrarbuen día, alguna sugerencia para el sig. error?
ResponderBorrar¿Cuál es el error?
ResponderBorrarHola Jorge, tengo una pregunta: en la nota anterior afirmas que este control solo se puede utilizar en la versión de 32 bits de Excel 2010, ¿Hay alguna forma de que funcione en la de 64 bits?
ResponderBorrarGracias!!
No, hasta donde dan mis conocimientos. Buscando en Google puedes encontrar alguna soluciones como ésta.
ResponderBorrarJorge Buen dia Hace mucho tiempo no compartia con usted pero ahoratengo el siguiente problema
ResponderBorrarSi puede ayudarme se lo agradeciria.
es sobre fechas
en la celda a1 digito la fecha (cualquiera),año, mes, dia,ejemplo (2015,09,30) necesito que en las celdas a5, (2015,10,31) a10,(2015,11,31), a15, (2015,12,31),a20 (2016,01,31), se continue la secuencia de fechas con el ultimo dia habil, es posible porfa ayudeme, no he podido
atentamente
Hector
Héctor,
ResponderBorrartenés que usar la función FIN.MES. EN la celda A5 usás =FIN.MES(A1,1); en la celda A10 =FIN.MES(A5,1); en la elda A15 =FIN.MES(A10,1) y así sucesivamente.
No me queda claro si te referís al último día del mes (que es lo que dá la función FIN.MES) o al último día hábil dado que el último día del mes puede ser feriado.
Hola amigos, hice todo lo que mencionan.
ResponderBorrarSi embargo me lleve una copia del archivo en un pendrive a otro pc y no hay nada de lo realizado.
Pregunto se pierde todo?
Adicional, intente realizar la operación en el otro PC y cuando intento repetir la operación, cuando hago clic en "Controladores Adicionales" no hace pasa nada.
Agradecido de antemano,
Saludos
Hola, tenés que asegurarte que el control Monthview esté instalado en el PC. Fijate en los comentarios del 04/03/2013 (de Ignacio Javier y mi respuesta).
ResponderBorrarHola, gracias por tu tutorial, me ayudó mucho, pero quisiera saber si es posible colocar en distintas celdas, por ejemplo coloco un calendario en la celda A3 y quiero colocar en la C3 y en la D3 , es posible?, espero me pueda ayudar. Gracias
ResponderBorrarHola, fijate en el paso 4. Allí definimos las celdas que al seleccionarlas aparecerá el calendario. En el ejemplo hay una única celda (definida en el nombre clFecha). Para que aparezca en otras celdas hay que cambiar la definición del nombre "clFecha" para que se refiera también a las otras celdas.
ResponderBorrarHola buen día, estoy aprendiendo y haciendo mi primer trabajo en VBA. Te cuento, debo controlar fechas de documentos, para ello inserte en Excel 3 controles DTPicker asignando que estas fechas son de EMISION, RECEPCION y PROCESO. Y quería consultar como se podría controlar las fechas que se seleccionan del calendario a fin que no existan errores. Por ejemplo:
ResponderBorrari) ninguna fecha puede ser posterior al día de hoy.
ii) PROCESO no puede ser anterior a RECEPCION.
iii) RECEPCION y PROCESO no pueden ser anteriores a EMISION
Espero me puedan aconsejar sobre el mejor modo de hacer este trabajo.
Saludos
Hola David, como estás haciendo tus primeros pasos en Vba no puedo orientarte en el marco de un comentario.
ResponderBorrarEn términos generales puedo decirte que para cada objeto con el DTPicker podés definir uno o más eventos (fijate en mis notas sobre eventos) de manera que al activarlo corra un código que controle los valores aceptables en cada entorno.
Te invito a ponerte en contacto conmigo por mail privado (fijate en el enlace Ayuda, en la parte superior de blog).
Excelente artículo. Me ha sido de gran ayuda. Que bueno tener una tutoría de este nivel y gratis!!
ResponderBorrarNO ME APARECE LA PESTAÑA TOOLBOX
ResponderBorrarEn el editor de VB, abrir el menu Tools y marcar Toolbox.
ResponderBorrar