Hojas de cálculo en Excel - página principal

Ejecutar un macro al cambiar una celda

La mayoría de las veces, cuando ejecutamos un macro, lo hacemos de forma consciente, previa solicitud, es decir, bajo petición, ya sea pulsando un botón que tiene asociado el macro, o bien desde los menús seleccionando el macro de la lista de macros disponibles.

Otras veces, ejecutamos una macro, cuando cambia cualquier celda de cualquier hoja de cálculo del libro (a través del evento SheetChange), o bien cuando cambia cualquier celda de una hoja de cálculo determinada (a través del evento Change).

Pero, ¿podemos ejecutar una macro, no solo a petición, o cuando cambia cualquier celda de la hoja, sino también cuando cambia una celda específica de la hoja de cálculo?. Es decir, ¿podemos ejecutar un macro solo si cambia una celda (o varias), impidiendo que se ejecute el macro, si se cambian otras celdas de la hoja?. Pues la respuesta, como debéis intuir, es sí. Por supuesto que se puede ejecutar un macro bajo esas condiciones.

Lo primero que tenemos que pensar es que tiene que cambiar "algo", para que se ejecute el macro. Ese "algo" será una celda de la hoja de cálculo. Y más concretamente esa celda será una que habremos elegido nosotros, es decir, no valdrá que cambie cualquier celda, sino solo la elegida por nosotros.

Para ver como funciona este macro, lo haremos con un ejemplo. Supongamos que tenemos la Hoja1 de un libro de excel, y queremos que nos muestre un mensaje (Msgbox), cada vez que alguien cambie el dato que tenemos en la celda B5. Por tanto, el mensaje solo se mostrará si alguien cambia la celda B5, y no se mostrará nada, si se cambia la celda B4, la B6, la N55, LA J677, o cualquier otra que no sea expresamente la celda B5.

Tenemos que pensar que lo primero que debe ocurrir es que debe cambiar algo, por tanto, debe producirse el evento Change (si es que lo aplicamos a la Hoja1 en concreto). Por tanto, deberemos poner algo dentro de la Hoja1, es decir, algo como esto:


Lo que irá dentro de ese evento Change, es un condicional, que evaluará si cambia o no la celda B5, para que en ese caso, se dispare el mensaje. La propia Microsoft nos propone hacer algo como esto (los comentarios del código son míos, no de Microsoft):


Private Sub Worksheet_Change(ByVal Target As Range)
'pasamos a una variable, la celda o celdas
'que queremos evaluar si cambian o no

datos = "B5"
'como estamos dentro del evento "Change", algo tiene
'que estar cambiando... Pues bien, si la celda activa
'es la misma que la celda que hemos puesto en
'la variable llamada "datos", entonces
'que muestre un mensaje (recordemos que una doble
'negación es una afirmación)

If Not Application.Intersect(ActiveCell, Range(datos)) Is Nothing Then
'mostramos un mensaje
MsgBox ("Oyeeeee, sé que estás cambiando la celda " & datos & ".")
End If
End Sub

Y efectivamente, ese código funciona correctamente si cambiamos la celda B5 y pulsamos intro. Pero ¿qué ocurre si en lugar de pulsar intro, una vez editada la celda B5, pulsamos cualquier tecla de desplazamiento?. Pues que no funciona la solución propuesta por Microsoft. ¿Y qué pasa si editamos el contenido de la celda B4 (la que está encima de B5), y en lugar de pulsar intro, una vez cambiado el valor de esa celda, pulsamos la telcla de desplazamiento hacia abajo?. Pues que se ejecuta el macro, con lo cual, estamos en las mismas, ...no funciona correctamente el macro.

Es decir, la solución propuesta por Microsoft funciona, siempre y cuando utilicemos la tecla intro (la tecla enter), para editar (para cambiar) el contenido de las celdas, pero los usuarios medianamente avezados, suelen utilizar las teclas de desplazamiento, en lugar de la tecla intro, para finalizar la edición de las celdas, ...y en ese caso, la solución de Microsoft puede no funcionar (no siempre falla, evidentemente, pues para que falle, la celda activa debe ser la celda B5, o cualquier de sus celdas contiguas vertical u horizontalmente).

Para solucionar ese contratiempo, podemos cambiar la solución propuesta por Microsoft, y utilizar esta otra que es parecidísima:

Private Sub Worksheet_Change(ByVal Target As Range)
'pasamos a una variable, la celda o celdas
'que queremos evaluar si cambian o no

datos = "B5"
'como estamos dentro del evento "Change", algo tiene
'que estar cambiando... Pues bien, si la celda activa
'es la misma que la celda que hemos puesto en
'la variable llamada "datos", entonces
'que muestre un mensaje (recordemos que una doble
'negación es una afirmación)

