Macro para calendario en Excel.
Scripts, Visual Basic 18 marzo 2008
¿Alguien ha pensado que crear un calendario en excel tenia que ser mas fácil?. Yo también. Aquí tenéis una macro de excel para crearos un calendario del mes que queráis y del año que queráis.
Para utilizar esta macro debéis ir a Herramientas / Macro /Editor de Visual Basic.
Menú Insertar / Modulo y pegar el texto siguiente.
Luego ya solo ejecutar la macro y te lo hace todo solo para el mes que le pongas, por ejemplo, si quieres para este mes has de poner en el InputBox "03/2008" (sin comillas).
-
Sub Crea_Calendario()
-
-
' Desprotege la hoja si tienes un calendario previo para prevenir el error.
-
ActiveSheet.Protect DrawingObjects:=False, Contents:=False, _
-
Scenarios:=False
-
'Previene el parpadeo de la ventana mientras se crea el calendario.
-
Application.ScreenUpdating = False
-
' Control de errores.
-
On Error GoTo MyErrorTrap
-
' Limpia el area a1:g14 incluyendo cualquier calendario previo.
-
Range("a1:g14").Clear
-
' Usa un InputBox para pedir el mes y año deseado y ponerlo en la variable MyInput.
-
MyInput = InputBox("Escribe el mes y el año para el calendario en formato 01/2008 ")
-
' Permite al usuario terminar la macro Cancelando el InputBox.
-
If MyInput = "" Then Exit Sub
-
' Coge el valor del día del comienzo del mes.
-
StartDay = DateValue(MyInput)
-
If Day(StartDay) <> 1 Then
-
StartDay = DateValue(Month(StartDay) & "/1/" & _
-
Year(StartDay))
-
End If
-
Range("a1").NumberFormat = "mmmm yyyy"
-
' Formatea el mes y el año.
-
With Range("a1:g1")
-
.HorizontalAlignment = xlCenterAcrossSelection
-
.VerticalAlignment = xlCenter
-
.Font.Size = 18
-
.Font.Bold = True
-
.RowHeight = 35
-
End With
-
' Formatea los días de la semana.
-
With Range("a2:g2")
-
.ColumnWidth = 18
-
.VerticalAlignment = xlCenter
-
.HorizontalAlignment = xlCenter
-
.VerticalAlignment = xlCenter
-
.Orientation = xlHorizontal
-
.Font.Size = 12
-
.Font.Bold = True
-
.RowHeight = 20
-
End With
-
' Pone los días de la semana en a2:g2.
-
Range("a2") = "Lunes"
-
Range("b2") = "Martes"
-
Range("c2") = "Miercoles"
-
Range("d2") = "Jueves"
-
Range("e2") = "Viernes"
-
Range("f2") = "Sabado"
-
Range("g2") = "Domingo"
-
' Formatea las celdas a3:g7 para los días.
-
With Range("a3:g8")
-
.HorizontalAlignment = xlRight
-
.VerticalAlignment = xlTop
-
.Font.Size = 18
-
.Font.Bold = True
-
.RowHeight = 21
-
End With
-
' Pone el mes y año indicado en la variable MyInput en "a1".
-
Range("a1").Value = Application.Text(MyInput, "mmmm yyyy")
-
' Pone la variable y coge el dia de la semana en el que el mes empieza.
-
DayofWeek = Weekday(StartDay)
-
' Separa las variables de mes y año en dos variables
-
CurYear = Year(StartDay)
-
CurMonth = Month(StartDay)
-
' Calcula el primer día del mes siguiente.
-
FinalDay = DateSerial(CurYear, CurMonth + 1, 1)
-
' Pone un "1" en la celda del primer día del mes escogido
-
Select Case DayofWeek
-
Case 1
-
Range("g3").Value = 1 ' g3 porque empieza por domingo
-
Case 2
-
Range("a3").Value = 1
-
Case 3
-
Range("b3").Value = 1
-
Case 4
-
Range("c3").Value = 1
-
Case 5
-
Range("d3").Value = 1
-
Case 6
-
Range("e3").Value = 1
-
Case 7
-
Range("f3").Value = 1
-
End Select
-
' Loop para el rango a3:g8 incrementando en 1 a partir del primer "1".
-
For Each cell In Range("a3:g8")
-
RowCell = cell.Row
-
ColCell = cell.Column
-
' Si "1" está en la primera columna.
-
If cell.Column = 1 And cell.Row = 3 Then
-
' Si NO está en la primera columna.
-
ElseIf cell.Column <> 1 Then
-
If cell.Offset(0, -1).Value>= 1 Then
-
cell.Value = cell.Offset(0, -1).Value + 1
-
' Se detiene cuando el el último dia del mes se ha colocado.
-
If cell.Value> (FinalDay - StartDay) Then
-
cell.Value = ""
-
Exit For
-
End If
-
End If
-
' Solo si la actual celda no está en fila 3 y está en la columna 1.
-
ElseIf cell.Row> 3 And cell.Column = 1 Then
-
cell.Value = cell.Offset(-1, 6).Value + 1
-
' Se detiene cuando el el último dia del mes se ha colocado.
-
If cell.Value> (FinalDay - StartDay) Then
-
cell.Value = ""
-
Exit For
-
End If
-
End If
-
Next
-
-
' Crea las celdas de entrada de datos y las formatea.
-
For x = 0 To 5
-
Range("A4").Offset(x * 2, 0).EntireRow.Insert
-
With Range("A4:G4").Offset(x * 2, 0)
-
.RowHeight = 65
-
.HorizontalAlignment = xlCenter
-
.VerticalAlignment = xlTop
-
.WrapText = True
-
.Font.Size = 10
-
.Font.Bold = False
-
' Desbloquea estas celdas para insertar texto después porque
-
' la hoja estará protegida.
-
.Locked = False
-
End With
-
' Crea el borde alrededor de los días.
-
With Range("A3").Offset(x * 2, 0).Resize(2, _
-
7).Borders(xlLeft)
-
.Weight = xlThick
-
.ColorIndex = xlAutomatic
-
End With
-
-
With Range("A3").Offset(x * 2, 0).Resize(2, _
-
7).Borders(xlRight)
-
.Weight = xlThick
-
.ColorIndex = xlAutomatic
-
End With
-
Range("A3").Offset(x * 2, 0).Resize(2, 7).BorderAround _
-
Weight:=xlThick, ColorIndex:=xlAutomatic
-
Next
-
If Range("A13").Value = "" Then Range("A13").Offset(0, 0) _
-
.Resize(2, 8).EntireRow.Delete
-
' Elimina las lineas del grid.
-
ActiveWindow.DisplayGridlines = False
-
' Protege la hoja para prevenir la sobre escritura de los días.
-
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, _
-
Scenarios:=True
-
' Redimensiona la ventana para ver todo el calendario.
-
ActiveWindow.WindowState = xlMaximized
-
ActiveWindow.ScrollRow = 1
-
-
' Permitimos a la ventana reescribirse para ver el calendario.
-
Application.ScreenUpdating = True
-
' Si no ha ocurrido ningún error aquí acaba la Macro
-
Exit Sub
-
' Si ha dado error al introducir los datos te muestra un mensaje y te
-
' muestra de nuevo el InputBox para que vuelvas a introducir la fecha.
-
MyErrorTrap:
-
MsgBox "No has introducido el mes y el año correctamente." _
-
& Chr(13) & "Escribe el mes correctamente" _
-
& Chr(13) & "y 4 digitos para el año"
-
MyInput = InputBox("Escribe el mes y el año correctamente para el calendario")
-
If MyInput = "" Then Exit Sub
-
Resume
-
End Sub
Si hemos creado una macro en excel y la quitamos al volver a abrir el documento sigue apareciendo una molesta ventana que dice que el documento tiene macros cuando no existe ninguna macro:
Menu Herramientas, Macro, Editor Visual Basic, menú ver explorador de proyectos, botón derecho sobre cada modulo y quitar.
Si nos preguntar guardar y no lo queremos le decimos que no.
La próxima vez que abramos el documento ya no nos preguntará si queremos habilitar los macros.
Vota este artículo:
Posts anterior y posterior:
Posts Relacionados:
- Previo: « Leer y escribir de un archivo INI. Visual Basic
- Siguiente: Extraer msi del Java Runtime Environment »

