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

VBA ActiveWorkbook y ActiveSheet en Excel — el objeto que toca el archivo equivocado

|

VBA ActiveWorkbook y ActiveSheet en Excel — el objeto que toca el archivo equivocado

TL;DRActiveWorkbook es el libro que esté al frente ahora mismo, y ActiveSheet es la pestaña que estás mirando dentro de él. Son blancos móviles: en cuanto el usuario hace clic en otro sitio — o tu propio código selecciona algo — cambian. Por eso el clásico patrón de macro grabada de Sheets("Jan").Select y luego Selection.Value = 1 es tan frágil. Referencia la hoja y la celda directamente, y si tienes que usar el objeto activo, léelo una sola vez en una variable en lugar de recurrir a él línea tras línea.

Sub ActiveIsAMovingTarget()
    ' Fragil: selecciona, luego actua sobre lo que este seleccionado
    Worksheets("Jan").Select
    Range("A1").Select
    Selection.Value = 100          ' depende por completo del foco

    ' Fiable: nombra la hoja y la celda, sin seleccionar
    ThisWorkbook.Worksheets("Jan").Range("A1").Value = 100
End Sub

Lo que aprenderás

  • El modelo mental — el objeto activo es un blanco móvil, no una dirección
  • Las tres herramientas para nombrar un objeto, y dónde encaja el objeto activo entre ellas
  • ActiveWorkbook frente a ThisWorkbook, y por qué el activo puede sorprenderte
  • El antipatrón de Select y Activate, y por qué la grabadora de macros lo enseña
  • Cuándo actuar sobre el objeto activo es de verdad la decisión correcta
  • La opinión — lee el activo una vez, luego referencia directamente

El modelo mental: un blanco móvil, no una dirección

ActiveWorkbook y ActiveSheet no son nombres de un archivo o una pestaña concretos. Son nombres de una posición: «la que esté encima». Esa posición se mueve. El usuario haciendo clic en otra ventana la mueve. Una macro que abre un archivo la mueve. Una línea de tu propio código que llama a .Select o a .Activate la mueve. Como el blanco se mueve, el código que no para de preguntar «¿qué está activo ahora?» en realidad pregunta «¿hacia dónde apunta el ratón?» — y esa no es una pregunta de la que deba depender una macro fiable.

Contrasta eso con una dirección. ThisWorkbook.Worksheets("Jan").Range("A1") nombra el archivo, la hoja y la celda sin rodeos. Le da igual lo que esté activo. Toda la destreza del VBA a nivel de libro consiste en preferir direcciones antes que posiciones.

El objeto activo entre las tres herramientas de referencia

El objeto activo es una de las tres herramientas que VBA te da para decir sobre qué objeto actúa una línea. Saber cuándo cada una es la correcta es la columna vertebral de este grupo de guías.

Herramienta A qué apunta La trampa
ThisWorkbook El libro que contiene este código — fijo Nunca el archivo equivocado, pero tampoco nunca otro archivo
ActiveWorkbook / ActiveSheet Lo que esté al frente ahora mismo Se mueve cuando se mueve el foco — incluido por tu propio .Select
Worksheets(...) Una hoja con nombre dentro de un libro Debes conocer el nombre, el índice o el CodeName

El objeto activo se gana su sitio para exactamente un trabajo: una herramienta genérica que debe actuar sobre «lo que sea que el usuario esté mirando» — un complemento de formato, una utilidad rápida atada a un botón. Para cualquier cosa que pertenezca a un archivo concreto o a una hoja concreta, una dirección le gana al objeto activo cada vez.

ActiveWorkbook frente a ThisWorkbook: el que te sorprende

ActiveWorkbook y ThisWorkbook son imágenes especulares. ThisWorkbook está fijado al archivo propio de la macro; ActiveWorkbook sigue al usuario. Coinciden solo mientras hay un único libro abierto, que es justo por lo que la diferencia se esconde durante las pruebas y aparece en producción.

Sub Mirror()
    Debug.Print ThisWorkbook.Name     ' el archivo con el codigo - siempre el mismo
    Debug.Print ActiveWorkbook.Name   ' el archivo al frente - podria ser cualquiera
End Sub

Hay una segunda sorpresa que conviene nombrar: ActiveWorkbook puede ser Nothing. Si todas las ventanas de libro están ocultas, o solo se ve el editor de VBA, no hay libro activo y tocarlo lanza un error. ThisWorkbook siempre existe. Ante la duda de en cuál debe confiar el código, confía en el que no puede desvanecerse.

El antipatrón de Select y Activate

Enciende la grabadora de macros, haz clic en una pestaña, clic en una celda, teclea un valor, y escribe esto:

Sheets("Jan").Select
Range("A1").Select
ActiveCell.Value = 100

Toda macro grabada se construye a base de .Select y .Activate porque es, literalmente, lo que la grabadora te ve hacer. Funciona, así que los principiantes lo conservan — y entonces se topan con tres problemas. Es lento (cada selección redibuja la pantalla), es frágil (cada línea posterior se apoya en Selection / ActiveCell, así que un clic despistado o un MsgBox que roba el foco lo descarrila) y no puede actuar sobre una hoja que el usuario no está mirando sin zarandear su vista de un lado a otro.