If Not Application.Intersect(Target, Range(datos)) Is Nothing Then
'mostramos un mensaje
MsgBox ("Oyeeeee, sé que estás cambiando la celda " & datos & ".")
End If
End Sub


Si observamos bien, la diferencia está en que Microsoft nos propone incluir Activecell, y en esta nueva versión lo cambiamos, y ponemos Target.

Si quisiéramos mostrar el mensaje al cambiar varias celdas contiguas, por ejemplo cuando cambiamos B5, B6, o B7, entonces haríamos esto:

Private Sub Worksheet_Change(ByVal Target As Range)
'pasamos a una variable, la celda o celdas
'que queremos evaluar si cambian o no

datos = "B5:B7"
'como estamos dentro del evento "Change", algo tiene
'que estar cambiando... Pues bien, si la celda activa
'es la misma que la celda que hemos puesto en
'la variable llamada "datos", entonces
'que muestre un mensaje (recordemos que una doble
'negación es una afirmación)

If Not Application.Intersect(Target, Range(datos)) Is Nothing Then
'mostramos un mensaje
MsgBox ("Oyeeeee, sé que estás cambiando alguna celda del rango " & datos & ".")
End If
End Sub


Si por el contrario, lo que queremos es mostrar el mensaje al evaluar un rango discontinuo de celdas, por ejemplo las celdas B5, B7, y B12, entonces haríamos esto:

Private Sub Worksheet_Change(ByVal Target As Range)
'pasamos a una variable, la celda o celdas
'que queremos evaluar si cambian o no

datos1 = "B5"
datos2 = "B7"
datos3 = "B12"
'como estamos dentro del evento "Change", algo tiene
'que estar cambiando... Pues bien, si la celda activa
'es la misma que la celda que hemos puesto en
'la variable llamada "datos", entonces
'que muestre un mensaje (recordemos que una doble
'negación es una afirmación)

If Not Application.Intersect(Target, Range(datos1)) Is Nothing Or _
Not Application.Intersect(Target, Range(datos2)) Is Nothing Or _
Not Application.Intersect(Target, Range(datos3)) Is Nothing Then
'mostramos un mensaje
MsgBox ("Oyeeeee, sé que estás cambiando alguna de estas celdas " & _
datos1 & ", " & datos2 & ", " & datos3 & ".")
End If
End Sub


Bueno, como veis, es bastante sencillo. El truco consiste en incluir dentro del evento Change de la hoja que queramos evaluar (aunque también puede ser en el libro), un condicional que evalúe si cambia determinada celda, y que será la que dispare el macro. En nuestro caso, en lugar de disparar un macro, lo que hemos hecho, ha sido mostrar un mensaje (mediante un Msgbox), aunque el mensaje, bien podría haber estado en un macro aparte, y de igual forma podríamos haberlo ejecutado. Tan solo habríamos tenido que llamar al macro desde el condicional del Intersect.



59 comentarios:

richdebian dijo...

que tal Master, fijate que necesito hacer una mini aplicacion con excel, pero no se mucho de programacion y ver todos tus codigos aun q esten documentados me hace falta lectura. bueno

Lo que necesito es saber si me puedes apoyar con ideas o un ejemplo de como mostrar datos en unas celdas seleccionado desde un combo o list un numero y ese numero que esta asociado a una persona o cosa, los muestre un unas celdas especificas.

por ejemplo

No. 1
2
3
SI AL SELECCIONARL DEL COMBO EL NUM 2 ME MUESTRE EL NOMBRE, EDAD, DIRECCION ETC. DE UN ALUMNO.
LO ESTOY TRATANDO DE HACE CON ACCESS, LISTAS PERO NO LOGRO LINKEAR ALGUN NUMERO PARA QUE ME MUESTRE DATOS.
MI CORREO ES ricmen19@gmail.com espero tengas un tiempo para ver de q forma me puedes apoyar

saludos cordiales

Javier Marco dijo...

En este artículo explico como crear nuestro primer combobox, y hay un ejemplo muy parecido a lo que buscas.

Anónimo dijo...

Hola ja vier, como puedo hacer para que yo deje un libro de excel abierto, y se ejecute una macro automaticamente?

Ejem:
todos salen de trabajar a las 6pm, pero quieres que se ejectue una macro a las 8pm de ese dia, y solo dejando el libro abrierto, la macro pueda detectar la hora y si son las 8, se estaria ejecutando la hora.

Otra consulta como puedo hacer en un formulario de excel, un reloj? pero que la hora se actualize tambien en el formualrio. Es decir que si lo abro a las 8:10 am, me debe salir la hora en el formulario, pero si lo dejo abierto todo el dia, como valla aumetando los minutos, esos minutos tambien se vean reflejados en el formulario.

Atte.
Augusto

Javier Marco dijo...

Pues todo eso que pides, se puede hacer utilizando lo que se explica en el artículo sobre como poner la hora en una celda

Saludos.

Daniel dijo...

