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

VBA Worksheet_SelectionChange en Excel — ejecuta código cuando se mueve el cursor (resalta la fila activa sin retardos)

|

VBA Worksheet_SelectionChange en Excel — ejecuta código cuando se mueve el cursor (resalta la fila activa sin retardos)

TL;DRWorksheet_SelectionChange es un evento que Excel dispara cada vez que la selección se mueve — un clic, una tecla de flecha, pulsar Enter. Te entrega la nueva selección como Target, así que puedes seguir al cursor: resaltar la fila activa, mostrar un panel contextual, actualizar una celda de estado. La única regla que lo gobierna: se dispara constantemente, así que el manejador debe ser ligerísimo — cualquier cosa lenta hace que toda la hoja se sienta con retardo y rota. Y si él mismo cambia la selección, protégelo con Application.EnableEvents o se volverá a disparar igual que hace Worksheet_Change.

' Vive en el propio objeto de la hoja (p. ej. Sheet1), NO en un Module ni en ThisWorkbook.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    ' Resalta la fila activa — limpia solo lo que ponemos y vuelve a aplicarlo.
    Cells.Interior.ColorIndex = xlNone            ' limpia el resaltado anterior
    Target.EntireRow.Interior.Color = RGB(255, 255, 200)
End Sub

Donde Worksheet_Change reacciona a las ediciones, SelectionChange reacciona al movimiento. Es el evento detrás de todo efecto de «seguir al cursor» — la fila activa resaltada que hace legibles las tablas anchas, el panel lateral que se actualiza mientras bajas por una lista con las flechas, la referencia de celda que se muestra en una barra de estado. Es también el evento con más probabilidades de hacer que un libro se sienta lento, porque Excel lo llama en cada movimiento del cursor — decenas de veces por segundo cuando mantienes pulsada una tecla de flecha.

Lo que aprenderás

  • El modelo mental — un rastreador del cursor que te entrega la nueva selección como Target
  • La regla que lo gobierna todo — se dispara constantemente, así que mantenlo ligero
  • El truco que todo el mundo quiere — resaltar la fila activa, hecho sin destrozar el formato
  • La trampa que comparte con Change — cambiar la selección vuelve a disparar el evento
  • Qué es Target en realidad — la nueva selección, que puede ser muchas celdas

El modelo mental: un rastreador del cursor, no un sensor de ediciones

SelectionChange es un rastreador cableado al cursor. Nunca lo llamas; cada vez que la celda o el rango seleccionado se mueve, Excel te llama a ti, pasándote la nueva selección como un Range llamado Target. Nada de los datos cambió — solo dónde está mirando el usuario. Esa es la línea clara entre los dos eventos de «reacciona al usuario»: Change = cambió un valor; SelectionChange = se movió el cursor.

Como todos los eventos de hoja, el manejador vive en el objeto de código de la hoja concreta (Sheet1 en el Explorador de proyectos), no en ThisWorkbook ni en un Module, con la firma fija Private Sub Worksheet_SelectionChange(ByVal Target As Range). La versión para todo el libro, que se dispara en cada hoja, es Workbook_SheetSelectionChange en ThisWorkbook.

La regla que lo gobierna todo: se dispara constantemente, así que mantenlo ligero

Esta es la regla que separa una hoja ágil de una lenta. SelectionChange se ejecuta en cada movimiento de la selección — cada pulsación de tecla de flecha, cada clic, cada Tab y cada Enter. Mantén pulsada la flecha abajo y puede dispararse muchas veces por segundo. Haga lo que haga el manejador, el usuario paga ese coste en cada movimiento.

Así que el manejador debe ser O(minúsculo). El modo de fallo es inconfundible: mete aquí una consulta lenta, un For grande o un reformateo de toda la hoja y la hoja desarrolla un retardo visible — el cursor da tirones, las teclas de flecha se sienten pastosas, y los usuarios concluyen que el archivo está «roto». La regla: haz lo mínimo en SelectionChange; nunca recorras rangos grandes, accedas al disco ni recalcules desde dentro. Si necesitas trabajo pesado, dispáralo desde un botón, no al mover el cursor.

El truco que todo el mundo quiere: resaltar la fila activa (bien hecho)

El uso más solicitado de este evento, con diferencia, es resaltar la fila de la celda activa para que una tabla ancha sea fácil de leer de lado a lado. La versión ingenua funciona, pero hace daño en silencio:

' Ingenua — destruye cualquier relleno existente y los colores de Formato condicional de la hoja
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Cells.Interior.ColorIndex = xlNone            ' borra el relleno de TODAS las celdas
    Target.EntireRow.Interior.Color = RGB(255, 255, 200)
End Sub

En ella se esconden dos problemas reales. Primero, Cells.Interior.ColorIndex = xlNone borra el relleno de todas las celdas — incluidos los rellenos deliberados y los resultados del bandeado tipo Formato condicional que pusiste a mano — así que tu resaltado se come el formato del usuario. Segundo, cambiar .Interior borra la pila de deshacer de Excel: después de que el evento se ejecute, el Ctrl+Z del usuario ya no está. En una hoja de entrada de datos eso es un coste de usabilidad de verdad.

El enfoque robusto es cambiar la visualización, no el formato de las celdas — controla una regla de Formato condicional desde una celda auxiliar que actualizas en el manejador:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    ' Guarda el número de la fila activa en una celda auxiliar (digamos Z1);
    ' una regla de Formato condicional =ROW()=$Z$1 pinta la fila.
    Application.EnableEvents = False        ' escribir en Z1 es una edición — no vuelvas a disparar eventos
    Range("Z1").Value = Target.Row
    Application.EnableEvents = True
End Sub

