TL;DR —
Worksheet_SelectionChangees 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 comoTarget, 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 conApplication.EnableEventso se volverá a disparar igual que haceWorksheet_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
Targeten 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ón —Target.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