HolaHola, yo necesitaria lo siguiente
Si el valor de la celda (que es el resultado de una funcion) es distinto de 0 reciba un mensaje. De lo contrario que no pase nada. Necesito que la macro se aplique para las 12 hojas del workbook .
Gracias de antemano.

Guillain Barré dijo...

Muchas gracias, dichas rutinas me fueron de gran utilidad.

Anónimo dijo...

Hola Javier agradecido por todo lo que enseñàs. te queria hacer una pregunta, para ver como armo la macro de la manera mas simple. Tengo que agregar una cantidad de documentos a una base de datos todo en excel y siempre es variable la cantidad, ejemplo linea a1 a d4 1 documento solo y lo copio y lo agrego en una base de datos, pero luego borro esa linea y tengo otros tres documentos en 3 lineas a1 a a3 hasta d1 a d3 para agregar a la base. La pregunta es como hago la macro si nunca se cuantos documentos voy a tener que copiar a la base si es 1 linea 3 ò 10lineas?

Pedro Silvestre dijo...

Hola Javier:

El artículo resulta interesantísimo.

Solo tengo una pregunta. Cómo puedo hacer para que dos comandos de este tipo (para que se ejecuten automaticamente ciertas macros) se encuentren en una misma hoja?. Te pregunto esto ya que cuando quiero incluir dos veces este comando en una hoja, resulta que automáticamente se cancela la ejecución de las macros.

Espero haberme explicado

Att. Pedro

Marta dijo...

Hola Javier,
Me ha encantado tu articulo. Mi problema es que en vez de cambiar una celda tengo que cambiar el valor de una combobox, y la macro no se ejecuta hasta que pulso intro. ¿Hay alguna forma de que se ejecute sin tener que pulsar intro y que lo haga sólo con cambiar el valor del combobox?

Muchas gracia.

Javier Marco dijo...

Hola Marta. Parece interesante tu pregunta, y acabo de desarrollar el código para hacer eso que pretendes, pero permíteme que lo incluya como un artículo la semana que viene, cuando lo explique detalladamente, que se me agotan las ideas, y esta parece interesante :-) y puede ser útil al resto de lectores del blog (que cada día son más, por cierto).

giuliano_ dijo...

javier, hola!... muy bueno tu blog---
tengo una duda con respecto a lo que comentas en esta publicación...
escribí una macro que evalua el valor de una columna,, y si este toma el valor "OK"... copia determinados valores contiguos a la celda que esta evaluando y los pega en otra hoja...
el problema es que no me funciona cuando el valor "OK" es el resultado de una fórmula SI, que me entrega el valor "OK" si se cumplen determinadas condiciones...
solo cuando manualmente escribo "OK".

habrá alguna solución???

a la hora de proporcionar más información te muestro la macro (son más valores los que se copian y pegan...)

Private Sub Worksheet_Change(ByVal Target As Range)
Application.ScreenUpdating = False
If Target.Row >= 11 And Target.Column = 17 And Target.Count = 1 Then
If Target.Value = 1 And IsNumeric(Target.Value) Then
desocupada = Sheets("macro_giu").Range("B65536").End(xlUp).Row + 1
Target.Offset(0, -1).Copy
Sheets("macro_giu").Cells(desocupada, 15).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End If
End If
Application.ScreenUpdating = True
End Sub

de antemano, muchas gracias...

saludos, giuliano_

Juan Carlos dijo...

Hola Javier, buenas noches es que me gustaría que ayudaras en algo, sucede es que creé una macro que le diera formato aun archivo que mandan mensualmente,cuando el archivo tiene el mismo nombre no hay problemas pero cuando le cambian el nombre, me sale el error, el hecho es que cuando me viene con un nombre diferente yo le cambio el nombre para que se ejecute la macro. Quisiera saber si existe una manera de que la macro que creé se ejecute asi tenga otro nombre diferente? con algún codigo o que? me agradaria mucho en lo que me puedas ayudar. Tu blog es full chevere.
Gracias

Juan Carlos

Javier Marco dijo...

Se me ocurren varias cosas que podrías hacer. Una es impedir que se le cambie el nombre al fichero, para que no tengas ese problema, y otra es crear una carpeta exclusiva para ese fichero, con independencia del nombre que tenga. En esa carpeta solo tendrías ese fichero, y utilizando este macro para saber los ficheros que hay en un directorio, lo tendrías más fácil, pues podrías obtener el nombre del fichero, y aunque se lo cambien, como siempre habrá solo 1 fichero en esa carpeta, pues tema solucionado. Lo abrimos y listo.

Espero que me hayas pillado la idea.

Un saludo.

Guillermo dijo...

