🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA Intersect en Excel — encuentra dónde se solapan dos rangos (y la guarda de Worksheet_Change que todo el mundo usa)

|

VBA Intersect en Excel — encuentra dónde se solapan dos rangos (y la guarda de Worksheet_Change que todo el mundo usa)

TL;DRIntersect devuelve solo las celdas que dos rangos comparten. Si no se tocan, devuelve Nothing — no un rango vacío, no un error — y ese Nothing es justo lo importante. Su uso número uno es proteger un evento Worksheet_Change para que solo reaccione a las ediciones de la columna que te importa. La regla más importante: sin solapamiento significa Nothing, así que cualquier acceso a una propiedad sin comprobar Is Nothing falla con error 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 — Intersect devuelve el solapamiento de dos rangos, o Nothing si no coinciden
  • La regla más importante — sin solapamiento es Nothing, así que protege con Is Nothing o te topas con error 91
  • El uso estrella — la guarda del Worksheet_Change, y la trampa de EnableEvents que 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