TL;DR —
Intersectdevuelve solo las celdas que dos rangos comparten. Si no se tocan, devuelveNothing— no un rango vacío, no un error — y eseNothinges justo lo importante. Su uso número uno es proteger un eventoWorksheet_Changepara que solo reaccione a las ediciones de la columna que te importa. La regla más importante: sin solapamiento significaNothing, así que cualquier acceso a una propiedad sin comprobarIs Nothingfalla conerror 91:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Me.Range("B:B")) Is Nothing Then Exit Sub ' la edicion no fue en la columna B
Application.EnableEvents = False ' evita que nuestra propia escritura vuelva a dispararlo
Target.Offset(0, 1).Value = Now ' sella la hora justo al lado
Application.EnableEvents = True
End Sub
Union combina rangos; Intersect es su opuesto — encoge a la parte compartida. Y a
diferencia de todas las referencias anteriores, Intersect puede legítimamente no devolver nada
en absoluto, porque dos rangos que no se solapan no tienen celdas en común. Esta guía se construye
sobre una sola idea — Intersect responde una pregunta de sí o no («¿se solapan estos?»)
devolviendo o bien el solapamiento o bien Nothing, y tienes que comprobar cuál antes de
tocarlo. Ese único hábito es lo que separa un manejador de eventos robusto de uno que falla con el
clic equivocado.
Lo que aprenderás
- El modelo mental —
Intersectdevuelve el solapamiento de dos rangos, oNothingsi no coinciden - La regla más importante — sin solapamiento es
Nothing, así que protege conIs Nothingo te topas conerror 91 - El uso estrella — la guarda del
Worksheet_Change, y la trampa deEnableEventsque viene con ella - Acotar una macro a un área concreta con
Intersect(Selection, ...) - Por qué
Intersect(∩, solapar) es lo opuesto de Union (∪, combinar) - Intersecciones de varios rangos y la regla de la misma hoja
El modelo mental: Intersect es el solapamiento de dos rangos
Dale a Intersect dos rangos y te devuelve una referencia a solo las celdas que están en ambos:
Dim shared As Range
Set shared = Intersect(Range("A1:D10"), Range("C5:F20"))
' shared es C5:D10 - el rectangulo que los dos rangos tienen en comun
Si los dos rangos no comparten nada, no hay rectángulo común que devolver, así que Intersect
devuelve Nothing. Ese es el comportamiento que lo hace útil: rara vez te importan las celdas
del solapamiento en sí — te importa si hay solapamiento siquiera. «¿Está esta celda dentro de
esa región?» se convierte en «¿es Intersect(cell, region) algo en vez de Nothing?». Intersect
convierte una pregunta de geometría en una simple prueba de presencia.
La regla más importante: sin solapamiento devuelve Nothing
Como un fallo devuelve Nothing, echar mano de cualquier propiedad o método sobre el resultado
sin comprobar antes es un fallo esperando a suceder:
' FRAGIL - error 91 en cuanto los rangos no se solapan:
MsgBox Intersect(Selection, Range("B:B")).Address
Cuando Selection no está en la columna B, Intersect es Nothing, y .Address sobre Nothing
lanza error 91, "Object variable or With block variable not set." El arreglo siempre es comprobar
antes con Is Nothing, y la forma idiomática usa If Not ... Is Nothing para decir «si hay
solapamiento»:
If Not Intersect(Selection, Range("B:B")) Is Nothing Then
MsgBox "Your selection touches column B."
End If
Lee If Not (overlap) Is Nothing como «si el solapamiento no es nada» — es decir, si existe.
Los dos errores aquí son quitar el Not (que invierte la lógica) y quitar la comprobación
Is Nothing (que falla ante un fallo). Memoriza la frase completa; es una de las líneas más
tecleadas de todo VBA.
El uso estrella: la guarda del Worksheet_Change
Aquí es donde Intersect se gana su sitio. Un evento Worksheet_Change se dispara con cada
edición en cualquier parte de la hoja, y el 99% de las veces solo quieres reaccionar a los cambios
de una columna o región. Sin una guarda, tu manejador se ejecuta con cada pulsación de tecla por
toda la hoja — lento e intrusivo. Intersect es la guarda: pregunta si la celda modificada
(Target) se solapa con el rango que vigilas.
Private Sub Worksheet_Change(ByVal Target As Range)
' Solo actua cuando la edicion cae en el rango de datos B2:B1000:
If Intersect(Target, Me.Range("B2:B1000")) Is Nothing Then Exit Sub
Application.EnableEvents = False ' CRITICO - ver mas abajo
On Error GoTo CleanExit
Dim c As Range
For Each c In Intersect(Target, Me.Range("B2:B1000")).Cells
c.Offset(0, 1).Value = "edited " & Format(Now, "yyyy-mm-dd hh:nn")
Next c
CleanExit:
Application.EnableEvents = True ' restaura siempre, incluso tras un error
End Sub
Dos cosas hacen que este sea el patrón correcto. Primero, la línea de guarda
If Intersect(...) Is Nothing Then Exit Sub sale pronto ante cualquier edición fuera del objetivo,
así que el cuerpo solo se ejecuta cuando debe. Segundo — y esta es la trampa que pilla a todos — el
manejador escribe en una celda, y escribir en una celda dispara Worksheet_Change otra vez,
que vuelve a escribir, y así sucesivamente. Application.EnableEvents = False rompe esa recursión,
y hay que restaurarlo en una etiqueta CleanExit para que un error a mitad del manejador no deje
los eventos desactivados durante el resto de la sesión (ver VBA On Error y
Worksheet_Change). La guarda Intersect y la guarda EnableEvents
son hermanas — casi nunca quieres una sin la otra.
Acotar una macro a un área concreta
La misma prueba de solapamiento acota una macro corriente a una región. Supón que una macro de formato solo debe tocar las celdas que el usuario seleccionó dentro del área de impresión — cruza la selección con la región y trabaja sobre el resultado:
Dim scope As Range
Set scope = Intersect(Selection, Range("PrintArea"))
If scope Is Nothing Then
MsgBox "Select cells inside the print area first."
Exit Sub
End If
scope.Font.Bold = True ' solo las celdas seleccionadas que caen dentro de PrintArea
Este es un patrón más limpio que comprobar a mano la dirección de cada celda seleccionada:
Intersect calcula el subconjunto que queda dentro en una sola llamada, y la rama Is Nothing
cubre el caso de «la selección falló el área por completo».
Intersect frente a Union: solapar frente a combinar
Intersect (∩) y Union (∪) son los dos operadores de conjuntos sobre
rangos, y tiran en direcciones opuestas. Union(A, B) hace crecer una referencia a todo lo que está
en cualquiera de los rangos. Intersect(A, B) la encoge a solo lo que está en ambos, o
Nothing. Union nunca devuelve Nothing (le diste rangos reales para combinar); Intersect devuelve
Nothing constantemente, y eso es una virtud, no un defecto. Usa Union para reunir celdas
dispersas para una operación por lotes, e Intersect para comprobar o restringir — para preguntar
si una edición, una selección o una celda cae dentro de una región que te importa.
Intersecciones de varios rangos y la regla de la misma hoja
Intersect acepta más de dos rangos y devuelve las celdas comunes a todos ellos —
Intersect(rngA, rngB, rngC) es la región que cubre cada argumento. Como con Union, todos los
rangos tienen que estar en la misma hoja, o te sale error 1004. Y la misma disciplina aplica
al resultado: si la intersección pudiera estar vacía, comprueba Is Nothing antes de usarla — con
tres o más rangos un solapamiento vacío es aún más probable que con dos.
Cómo ayuda ExcelMaster
Intersect es un método pequeño que esconde dos reglas fáciles de olvidar: comprueba Is Nothing
antes de tocar el resultado, y empareja la guarda de evento con EnableEvents = False para que un
cambio autoprovocado no se descontrole. Falla la primera y te estrellas con error 91; falla la
segunda y un manejador Worksheet_Change se vuelve a disparar a sí mismo hasta un parpadeo o un
cuelgue.
ExcelMaster te deja describir
el comportamiento en su lugar. Di «cuando alguien edite la columna B, sella la hora en la columna
C», y escribe la guarda Intersect(Target, ...), el Exit Sub temprano, el interruptor de
EnableEvents y la restauración en CleanExit — todo el patrón de evento robusto, no solo el
camino feliz. Te quedas con el libro y con el código; te ahorras la sesión de depuración en la que
el manejador se disparó con la celda equivocada o entró en bucle consigo mismo.
Preguntas frecuentes
¿Qué hace el método Intersect en Excel VBA?
Intersect devuelve un rango con las celdas que dos o más rangos tienen en común — su
solapamiento. Intersect(Range("A1:D10"), Range("C5:F20")) devuelve C5:D10. Si los rangos no se
solapan en absoluto, Intersect devuelve Nothing, que es por lo que se usa para comprobar si un
rango cae dentro de otro.
¿Por qué Intersect devuelve Nothing y hace que mi código falle?
Cuando los rangos no comparten celdas, Intersect devuelve Nothing en lugar de un rango vacío.
Acceder entonces a cualquier propiedad — .Address, .Cells, .Value — lanza error 91.
Comprueba siempre primero con If Not Intersect(a, b) Is Nothing Then (que significa «si hay
solapamiento») antes de usar el resultado.
¿Cómo uso Intersect en un evento Worksheet_Change?
Protege el manejador para que solo reaccione a las ediciones dentro de tu rango objetivo:
If Intersect(Target, Me.Range("B2:B1000")) Is Nothing Then Exit Sub. Luego pon
Application.EnableEvents = False antes de escribir en ninguna celda — de lo contrario tu escritura
vuelve a disparar Worksheet_Change — y restáuralo a True en una etiqueta CleanExit para que un
error no pueda dejar los eventos desactivados.
¿Cuál es la diferencia entre Intersect y Union en VBA?
Son operaciones de conjuntos opuestas. Intersect devuelve solo las celdas que están en ambos
rangos (el solapamiento), o Nothing si no se tocan. Union devuelve las celdas que están en
cualquiera de los rangos (el área combinada). Usa Intersect para comprobar o restringir una
región, y Union para reunir celdas dispersas en una sola referencia.
¿Puede Intersect aceptar más de dos rangos?
Sí. Intersect(rngA, rngB, rngC) devuelve las celdas comunes a todos los rangos. Todos los
rangos tienen que estar en la misma hoja, y el resultado puede ser Nothing si los rangos no
comparten ninguna celda común — lo cual es más probable con tres o más rangos, así que comprueba
siempre Is Nothing.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 16/08/2026.
Guías relacionadas: VBA Union · VBA SpecialCells · VBA Worksheet_Change · VBA On Error · VBA Range