Hola javier,
He leido varios de tus articulos y son muy buenos pero no he encontrado lo que buscaba, ya que no soy ningun experto...
te cuento,tengo una hoja de excel en la que una columnaen la que todas las celdas tienen asociada una lista despleglable con varias opciones. lo que quiero es que al escoger una opcion de la lista, segun lo que escojas, se cambie de color la fila entera. Como lo ves?
Muchas gracias.
Guillermo

Anónimo dijo...

estaba leyendo sus comentarios y son muy buenos, pero mi pregunta es: cómo puedo hacer para que cuando una celda tome un valor automáticamente (por ejemplo que al hacer una formula de validación y la celda C5 =1 cuando dicha validación sea Veradera), esto ejecute una macro sin necesaidad de pulsar intro

Javier Marco dijo...

¿Qué tal si anidas un IF dentro del IF que hay en el código, y que evalúe si la celda en cuestión toma valor 5, u otro distinto, para mostrar un mensaje, lanzar un macro, o hacer cualquier otra cosa?.

Con el macro del artículo y un condicional más, lo tienes resuelto.

Jorge dijo...

Si por el contrario, lo que queremos es mostrar el mensaje al evaluar un rango discontinuo de celdas, por ejemplo las celdas B5, B7, y B12, entonces haríamos esto:

Private Sub Worksheet_Change(ByVal Target As Range)
'pasamos a una variable, la celda o celdas
'que queremos evaluar si cambian o no
datos1 = "B5"
datos2 = "B7"
datos3 = "B12"
'como estamos dentro del evento "Change", algo tiene
'que estar cambiando... Pues bien, si la celda activa
'es la misma que la celda que hemos puesto en
'la variable llamada "datos", entonces
'que muestre un mensaje (recordemos que una doble
'negación es una afirmación)
If Not Application.Intersect(Target, Range(datos1)) Is Nothing Or _
Not Application.Intersect(Target, Range(datos2)) Is Nothing Or _
Not Application.Intersect(Target, Range(datos3)) Is Nothing Then
'mostramos un mensaje
MsgBox ("Oyeeeee, sé que estás cambiando alguna de estas celdas " & _
datos1 & ", " & datos2 & ", " & datos3 & ".")
End If
End Sub

Hola que tal? es posible aplicar este codigo para una columna entera? por ejemplo datos1=A:A? y a su vez el MsgBox puede mostrar cambios de otras celdas que esten en la misma fila de celda que cambio?? gracias a todos

Anónimo dijo...

Hola
Me preguntaba para qué version de excel aplica lo comentado, ya que ahora mismo estaba probando en mi excel si ocurría lo que usted comentaba y resulta que no, que no me ocurren las situaciones excepcionales. Por ejemplo, si en lugar de presionar el enter presiono las teclas de desplazamiento la macro inicial sí se ejecuta.Tampoco se ejecuta la macro si es que modifico la celda de arriba y me desplazo a la que debería ejecutar la macro, es por eso que el pido que me respodna prontamente a qué versiond e excel aplica lo que usted ha comentado.

Gracias
Magdaleena

Javier Marco dijo...

A ver..., el macro del ejemplo se ejecuta al cambiar la celda B5, ni la de arriba, ni la de abajo, ni la de los lados, solo la de B5. Si se edita la celda sin cambiar el dato que hay en ella, también se ejecuta, pues aunque se deje el mismo dato, se entra en modo de edición, y se está cambiando la celda.

Debes escoger el segundo macro del ejemplo, para que te funcione todo correctamente. El primero tiene el problema de que se ejecuta el macro al situarte en B5, pero cambiando la celda de arriba por ejemplo, y bajando con las flechas de desplazamiento, en lugar de con un enter. De ahí que la segunda opción sea la recomendable, pue el macro solo debe ejecutarse al cambiar B5 y no una celda de alrededor.

En principio debería funcionar en todas las versiones. Yo lo acabo de probar en Excel 2003 y Excel 2007 y funciona perfectamente en ambas.

Un saludo.

orh dijo...

Mi duda es la siguiente:
Quisiera copiar a otra hoja una fila de datos, una vez se haya marcado una casilla de verificación que se encuentra al final de la misma.
Te estaría agrarecido si me dijeras como hacerlo. Gracias

Anónimo dijo...

Hola Javier, tienes un tema muy interesante, de verdad. Cuando explicas como ejecutar una macro dices que en vez de ejecutarla, escribes un mensaje, pero acabas diciendo "Tan solo habríamos tenido que llamar al macro desde el condicional del Intersect" mi pregunta es: ¿Y como se hace eso?

Muchas gracias.

Javier Marco dijo...

A ver, no me queda muy clara tu duda...

En este artículo estamos mostrando como ajecutar un macro a cambiar una celda determinada (o un rango de celdas).

Si lo que deseas realmente es iniciarte con las macros, pásate por este artículo: Mi primer macro en excel.

Saludos.

Anónimo dijo...