marzo 27th, 2008 a las 4:23 pm
Me parece muy interesante este planteamiento, ahora estaba pensado en la construccion de un calendario donde se permita porgramar valores en cada dia el cual genere un cuadro de resumen.... por ejemplo de reservaciones..
octubre 1st, 2008 a las 10:46 am
David,
Muchas gracias, la macro está muy bien y me ha sido de mucha utilidad.
Un saludo
octubre 13th, 2008 a las 2:31 pm
Fantástica Macro

Enhorabuena, eres un crack.
Muy útil.
octubre 15th, 2008 a las 6:53 am
Muy buena ...
octubre 17th, 2008 a las 5:47 am
Buenas noches. Espero alguien me pueda ayudar con algo que quiero saber si se puede o no hacer en excel.
necesito bloquear una celda pero que se bloquee automaticamente una vez que hayan puesto informacion en ella, o bien que se bloquee automaticamente despues de una fecha determinada. essto es porque manejo un reporte de citas para mis ejecutivos de venta y les pido cierta informacion y lo que quiero es evitar que me cambien informacion una vez que ya la ingresaron. esto para llevar un control. les agradeceria me pudieran contestar a mi e-mail tambien. julio.andrade@nextel.com.mx
gracias por su ayuda.
octubre 17th, 2008 a las 12:49 pm
Julio, tienes que utilizar un evento que se llama Change.
Por ejemplo, asumimos que las celdas de la columna B están desbloqueadas y la hoja está protegida con con la contraseña "perrea-perrea", cuando pongas un dato en la celda se volverá bloqueada.
octubre 26th, 2008 a las 2:06 am
Muchas gracias por la Macro del bloqueo de celda me ayudo mucho.
ahora requiero nuevamente de su apoyo y quiero ver si me pueden ayudar y me digan si alguna macro que sea un contador, es decir, que me cuente las veces que se haga un cambio en una celda y el contador este en otra celda.
por ejemplo si pongo la fecha de hoy en una celda en la celda de la derecha me ponga 1 y si mañana cambio la fecha me cuente 2 y asi con cada movimiento.
Gracias por su ayuda.
Saludos y los felicito por la pagina, es de mucha ayuda.
octubre 26th, 2008 a las 8:10 pm
Julio, aqui tienes el codigo. Pégalo en un módulo.
octubre 26th, 2008 a las 10:17 pm
Gracias David. me han servido mucho estos macros.
octubre 26th, 2008 a las 11:27 pm
Gracias por el codigo, he estado haciendo pruebas pero no me respeta la celda que pongo ( en este caso del ejemplo es A1, entonces cuando hago un cambio en cualquier celda de cualquier columna tambien me lo cuenta como cambio.
a que se debe eso?
octubre 28th, 2008 a las 12:07 am
Hola Julio, algo no has hecho bien.
If Target = Range("A1") Then
Cells(2, 2) = Cells(2, 2) + 1
End If
Hace que solo sume 1 en la celda B2 si la celda que ha sufrido el cambio es la A1.
noviembre 3rd, 2008 a las 11:14 pm
POR fa necesito las plantillas o macros financieras ejmplo calculo de flujo neto de fondos
ME ESTA OCASIONANDO PROBLEMAS
noviembre 3rd, 2008 a las 11:42 pm
CHRISTIAN, dirígete al sitio adecuado. Yo, de formulas financieras las justitas.
noviembre 4th, 2008 a las 8:46 pm
David, Muchas gracias por la macro.
Esta EXCELente. Hacia tiempo que buscaba una macro como esta. Por el momento se me ocurre una opcion en que se pueda elegir entre crear el calendario de un mes o el de todo un año. Yo apenas empiezo a aprender VBA pero supongo que basta con agregar un ciclo. Otra mas es que el calendario se cree a partir de la celda activa y no de la A1. Y por ultimo, la opcion de que inicie la semana en lunes o en domingo.
Yo intentare hacer las modificaciones pero ahi si modificas el codigo, me avisas, si? Jejeje
PD. Saludos desde México!
noviembre 18th, 2008 a las 9:28 am
Buenos dias:
En primer lugar muchas gracias por esta macro, me parece muy buena.
Me gustaria preguntar si es posible transformar una tabla por ejemplo de Noviembre 2008 a Noviembre 2009 conservando los datos que haya metido, por ejemplo cumpleaños, aniversarios, fiestas, etc..
Gracias.
noviembre 19th, 2008 a las 11:09 pm
Efectivamente Ulises34 con el VBA y tiempo todo es posible. Dale un poquito y te invito a que nos cuentes.
diciembre 15th, 2008 a las 6:14 pm
¿Es posible calcular cuántos lunes y miércoles tiene un periodo de días laborables, por ejemplo: del 1 de septiembre al 31 de diciembre?
diciembre 16th, 2008 a las 5:45 pm
Bueno Ricardo, te has comido poco la oreja. Se aprende probando.
Function nlunes(r1 As Range, r2 As Range) As Integer
For i = r1.Value To r2.Value
If Weekday(i) = 2 Then
nlunes = nlunes + 1
End If
Next
End Function
Si A12 contiene 6/12/2008 y A13 contiene 16/12/2008
Entonces, nlunes(A12,A13) te devolverá 2
diciembre 16th, 2008 a las 6:06 pm
Muchas gracias, David. No te creas que no he probado. He revisado múltiples foros y he hecho pruebas con la función DIAS.LAB de Excel. Pero no me salía el resultado esperado. Supondrás ahora que no tengo ni idea de programación.Sólo uso Excel y a un nivel poco avanzado.
Cuando vi tu Blog pensé que en él estaba la solución.
Un trabajador de mi empresa cobra unos complementos semestrales por días trabajados y resulta que sólo trabaja los lunes y los miércoles: de ahí mi pregunta. Hasta ahora lo hacía calendario en ristre y contando.
diciembre 23rd, 2008 a las 4:08 pm
Hola.
Necesito saber si existe la posibilidad de utilizar de forma automatica en Excel el número del día del calendario de windows para dividirlo por un monto y así obtener el promedio diario actualizado todo el tiempo.
Por ejemplo: tengo acumulado en mi hoja de Excel $100 al dia 10, el promedio diario sería: $10. Quisiera saber si esto puede hacerse automaticamente y que sea el Excel mismo el que divida el monto acumulado según el dia del mes que sea.
Muchas gracias.
diciembre 23rd, 2008 a las 10:26 pm
Efectivamente Hernan,
con el Excel es posible casi todo. La función para obtener el día es =AHORA().
Debes sumar todas las celdas de los días del mes y dividirlo entre la diferencia en días entre el día de inicio y el día de hoy.
Supongamos que la celda D11 contiene la fecha inicial y la celda E11 tiene la función =AHORA() que nos da la fecha del sistema Windows.
La formula para obtener la diferencia en días entre ambas fechas sería:
=DIAS360(D11;E11)
Si sigo te lo dejo hecho. Dale un poco al coco.
julio 17th, 2009 a las 7:04 pm
hola me podrian ayudar, estoy haciendo un pagare y ocupo el macro donde el pagare lo llene automatica mente incremente los dias en donde seria 15 dias me podrian ayudar
julio 23rd, 2009 a las 10:51 am
Excelente macro David, lo unico que yo al ser novato en esto, me gustaria poder volver a dejar la hoja en su posicion inicial ejecutando un comando, es decir habilitar el calendario, para hacer consultas, y deshabilitarlo dejando las celdas en su tamaño y posicion inicial. puede ser???
un saludo
enero 13th, 2010 a las 2:40 pm
Yo ejecuto pero me dice que las macros están deshabilitadas...
No tengo mucha idea de VB
enero 13th, 2010 a las 6:09 pm
Julio pues habilitalas en el excel.
La tecla F1 es la ayuda.
marzo 2nd, 2010 a las 9:58 am
Muy buena tu página, excelente de verdad
abril 26th, 2010 a las 12:48 am
Muy buena tu pagina te escribo a ver si me puedes ayudar. en la elaboracion de una macros de excel que consiste en comparar un documento excel con otro, hacer un match y extraer lo que esta escrito en las celdas del segundo documento y generar uno nuevo donde me pegue esa informacion o generarlo en el mismo excel donde se ponga lo que yo quiero comparar con el segundo excel.
A mis manos llego una macros la cual compara con otro segundo documento pero me escribe en las celdas del documento donde se ejecuta la macros encontrado y no encontrado quiciera que me escribiera lo q encuentra y me extraiga y pegue en ese mismo documento las dos celdas mas que le siguen a la que compara hacia la derecha... me seria de gran utilidad tu ayuda pues no tengo muchos conocimientos de programacion... muchas gracias
abril 26th, 2010 a las 12:51 am
escribo el codigo de la macros que tengo la cual te comente arriba como modificarla para que haga lo que te plantie muy agradecido..
Sub BUSCAR2()
While ActiveCell.Value ""
Windows("BUSCADOR2.xls").Activate
FENUEVA = ActiveCell.Value
Windows("TEMPLATE.xls").Activate
Set FEVIEJA = Cells.Find(What:=FENUEVA, After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False)
If Not (FEVIEJA Is Nothing) Then
Windows("BUSCADOR2.xls").Activate
ActiveCell.Offset(0, 1).Range("A1").Select
ActiveCell.FormulaR1C1 = "ENCONTRADA. Esta facilidad está en el archivo INVENTARIO"
ActiveCell.Offset(1, -1).Range("A1").Select
Else
Windows("BUSCADOR2.xls").Activate
ActiveCell.Offset(0, 1).Range("A1").Select
ActiveCell.FormulaR1C1 = "NO ENCONTRADA. Esta facilidad no está en el archivo INVENTARIO"
ActiveCell.Offset(1, -1).Range("A1").Select
End If
Wend
End Sub
mayo 26th, 2010 a las 5:29 pm
Hola como estan me encanto la macro pero podemos hacer que genere todo el año,,, ademas me gustaria que las cosas que se anoten se despliege una alerta para ese dia avisando de la tarea anotada.
junio 12th, 2010 a las 11:45 pm
Hola, por favor ayudenme necesito crear un calendario donde le de una fecha inicial de apertura y automaticamente me arroje la fecha de cierre y las etapas previas respetando los sabados y domingos (solo días efectivos) gracias
julio 9th, 2010 a las 7:50 pm
Hola, excelente página! Quisiera saber cómo hacer para insertar un Grid en un formulario de una Macro? Es que el control Grid que se puede agregar, da un error al insertarlo al Form... Muchas gracias!
noviembre 26th, 2010 a las 1:21 am
Quisiera saber si se puede hacer lo sig. en excel; una persona captura una lista de cobro con los datos del cliente al que le fue a cobrar y obvio el saldo de lo que debe...en ocasiones el cliente me programa el pago para determinado dia, entonces quiero que los datos del cliente se pasen a la hoja de esa fecha, (tengo un libro con los 31 dias del mes) asi que si un cliente me dice que me paga el dia 15 de nov. quiero que los datos de ese cliente se copien en la hoja que tiene esa fecha, del dia 15, se podrá?
noviembre 30th, 2010 a las 11:55 am
pues la he ejecutado en un excel 2003, y me ha puesto un area azul a la izquierda que no veo en el código cómo quitarla...
me tapa las celdas y es un lío curioso...
enero 20th, 2011 a las 5:50 pm
David, me ha gustado mucho tu página. Podrías ayudarme con lo siguiente?... En una macro si colocas el comando
ActiveCell.Next.Select
Te mueves en la hoja de Excel de la celda activa en la que te encuentras a la siguiente celda a la derecha.
Me puedes decir como es el comando para moverte de la celda actual a la celda superior y a la celda inferior, por favor?
Te agradezco mucho.
enero 21st, 2011 a las 2:26 am
Utiliza ActiveCell.Offset()
Para moverse una posición hacia arriba:
ActiveCell.Offset(-1,0).Select
Para bajar una fila:
ActiveCell.Offset(1,0).Select
abril 4th, 2011 a las 4:35 am
Hola, quisiera ver la posibilidad que me pueda ayudar, estoy tratando de insertar un calendario en una celda de Excel, me voy a programador >Mas Controles> pero no tengo control calndar 12.0 o el 11.0, lo unico que tengo es Microsoft Date and Time Picker Control, Version 6.0 pero solo me aparece la fecha del dia actual, no se si haya que hacer algo en VB y si hay que hacer algo, podrian indicarme que es? no soy programador pero intento aprender algo de usted, de antemano agradezco mucho su apoyo
abril 6th, 2011 a las 3:12 am
Muchas gracias por la macro esta excelente la web, yo tengo un problema similar, pero en access. desearia saber si hay una macro que me permita programar valores cada dia del calendario, que sea solo escoger el dia y que me de la opcion de agregar o poner el valor, eso seria excelente por que me sacaria de un aprieto en el que estoy, muchas gracias
abril 29th, 2011 a las 6:06 am
Hola!!, he estado viendo la pagina y me parece super sobre todo porque tengo un pequeño problema en mi trabajo llevamos el control de registro de muestras en las cuales se introducen muchos datos, el problema es que no soy la unica que captura los datos y a veces los capturan mal, entonces al querer filtrarlos no me aparecen los que realmente hay, quisiera saber si hay alguna forma de haya una lista de la cual se pueda seleccionar el dato, o de alguna forma que no se pueda capturar, la verdad no se mucho. Muchas gracias.
julio 5th, 2011 a las 2:15 pm
Compañero como puedo actualizar una hoja de exel de VB que contega una tabla dinamica.