TL;DR —
Selectiones un puntero vivo a lo que esté resaltado ahora mismo. La mayoría de las veces es unRange—una celda o muchas—, así que puedes recorrerlo, sumarlo o darle formato. PeroSelectionpuede ser con la misma facilidad un gráfico, una forma o un grupo de objetos, y entonces código comoFor Each c In SelectionoSelection.Valuelanza un error en tiempo de ejecución. El hábito profesional tiene dos partes: protégete conTypeName(Selection) = "Range"antes de tocar celdas y, para todo lo que no sea una herramienta guiada por el usuario, no usesSelectionen absoluto — nombra el rango que quieres.
Sub SumTheSelection()
' Protégete primero: Selection no siempre es un rango
If TypeName(Selection) <> "Range" Then
MsgBox "Select some cells first.", vbExclamation
Exit Sub
End If
Dim cell As Range, total As Double
For Each cell In Selection.Cells
If IsNumeric(cell.Value) Then total = total + cell.Value
Next cell
MsgBox "Sum of selection: " & total
End Sub
Selection parece sencillo —es «lo que resalté»— y para una herramienta rápida que
actúa sobre lo que sea que eligió el usuario, es justo lo correcto. Los problemas
empiezan cuando el código da por hecho que la selección es un bloque ordenado de
celdas. A menudo no lo es, y el fallo es un cierre en seco en lugar de una respuesta
equivocada. Esta guía trata de saber qué puede ser realmente Selection y de manejar
cada caso.
Lo que aprenderás
- El modelo mental — un puntero vivo al resaltado, no un rango que nombraste
- La regla que lo hace útil — normalmente un rango que puedes recorrer
- La regla que rompe el código —
Selectionno siempre es un rango Selectionfrente aActiveCell— todo el resaltado frente a la única ancla- Selecciones de varias áreas — la trampa de
.Areascon Ctrl+clic - La lección de fondo — referencia los rangos de forma explícita en el código no interactivo
El modelo mental: un puntero vivo al resaltado
Como ActiveCell, Selection no tiene identidad fija. No
es una celda ni un rango que declaraste — es la respuesta de Excel a la pregunta «¿qué
está resaltado en la ventana activa en este instante?». Haz clic en otra celda y
Selection significa otra cosa. Ejecuta una macro el lunes con una columna resaltada y
el martes con un gráfico seleccionado, y Selection es un Range un día y un Chart
al siguiente.
Eso es lo que hace a Selection potente para las herramientas —un botón que da
formato a «lo que sea que elegí» necesita justo esto— y peligroso para la
automatización, donde el resaltado es lo que el usuario haya dejado atrás. Lo más
importante que hay que saber sobre Selection es que no controlas su tipo.
La regla que lo hace útil: normalmente un rango que puedes recorrer
Cuando la selección es celdas, Selection es un Range, y se aplica cada truco de
rango. El patrón más común es recorrer las celdas seleccionadas:
Sub HighlightNegatives()
Dim cell As Range
For Each cell In Selection.Cells
If IsNumeric(cell.Value) Then
If cell.Value < 0 Then cell.Interior.Color = vbRed
End If
Next cell
End Sub
Miembros útiles cuando la selección es un rango:
Selection.Cells.Count— cuántas celdas están resaltadasSelection.Rows.Count/Selection.Columns.Count— su formaSelection.Address— la dirección resaltada, p. ej.$B$2:$D$10Selection.Value— pero solo tiene sentido para una sola celda; en una selección de varias celdas devuelve una matriz 2D, y asignarx = Selection.Valuea un escalar te da solo la primera celda o un error
Ese último punto es el silencioso: Selection.Value no te da «la suma» ni «los
valores» de un bloque de la forma que esperan la mayoría de los principiantes. Para
trabajar sobre una selección de varias celdas, la recorres (como arriba) o la lees en
una matriz.
La regla que rompe el código: Selection no siempre es un Range
Este es el error número uno con Selection. Tu macro recorre la selección, funciona a
la perfección durante semanas y luego un usuario la ejecuta con un gráfico seleccionado
y se cae con «El objeto no admite esta propiedad o método» (error 438) o «Se
requiere un objeto» (error 424). Nada está roto — la selección sencillamente no es un
rango:
' Lo que Selection puede ser, según lo que esté seleccionado:
' celdas -> Range
' un objeto gráfico -> ChartObject / Chart
' una forma -> Shape
' varios objetos -> DrawingObjects
' nada usable -> depende del contexto
La solución es una comprobación de una línea al inicio de cualquier macro que espere celdas — revisa el tipo antes de tocarlo:
Sub NeedsCells()
If TypeName(Selection) <> "Range" Then
MsgBox "This tool works on cells. Select a range first.", vbExclamation
Exit Sub
End If
' ...a partir de aquí es seguro tratar Selection como un Range...
End Sub
TypeName(Selection) devuelve la cadena "Range" cuando hay celdas resaltadas, y
"ChartObject", "Rectangle", "Picture", etc. en los demás casos. Convierte esta
comprobación en un reflejo en cualquier herramienta basada en la selección — es la
diferencia entre un aviso amable y un cierre en las narices del usuario.
Selection frente a ActiveCell: todo el resaltado frente a la única ancla
Se confunden constantemente, así que ten clara la división:
Selection |
ActiveCell |
|
|---|---|---|
| Alcance | Todo el resaltado | La única celda ancla |
| Cantidad | Una o muchas celdas (o un objeto que no es celda) | Siempre exactamente una celda |
| ¿Siempre un rango? | No — puede ser una forma/gráfico | Solo una celda (da error en una hoja de gráfico) |
Leer .Value |
Matriz en varias celdas | Siempre un único valor |
| Úsalo para | «Todo lo que eligió el usuario» | «La única celda enfocada» |
Trabajan juntos: ActiveCell es el ancla dentro de Selection. Mira
VBA ActiveCell para la cara de una sola celda de la pareja.
La trampa de varias áreas: Ctrl+clic crea varias Areas
Hay un problema de forma más sutil incluso cuando Selection es un rango. Si el
usuario hace Ctrl+clic para resaltar A1:A5 y C1:C5, esa es una sola selección
compuesta de dos áreas. Un único bucle sobre Selection.Cells sigue visitando
todas las celdas — pero el código que razona sobre «el rango» (su dirección, sus
esquinas, Selection.Rows.Count) puede obtener la respuesta equivocada, porque esos se
aplican solo a la primera área:
Sub WalkAllAreas()
Dim area As Range, cell As Range
Debug.Print "Areas selected: " & Selection.Areas.Count ' p. ej. 2
For Each area In Selection.Areas
For Each cell In area.Cells
' ...procesar cada celda de cada área...
Next cell
Next area
End Sub
La regla: cuando una selección pueda no ser contigua, recorre Selection.Areas, no
solo Selection. Es la misma clase de error de «la forma no es la que supuse» que el
caso de no-rango de arriba.
La lección de fondo: nombra el rango para el código no interactivo
Todo lo anterior trata de manejar Selection con seguridad — pero la lección más
profunda es saber cuándo evitarlo. Selection depende por completo del estado de la
interfaz, cambia bajo tus pies y no significa nada cuando una macro se ejecuta sin
supervisión. Así que:
- Usa
Selectionpara herramientas genuinamente interactivas — un botón de la cinta, un ayudante del clic derecho, una macro de «da formato a lo que elegí». Ahí, «lo que sea que resaltó el usuario» es la entrada. - No uses
Selectionpara la automatización que apunta a datos conocidos. Referencia el rango directamente —Worksheets("Data").Range("A1:A100")— para que la macro sea independiente de dónde esté el cursor.
Es el mismo principio que no seleccionar celdas antes de actuar sobre ellas, tratado en VBA Select frente a Activate: cuantas menos de tus macros dependan de la selección viva, menos se rompen cuando un usuario hace clic en un sitio inesperado.
Cómo ayuda ExcelMaster
Las trampas de Selection —un gráfico en lugar de celdas, un Ctrl+clic que se divide
en áreas, un Selection.Value que no es el valor que querías— compilan todas bien y
solo muerden en tiempo de ejecución, con el clic de otra persona. Escribir a mano las
comprobaciones y los bucles de áreas es engorroso y fácil de olvidar.
ExcelMaster te
deja describir la herramienta en su lugar. Pide «un botón que sume las celdas que tenga
seleccionadas» y escribe por ti la comprobación de TypeName y el bucle consciente de
las áreas; pide «limpia la columna A de la hoja Data» y se salta Selection por
completo y referencia el rango directamente. Conservas una macro legible sin tener que
acordarte de cada forma en que una selección puede sorprenderte.
Preguntas frecuentes
¿Cómo recorro las celdas seleccionadas en VBA?
Usa For Each cell In Selection.Cells. Por ejemplo:
For Each cell In Selection.Cells: Debug.Print cell.Address: Next cell. Protégete
primero con If TypeName(Selection) <> "Range" Then Exit Sub, porque un bucle sobre
una selección que no es un rango (como un gráfico) lanza un error. Para selecciones con
Ctrl+clic, recorre Selection.Areas y luego las celdas de cada área.
¿Por qué mi código de Selection da el error 438 o 424?
Porque Selection no es un Range en ese momento — se seleccionó un gráfico, una
forma u otro objeto en lugar de celdas, y no admite miembros de rango como .Cells o
.Value. Añade If TypeName(Selection) <> "Range" Then Exit Sub al inicio de la macro
para que salga limpiamente (o avise al usuario) en lugar de caerse.
¿Cuál es la diferencia entre Selection y ActiveCell?
Selection es toda la región resaltada y puede ser muchas celdas — o incluso una forma
o un gráfico. ActiveCell es siempre la única celda ancla dentro de esa selección. Usa
ActiveCell para la única celda enfocada y Selection cuando necesites todo lo que
resaltó el usuario.
¿Cómo obtengo el número de celdas seleccionadas?
Usa Selection.Cells.Count para el número total de celdas, Selection.Rows.Count y
Selection.Columns.Count para su forma, y Selection.Areas.Count para ver si es un
solo bloque o un Ctrl+clic de varias áreas. Recuerda que los recuentos de
filas/columnas describen solo la primera área cuando la selección no es contigua.
¿Debo usar Selection o referenciar el rango directamente?
Usa Selection solo para herramientas interactivas que actúan sobre «lo que sea que
eligió el usuario». Para la automatización que apunta a datos conocidos, referencia el
rango de forma explícita —por ejemplo Worksheets("Data").Range("A1:A100")— para que
la macro no dependa de dónde esté el cursor y no pueda actuar sobre las celdas
equivocadas.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 03/08/2026.
Guías relacionadas: VBA ActiveCell · VBA Select frente a Activate · VBA Range · VBA For Each · VBA Worksheet_SelectionChange