Hola Javier, perdona por no explicarme bien sobre las macros. Yo tengo una macro diseñada de tal forma que cuando la ejecuto, envia un e-mail a la direccion de correo que tengo especificada en el cuerpo del modulo. Navegando por internet encontre tu blog, en donde expones muy bien el como hacer cosas cuando cambia el estado de una celda de una hoja en cuestion. Bien pues lo que yo quiero es que se ejecute ese modulo o macro cuando cambias el valor de una celda en cuestion. Por eso cuando acabas tu comentario diciendo "Tan solo habríamos tenido que llamar al macro desde el condicional del Intersect." pues lo he intentado y no he sabido solucionarlo, me da errores.
Decirte que me llamo Miguel.

Muchas gracias Javier.

Anónimo dijo...

Hola Javier,
felicitarte por tus aportaciones, que nos facilitan la vida a muchos. Por mi parte, me gustaría saber la respuesta que le diste a Marta, pues no he podido ver qué decías en tu blog en septiembre del año pasado.

Saludos,

Juan Carlos.

Javier Marco dijo...

Dónde estarías tú en septiembre del año pasado... ayyyy señor :-)

El artículo que escribí relacionado con la pregunta de Marta, fue este: Ejecutar un macro, al seleccionar un elemento de un combobox.

Saludos.

Anónimo dijo...

Hola Javier; Muchas felicidades y gracias por tu ayuda.
Tengo una hoja de examen en excel que es de selección múltiple y lo que quiero saber como puedo hacer para que los siguientes datos de una fila se almacenen en una hoja:
1º Nombre 2º Curso 3ºCalificación.
Y que la hja de examen se vuelva a borrar

Anónimo dijo...

Clarisimo, me has resuelta la duda.

Muchas gracias.

Xavier

Anónimo dijo...

Hola Javier
Estaba leyendo el blog y yo tengo una inquietud similar. El tema es que cuando cambio la celda que activa la macro ya es tarde.
¿Hay forma de hacer una advertencia antes que indique que el usuario está por cambiar el valor A por el valor B?
Muchas gracias

Javier Marco dijo...

En principio el macro se activa al cambiar o editar la celda (porque también se ejecuta al reescribir el mismo valor que ya había).

Se puede hacer algo parecido a lo que pretendes, cuando un usuario seleccione una celda determinada (ojo, digo seleccionar, es decir, situarse encima de esa celda, sin necesidad de cambiar el dato). Para ello, tienes que usar un macro donde pongas dentro un MsgBox, por ejemplo, para que salte, solo seleccionar esa celda, dentro del evento SelectionChange de la hoja de cálculo. Algo así, vamos:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'Aquí va el código condicional que mira
'si hemos seleccionado la celda X, para
'lanzar un MsgBox
End Sub

Saludos.

Anónimo dijo...

Hola Javier, de antemano muchas gracias por tus valiosos aportes.
Tengo una inquietud sobre este tema, hice unos cambios para que al modificar una celda de una columna me escriba en otra celda especifica la fecha de la modificacion. pero ahora necesito que ponga la fecha solo cuando escriba "OK" y que cuando escriba algo diferente a esto no haga nada.

Si me puedes colaborar te lo agradeceria muchisimo.

Anónimo dijo...

Hola, respecto al tema "Ejecutar una macro al cambiar una celda", como se podria modificar dicha macro para que solo cambiara si existe algun dato previo en esa celda (ninguno en especifico)? Ademas que mostrara en el MsgBox el dato actual que se quiere cambiar, es decir, el MsgBox diria: "Seguro que desea modificar "dato_actual_celda" por este "dato_a_modificar".

Javier Marco dijo...

Aquí tienes un ejemplo sencillo. Copy y pega todo esto en la hoja que quieras controlar:

Public valor

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
valor = Range("B5")
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)
'pasamos a una variable, la celda o celdas
'que queremos evaluar si cambian o no
datos = "B5"
'como estamos dentro del evento "Change", algo tiene
'que estar cambiando... Pues bien, si la celda activa
'es la misma que la celda que hemos puesto en
'la variable llamada "datos", entonces
'que muestre un mensaje (recordemos que una doble
'negación es una afirmación)
If Not Application.Intersect(Target, Range(datos)) Is Nothing Then
'si la celda de arriba contiene un dato...
If Not IsEmpty(ActiveCell.Offset(-1, 0)) Then
'mostramos un mensaje, informando lo que va a cambiar
MsgBox ("Dato a cambiar: " & valor & ". Valor nuevo: " & Range(datos) & ".")
End If
End If
End Sub

Anónimo dijo...

Que tal Javier, agradecido con tu pronta y eficaz respuesta a la pregunta del 18 de Febrero 2011 8:24 "Ejecutar macro al cambiar una celda", lo cual me tiene admirado.
En verdad "ese detalle" de la solucion me saca de apuros. Gracias de nuevo.

EdsonHRV dijo...

