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

VBA Selection en Excel — trabaja con lo que está resaltado (y por qué no siempre es un Range)

|

VBA Selection en Excel — trabaja con lo que está resaltado (y por qué no siempre es un Range)

TL;DRSelection es un puntero vivo a lo que esté resaltado ahora mismo. La mayoría de las veces es un Range —una celda o muchas—, así que puedes recorrerlo, sumarlo o darle formato. Pero Selection puede ser con la misma facilidad un gráfico, una forma o un grupo de objetos, y entonces código como For Each c In Selection o Selection.Value lanza un error en tiempo de ejecución. El hábito profesional tiene dos partes: protégete con TypeName(Selection) = "Range" antes de tocar celdas y, para todo lo que no sea una herramienta guiada por el usuario, no uses Selection en 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 — Selection no siempre es un rango
  • Selection frente a ActiveCell — todo el resaltado frente a la única ancla
  • Selecciones de varias áreas — la trampa de .Areas con 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 resaltadas
  • Selection.Rows.Count / Selection.Columns.Count — su forma
  • Selection.Address — la dirección resaltada, p. ej. $B$2:$D$10
  • Selection.Value — pero solo tiene sentido para una sola celda; en una selección de varias celdas devuelve una matriz 2D, y asignar x = Selection.Value a 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 Selection para 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 Selection para 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