La cura es saltarte la selección por completo y nombrar lo que quieres decir:

' Antipatron - selecciona, luego actua sobre la seleccion
Sheets("Jan").Select
Range("A1").Select
Selection.Value = 100

' Directo - una linea, sin cambios de foco, funciona en cualquier hoja
ThisWorkbook.Worksheets("Jan").Range("A1").Value = 100

Casi nunca necesitas .Select ni .Activate en código real. Las raras excepciones son cuando quieres dejar al usuario en una hoja concreta al final, o una API que de verdad exige una selección. Todo lo demás debería referenciar el objeto directamente.

Cuándo actuar sobre el objeto activo es de verdad lo correcto

El objeto activo no siempre está mal — está mal por defecto. Es exactamente lo correcto cuando la macro es una herramienta genérica cuyo único propósito es «haz esto a lo que sea que el usuario tenga abierto»: una utilidad que da formato a la selección actual, aplica un estilo de la casa a la hoja activa o exporta a PDF el libro que está al frente. En esos casos el objeto activo es el objetivo buscado, y codificar a mano un nombre de libro sería el bug.

Aun así, léelo una vez en una variable al principio y trabaja a través de esa variable, para que el objetivo no pueda desplazarse a mitad de macro:

Sub FormatWhateverIsOpen()
    Dim ws As Worksheet
    Set ws = ActiveSheet            ' captura el objetivo una vez, ahora mismo
    ws.UsedRange.Font.Bold = False
    ws.Range("A1").Value = "Reviewed"
    ' ...nada de aqui depende ya de lo que este activo...
End Sub

La opinión: lee el activo una vez, luego referencia directamente

Recurre a ActiveWorkbook o a ActiveSheet solo cuando «lo que sea que el usuario tenga delante» es de verdad lo que quieres decir — y cuando lo hagas, captúralo en una variable en la primera línea y no vuelvas a tocar el objeto activo en vivo. Para todo lo demás, nombra el objeto: ThisWorkbook para tu propio archivo, una variable de libro con Set para otro archivo concreto, y un Worksheets(...) calificado para la hoja. Borra .Select y .Activate de las macros que te dio la grabadora; son la señal más clara de que una macro se apoya en el foco en lugar de decir lo que quiere decir.

Cuando preferirías no gestionar nada de esto a mano

Reescribir una macro grabada para arrancar cada .Select y calificar cada referencia es justo la clase de limpieza que merece la pena hacer y resulta tediosa de hacer. ExcelMaster toma el resultado en lenguaje natural — «pon los totales del mes pasado en la pestaña de resumen de este archivo, sin cambiar lo que sea que el usuario esté mirando» — escribe el código directo y calificado, respalda tu libro y lo ejecuta. Tú describes el resultado; él produce código que nunca depende de lo que esté activo por casualidad.

Preguntas frecuentes

¿Cuál es la diferencia entre ActiveWorkbook y ThisWorkbook?

ActiveWorkbook es el libro que esté al frente en el momento en que corre una línea, así que cambia según el usuario o tu código cambien el foco. ThisWorkbook es el libro que contiene el código en ejecución y no cambia nunca. Usa ThisWorkbook para el archivo propio de tu macro y ActiveWorkbook solo cuando quieras decir a propósito lo que sea que el usuario tenga delante.

¿Cómo evito Select y Activate en VBA?

Referencia el objeto directamente en lugar de seleccionarlo. Sustituye Range("A1").Select y luego Selection.Value = 1 por un único ThisWorkbook.Worksheets("Jan").Range("A1").Value = 1. Declara una variable Worksheet una vez con Set y trabaja a través de ella, para que ninguna línea dependa de lo que esté seleccionado en ese momento.

¿Por qué ActiveSheet es arriesgado en una macro?

Porque es un blanco móvil: es la pestaña que esté encima cuando corre la línea, que puede cambiar si el usuario hace clic en otro lado o tu propio código activa otra cosa. Una macro que no para de recurrir a ActiveSheet puede actuar sobre la hoja equivocada sin ningún error. Captúralo en una variable una vez, o nombra la hoja directamente.

¿Cómo asigno a una variable la hoja activa?

Usa Dim ws As Worksheet y luego Set ws = ActiveSheet al principio de la macro, y usa ws a partir de ahí. Leer la hoja activa una sola vez congela tu objetivo para que no pueda desplazarse a mitad de macro, que es la forma segura de usar el objeto activo cuando de verdad es lo que quieres decir.

¿Cuándo debería usar de verdad ActiveWorkbook?

Cuando la macro es una herramienta genérica pensada para actuar sobre lo que sea que el usuario tenga abierto — un formateador, una utilidad rápida, un botón de exportar — en lugar de sobre un archivo concreto. En esos casos ActiveWorkbook es el objetivo buscado; para cualquier cosa atada a un archivo en particular, usa ThisWorkbook o una variable de libro en su lugar.

Probado en

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

Guías relacionadas: VBA ThisWorkbook · VBA Worksheets · VBA ActiveSheet · VBA Range · VBA Worksheet