Estimado Javier:
Tengo un codigo parecido que me gustaria que lo comentes.
Me lo pasaron para que al cambiar la fecha esta busque la data y actualize un cuadro segun la fecha.

Pero lo quise mejorar colocando una barra de desplazamiento para cambiar la fecha con la barra y ya no manualmente pero no cambia nada como si no reconociera el cambio en la celda.

el codigo es este:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address <> "$C$1" Then Exit Sub
If Target.Value = "" Then Exit Sub
' Busca fecha ingresada en "C1" y actualiza un cuadro deacuerdo a la data de esa fecha encontrada en una base de datos...
End Sub


Por favor ojala me respondas pronto porque nos e como hacerlo correr esta vez

Anónimo dijo...

Estimado Javier. La consulta es la siguiente: tomo 2 cosas que enseñaste: 1-lo que es el tema de Validacion de listas dependientes y 2- Ejecutar un macro al cambiar una celda.
supongamos que en una hoja tengo 3 columnas A, B y C para seleccionar datos que se relacionen entre si (validacion de listas dependientes -la validacion esta preparada en hoja 2-: al seleccionar en hoja 1, la celda A1, me define los datos de B1; y als eleccionar B1 me define que datos seleccionar de C1). Ahora bien, yo quisiera contar con las mismas alternativas al seleccionar dato en A2 (con relacion a B2 y de B2 con C2), y Asi hasta hasta la fila 20 -por ejemplo-). Yo habia pensado en Private Sub Worksheet_Change(ByVal Target As Range): porque?, por cuando seleccione A2, o A3, etc. la validacion de listas dependientes se deberia poder volver a ejecutar...no se si me explico...si te interesa me vendria excelente tu ayuda.
desde ya muy amable. Leo de santa Fe, Argentina.

Anónimo dijo...

Estimado Javier,
EStoy intentando crear un macro que ejecute lo siguiente. Dandole a un boton, creado para tal fin, que pregunte de una celda en concreto los valores a imprimir, por ejmplo del 1 al 20 y que ese ultimo valor se quede en la celda, y que imprima ocho copias de cada hoja. Gracias y un saludo

adrian_atu dijo...

HOLA JAVIER...tengo un problema necesito hacer que una celda cambie de valor al modificar el valor de otra celda en la misma hoja he buscado mil manera y me manda error no se si me puedas ayudar lo quiero un ejemplo es que si la celda b5 es igual a 750 la celda b9 su valor sea de 15 y si la celda b5 es menor a 750 la celda b9 cambie su valor a 10 ojala me puedas ayudar de antemano muchas gracias

Javier Marco dijo...

Para eso no necesitas recurrir a las macros. Te bastará poner esta fórmula en la celda B9:

=SI(B5=750;15;SI(B5<750;10;""))

Saludos.

adrian_atu dijo...

BUEN DIA JAVIER GRACIAS POR LA FORMULA PERO EN VERDAD NO SE QUE ESTE HACIENDO MAL YA QUE SIGUE SIN FUNCIONARME HAY ALGUNA OTRA OPCION POR QUE LA FORMULA ME MANDA ERROR
GRACIAS...

Javier Marco dijo...

Supongo que será por el separador del punto y coma, pues debes tener otra configuración regional. Prueba a cambiarlo por comas, para que quede así (debes ponerlo en B9):

=SI(B5=750,15,SI(B5<750,10,""))

Saludos.

adrian_atu dijo...

MUCHISIMAS GRACIAS JAVIER ME FUE DE MUCHA AYUDA ESTA MUY BIEN TU BLOG SUERTE¡¡¡¡

Carlos dijo...

Hola buenas!

acerca de las macros tengo una duda:
como haría para poner cierta palabra en una celda y que automáticamente se me active la macro de ocultar la fila?

gracias!!

Javier Marco dijo...

Hola Carlos. Coloca este macro en la hoja que quieras controlar (no en un módulo). He utilizado como palabra de control para ocultar la fila, tu propio nombre, como verás en el ejemplo:

Private Sub Worksheet_Change(ByVal Target As Range)
'si en la celda escribimos la palabra "Carlos"
If ActiveCell = "Excelente" Then
'escondemos la fila
Selection.EntireRow.Hidden = True
'y bajamos para situarnos en la fila siguiente
ActiveCell.Offset(1, 0).Select
End If
End Sub

Un saludo.

fofo dijo...

pero si uno quiere que esa celda cambie el valor o un numero por medio de una formula como seria?

Andres Avila dijo...

Exelente, pero tengo una duda
por que al cambiar el valor de otra celda diferente, al dar intro esta se va al resultado de la macro

Javier Marco dijo...

Debería funcionarte correctamente. Lo acabo de probar en Excel 2003 y Excel 2010 y funciona correctamente, sin hacer lo que tú comentas. Creo haberlo probado también anteriormente en Excel 2007.