Ahora es el Formato condicional el que pinta, no se toca ningún relleno real, y la pila de deshacer sobrevive. El manejador se mantiene minúsculo — escribe un número. Ese es el patrón al que recurrir cuando «resaltar la fila activa» tiene que convivir con formato real.

La trampa que comparte con Change: volver a seleccionar dispara de nuevo el evento

SelectionChange tiene el mismo peligro de autodisparo que Worksheet_Change, solo que a través de una acción distinta. Si tu manejador mueve la selecciónTarget.Offset(1, 0).Select, o Range("A1").Select— eso es en sí mismo un cambio de selección, que vuelve a disparar SelectionChange. Hazlo sin condiciones y obtienes recursión o un cursor que pelea contra el usuario.

Aplica el mismo arreglo: encierra cualquier cambio de selección (o escritura de celda, como la celda auxiliar de arriba) entre Application.EnableEvents = False … = True, y vuelve a activarlos en un manejador de errores para que un fallo no pueda dejar los eventos apagados de forma global:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    On Error GoTo Done
    Application.EnableEvents = False
    Range("Z1").Value = Target.Row     ' o un .Select protegido, si tienes que mover el cursor
Done:
    Application.EnableEvents = True
End Sub

Si alguna vez ves que los eventos dejan de funcionar tras experimentar aquí, un manejador que falló dejó EnableEvents apagado — la misma historia que se cuenta en VBA On Error. Ejecuta Application.EnableEvents = True en la ventana Inmediato para recuperarte.

Qué es Target en realidad: la nueva selección, quizá muchas celdas

Target es lo que esté seleccionado ahora — y eso no siempre es una sola celda. Haz clic en el encabezado de una columna y Target es la columna entera; arrastra un bloque y Target es ese bloque; haz Ctrl+clic y es un rango de varias áreas. El código que da por hecho una sola celda —Target.Value, o tratar Target.Row como «la única fila»— puede comportarse mal con una selección grande.

Dos hábitos lo mantienen a salvo: lee Target.Cells(1, 1) cuando de verdad quieras la celda activa superior izquierda, y corta por lo sano cuando una selección enorme deja el trabajo sin sentido: If Target.Cells.Count > 1000 Then Exit Sub. Eso protege el rendimiento (de vuelta a la regla de «mantenlo ligero») y evita hacer alguna tontería cuando el usuario selecciona una columna entera. SelectionChange completa el trío: reacciona al cursor, Worksheet_Change reacciona a las ediciones, y Workbook_Open reacciona a la apertura del archivo.

Cómo ayuda ExcelMaster

Una macro que sigue al cursor es un ejercicio de equilibrio: reaccionar en cada movimiento, pero hacer casi nada; resaltar la fila, pero sin comerse el formato del usuario ni su deshacer; proteger tus propios cambios de selección para que el evento no pelee consigo mismo. Es fácil escribir una que funcione y aun así haga que la hoja se sienta rota.

ExcelMaster te deja describir el efecto en su lugar. Di «resalta la fila de la celda en la que esté, sin tocar mis colores existentes», y escribe un Worksheet_SelectionChange ligero en el objeto de hoja correcto — controlando el Formato condicional desde una celda auxiliar, protegido con EnableEvents y lo bastante pequeño como para no ir con retardo. Mantienes el control total del código; te ahorras la parte en la que un resaltado bienintencionado borra el formato de un día entero.

Preguntas frecuentes

¿Qué es Worksheet_SelectionChange en VBA?

Es un evento de hoja que Excel dispara cada vez que la selección se mueve — un clic, una tecla de flecha, Tab o Enter. Excel pasa la nueva selección a tu manejador como un Range llamado Target. A diferencia de Worksheet_Change, se dispara con el movimiento, no con las ediciones, así que se usa para seguir al cursor (resaltar la fila activa, actualizar un panel de estado).

¿Cómo resalto la fila activa en Excel con VBA?

La forma robusta es guardar el número de la fila activa en una celda auxiliar desde un manejador Worksheet_SelectionChange y dejar que una regla de Formato condicional (=ROW()=$Z$1) pinte la fila. Eso evita el enfoque ingenuo de Cells.Interior.ColorIndex = xlNone, que borra los rellenos existentes y vacía la pila de deshacer cada vez que se mueve el cursor.

¿Por qué mi hoja va lenta o con retardo tras añadir SelectionChange?

Porque el evento se dispara en cada movimiento del cursor — muchas veces por segundo cuando mantienes pulsada una tecla de flecha — y tu manejador hace demasiado. Mantenlo ligerísimo: sin bucles sobre rangos grandes, sin recálculo, sin acceso a disco. Mueve el trabajo pesado a un botón, y sal pronto ante selecciones grandes con If Target.Cells.Count > 1000 Then Exit Sub.

¿Cuál es la diferencia entre SelectionChange y Change?

Worksheet_SelectionChange se dispara cuando el cursor se mueve a una nueva celda o rango; Worksheet_Change se dispara cuando cambia el contenido de una celda (tecleado, pegado, borrado o escrito por VBA). Moverte por una hoja dispara solo SelectionChange; editar un valor dispara solo Change.

¿Se dispara SelectionChange cuando muevo la selección con VBA?

Sí. Range("A1").Select desde código cuenta como un cambio de selección y dispara el evento, lo que puede causar recursión si ocurre dentro del manejador. Envuelve cualquier cambio de selección en Application.EnableEvents = False … = True, y vuelve a activar siempre los eventos en un manejador de errores.

Probado en

Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 02/08/2026.

Guías relacionadas: VBA Worksheet_Change · VBA Workbook_Open · VBA On Error · VBA Range · VBA Bucle For