Pruébalo en otro PC, y verás como funciona correctamente. Parece un problema de tu instalación de Excel, suponiendo que no hayas tocado nada del código, claro.

Anónimo dijo...

Hola javier, eres un excelente maestro..nosé que hariamos algunos sin ti, tengo una duda grande, necesito insertar filas dependiendo del resultado de una celda, por ejemplo..si la celda A1 de la hoja 1 es dos, insertar 2 filas en la hoja 3 en un rango determinado..ojalá pudieras responderme
saludos y desde ya muchas gracias

Javier Marco dijo...

Prueba con esto en la hoja1:

Private Sub Worksheet_Change(ByVal Target As Range)
'If Not Application.Intersect(Target, Range(datos)) Is Nothing Then
'Miramos si el dato es igual a 2
If Range("A1") = 2 Then
'llamamos al macro insertar_filas
insertar_filas
End If
End Sub

Y esto en un módulo:

Sub insertar_filas()
'ocultamos el procedimiento
Application.ScreenUpdating = False
'seleccionamos la hoja2
Hoja2.Select
'insertamos 2 filas en la fila 5 y 6
Range("A5:A6").Select
Selection.EntireRow.Insert
'volvemos a la hoja1
Hoja1.Select
'mostramos el procedimiento
Application.ScreenUpdating = True
End Sub

Saludos.

Anónimo dijo...

Hola Javier, necesito de tu ayuda:
Tengo varias hojas de cálculo, + o - 30 que correponden a cursos del secundario, cada curso tiene su hoja ("Hoja1roA", "Hoja1roB", "Hoja1roC", etc, con las columnas: APEYNOM, DNI; CUIL, ESTADO, RESPONSABLE...etc,) todos estos datos estan copiados en una hoja "HojaListGral", pero aqui el problema, cuando modifico una celda en alguna hoja de curso necesito que la misma se vea modificada en la "HojaListGral", intente copiar los datos desde las hojas de curso como una matriz, haciendo referencia, pero no he podido y el trabajo es muy tedioso sobre todo porque tengo 786 alumnos en total..! imaginate, desde ya muchas gracias, abrazos

Anónimo dijo...

Buenos días Javier, mi nombre es Oscar, actualmente estoy haciendo un libro de excel con varias formulaciones, entre esas debo hacer una que haga lo siguiente:
1- En un fila hay varios campos (columnas), en el campo XX, es una lista desplegable, con opciones A,B,C y D (esto ya lo tengo)
2- Cuando el estado de la columna XX tenga el valor de D, debe ocultarse automáticamente(Esto no sé como hacerlo)

Leí tu foro y los comentarios-respuesta, intenté modificar el código que tienes de ocultar, pero no me ha funcionado

De antemano gracias por tu posible ayuda

Código realizado:
Private Sub Worksheet_Change(ByVal Target As Range)
'pasamos a una variable, la celda o celdas
'que queremos evaluar si cambian o no
datos = "c2:c7"
valor = "d"
'si en la celda escribimos la palabra "D"
If Not Application.Intersect(ActiveCell(valor), Range(datos)) Is Nothing Then
'escondemos la fila
Selection.EntireRow.Hidden = True
'y bajamos para situarnos en la fila siguiente
ActiveCell.Offset(1, 0).Select
End If
End Sub

Oscar dijo...

Hola a todos, pude realizar lo del ocultamiento de una fila al cambiar el valor de una celda:
Tuve que crear un módulo, el código es el siguiente:
Sub auto_open()
'ocultamos el procedimiento
Application.ScreenUpdating = False
'nos situamos en S11
Range("S11").Select
'hasta la fila 7
For i = 1 To 40
'si la celda tiene el valor diferente a D
'solo miramos la celda)
If ActiveCell = "D" Then
' si es igual a D, ocultamos la fila
Selection.EntireRow.Hidden = True
End If
'bajamos una fila
ActiveCell.Offset(1, 0).Select
Next
'mostrams el procedimiento
Application.ScreenUpdating = True
End Sub

Saludos a todos

Oscar

Anónimo dijo...

Hola Javier,

Tengo un libro con dos hojas y quisiera saber como hacer para crear una macro que cada vez que los valores de 4 celdas especificas de la hoja 1 (A10,E6,B9,G18) cambien me los copie en la hoja 2 en A1,B1,C1,D1 y si vuelven a cambiar en A2,B2,C2,D2. Es decir que cada vez que cambien me copie los nuevos datos y los transporte a la siguiente fila de la hoja2, mismas columnas.
Espero haber sido clara, y muchas gracias por tu ayuda.
Tengo excel 2007,Claudia

Jaime dijo...

Hola, quiera saber si podrías ayudar porque estoy hecho un lio porque soy nuevo en esto.
Tengo una macro que la ejecuto con un botón y funciona perfectamente que es:

Sub FILTRO_ALIMENTO()
' FILTRO_ALIMENTO Macro
' BUSCAR ALIMENTO ESCRITO
Application.CutCopyMode = False
Range("F15").Select
Sheets("MACRONUTRIENTES Y MINERALES2").Range("A1:AX1557").AdvancedFilter _
Action:=xlFilterCopy, CriteriaRange:=Range( _
"'Macronutrientes y Minerales'!Criteria"), CopyToRange:=Range("A11:AX11"), _
Unique:=False
End Sub

Y esta macro la quería ejecutar sin tener que apretar el boton, solo cambiando los criterios, uno o varios que tengo en las celdas A10:AB10 y lo que estoy haciendo es lo siguiente:

Private Sub Worksheet_Change(ByVal Target As Range)
datos = "B10:AB10"
If Not Application.Intersect(Target, Range(datos)) Is Nothing Then
Application.CutCopyMode = False
Range("F15").Select
Sheets("MACRONUTRIENTES Y MINERALES2").Range("A1:AX1557").AdvancedFilter _
Action:=xlFilterCopy, CriteriaRange:=Range( _
"'Macronutrientes y Minerales'!Criteria"), CopyToRange:=Range("A11:AX11"), _
Unique:=False
End If
End Sub

Y sin éxito claro está, sin saber porqué.
Te agradecería mucho que me orientaras o dijeras cuál es el error.
Muchas Gracias de antemano.

Salomón Arango Puerta dijo...

Excelente publicación. Muchas gracias

Anónimo dijo...

Hola Javier. He leido este articlo y tambien el relativo a comboboxes. Mi duda es la siguiente:
Tengo un formulario en hoja sin userformen el que utilizo listboxes y comboboxes, de manera que a ciertas preguntas ahi 4 casillas donde se marca - o X, donde X es que queda marcada(por defecto el formulario comienza con todo -).
El problema es que segun lo que marques se van sumando o haciendo operaciones para lograr una puntuación final y por error pueden quedar marcadas varias opciones a una pregunta.
Por eso quiero usar algo parecido a lo de este articulo, es decir, que al marcar una casilla se borre el resto de casillas(listboxes) correspondientes a esa pregunta. Si lo hago con una casilla va bien, pero cuando se lo aplico a varias para que se cumpla no lo aguanta excel y se me cierra.
Te dejo la subrutina que utilice:
Private Sub Worksheet_Change(ByVal Target As Range)
'Si hay errores, que continúe
On Error Resume Next
'Si cambiamos el dato de la celda C11,
'limpiamos el segundo desplegable
If Target.Cells = Range("C11") Then
'eliminamos el contenido de las otras
Range("D11").ClearContents
Range("E11").ClearContents
Range("F11").ClearContents
End If
End Sub

Gracias

Anónimo dijo...

Soy el del comentario anterior.
Me he dado cuenta del error. Al cambiar una casilla, se borra el contenido de las otras 3. Esto hace que se active el otro If, que me vuelve a borrar 3 casillas y me lleva de nuevo al primer If y asi sucesivamente. Por eso me saca del programa, porque entra en un bucle sin fin.
He intentado añadirle la condición de que cuando además de cambiar una casilla no se cambien las otras 3 (con And Not), es cuando debe proceder a borrar dichas 3. Así ya no se mete en un bucle infinito, pero no acaba de funcionar bien. Se me quedan borradas las 4 casillas cuando marco una (C11 o D11)

Anónimo dijo...

Hola Javier,

¿Qué pasa si el contenido de la celda es una fórmula? Es decir, el contenido de la celda no va a cambiar, pero el resultado de dicha fórmula sí. Me gustaría que se fijase en el resultado y no en la fórmula.

¿Alguna idea?

Muchas gracias de antemano

LLRULL dijo...

Hola a todos,

Amigo Javier, que casualidad el comentario de Anónimo a 24 de junio de 2013 16:04. Me sucede lo mismo... en mi caso me interesa resaltar las celdas que se ven afectadas por un cambio en el valor de la fórmula que contienen.

El evento Worksheet_Change no se dispara al cambiar el valor (de la función contenida en la celda), te replico mi script:
If Not Application.Intersect(Target, Range("_BS2013")) Is Nothing _
Then Target.Interior.Color = RGB(223, 223, 223)

Donde Target contiene una fórmula y _BS2003 es el rango de celdas donde deben detectarse cambios.

Desde ya, muchas gracias ^N

llrull








Anónimo dijo...

Hola Javier, disculpeme por abusar de su confianza, es para ver si me puede colaborar para guardar un documento en excel automaticamente cuando se cambie un valor en la columna ha de la fila a1 a la a200 cada vez que digite un valor guarde automaticamente el documento, porque he leido y solo existe el autoguardado pero eso no me garantiza que no se pierda informacion. No soy experto en macros.
Muchas gracias por la colaboracion.