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

VBA Worksheet en Excel — referenciar una hoja por nombre, CodeName o índice (y en cuál confiar)

|

VBA Worksheet en Excel — referenciar una hoja por nombre, CodeName o índice (y en cuál confiar)

Resumen (TL;DR) — Una hoja tiene tres asas y solo una es segura. Sheets("Jan") usa el nombre de la pestaña: el usuario puede renombrarla y tu macro muere con «subíndice fuera del intervalo». Sheets(1) usa la posición: arrastra una pestaña y tu macro escribe en silencio en la hoja equivocada. Sheet1 (el CodeName, fijado en el VBE) es la que el usuario no puede tocar desde Excel, así que nunca se rompe. Captura una referencia una sola vez — Set ws = ThisWorkbook.Worksheets("Data") — y deja de usar .Select/.Activate.

Una hoja está un nivel por debajo del libro: el libro contiene hojas, una hoja contiene rangos. El dolor recurrente no es usar una hoja, sino nombrarla. Si te equivocas en la referencia, tu macro o se cae a gritos o, peor, escribe en la pestaña equivocada sin un solo error.

Qué aprenderás

  • Las tres formas de referenciar una hoja y cuáles dos te traicionan
  • Por qué el CodeName es el asa a prueba de balas (y dónde fijarlo)
  • La diferencia entre Sheets y Worksheets (no son sinónimos)
  • Por qué .Select y .Activate son hábitos de la grabadora de macros, no código real

El modelo mental: tres asas, dos de ellas se mueven

Una hoja es un objeto que puedes tomar de tres maneras. Dos de esas asas están atadas a cosas que controla el usuario — el nombre de la pestaña y el orden de las pestañas — así que se mueven bajo tus pies. La tercera, el CodeName, está atada a algo que solo controlas desde el VBE.

Sub ThreeWaysToGrabASheet()
    ' 1) Por NOMBRE de pestaña — el usuario puede renombrarla -> se rompe
    Debug.Print Worksheets("Jan").Name

    ' 2) Por ÍNDICE (posición) — el usuario puede reordenar -> hoja equivocada en silencio
    Debug.Print Worksheets(1).Name

    ' 3) Por CODENAME — fijado en el VBE, invisible al usuario -> a prueba de balas
    Debug.Print Sheet1.Name     ' "Sheet1" es el CodeName, no el texto de la pestaña
End Sub

Por qué importa: las asas #1 y #2 dependen del comportamiento del usuario. Alguien renombra «Jan» como «January» o la arrastra detrás de «Feb», y tu macro o lanza error de ejecución 9 («subíndice fuera del intervalo») o — mucho más peligroso — sigue corriendo y edita la pestaña equivocada. El asa #3 es inmune porque el CodeName vive en el código, no en la pestaña.

La regla: fija un CodeName o captura la referencia una vez

El modo de fallo es usar un asa móvil en lo profundo de tu macro. La solución es clavar la hoja una vez, arriba, y luego hablar solo con esa variable.

Sub SafeSheetReference()
    ' Captura la referencia una vez — calificada hasta el libro
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("Data")

    ' De aquí en adelante, todo pasa por ws. Sin «activo», sin volver a buscar.
    ws.Range("A1").Value = "Report"
    ws.Range("A2:A100").ClearContents
    Debug.Print ws.UsedRange.Rows.Count
End Sub

Para hacer el nombre mismo irrompible, dale a la hoja un CodeName: en el VBE, selecciona la hoja bajo Microsoft Excel Objects, abre la ventana Propiedades (F4) y fija (Name). Ahora puedes escribir Set ws = SalesData y renombrar la pestaña en Excel no cambia nada. El juicio: si una macro debe sobrevivir a que otros usen el archivo, referencia las hojas por CodeName — los nombres de pestaña son contenido del usuario, no código.

Sheets vs. Worksheets — no es la misma colección

Esto hace tropezar a casi todos. Worksheets son solo las hojas de cuadrícula. Sheets es todo lo que tiene pestaña, incluidas las hojas de gráfico. Itera sobre la colección equivocada y darás con una hoja de gráfico que no tiene .Range, y te caes.

Sub SheetsVsWorksheets()
    ' Worksheets: SOLO hojas de cuadrícula — seguras para .Range / .Cells
    Dim ws As Worksheet
    For Each ws In ThisWorkbook.Worksheets
        ws.Range("A1").Value = "Auditado"
    Next ws

    ' Sheets: cuadrícula MÁS hojas de gráfico — .Range en una de gráfico = caída
    Debug.Print ThisWorkbook.Worksheets.Count   ' solo cuadrículas
    Debug.Print ThisWorkbook.Sheets.Count        ' cuadrículas + gráficos
End Sub

La regla práctica: si tu bucle toca celdas, itera Worksheets, nunca Sheets. Recurre a Sheets solo cuando de verdad necesites hojas de gráfico en la mezcla.

Deja de usar .Select y .Activate

La grabadora de macros escribe Sheets("Data").Select y luego Range("A1").Select porque solo puede grabar lo que hiciste clic. El código real se salta el clic por completo: habla directamente con el objeto hoja. Seleccionar es lento, parpadea la pantalla y (porque cambia el ActiveSheet) prepara justamente los errores de hoja equivocada de arriba.

' Estilo grabadora — selecciona, luego actúa sobre la selección (frágil)
Sheets("Data").Select
Range("A1").Select
Selection.Value = 100

' Código real — una línea, sin selección, sin depender de ActiveSheet
ThisWorkbook.Worksheets("Data").Range("A1").Value = 100

Casi nunca necesitas seleccionar una hoja para leerla o escribirla. Por qué «activo» es una trampa de entrada lo ves en VBA ActiveSheet.

Cómo ayuda ExcelMaster

La mayoría del VBA multihoja existe para barajar datos entre pestañas de forma periódica. ExcelMaster lo hace desde una descripción en lenguaje natural — «copia las filas limpias de Data a la pestaña Summary y actualiza los totales» — sin referencias de hoja que nombrar mal. Te saltas toda la clase de error de «subíndice fuera del intervalo».

VBA sigue ganándose su lugar en la automatización permanente dentro del libro. Pero para el cotidiano «mueve esto de aquella pestaña a esta», describirlo es más rápido y no se rompe cuando alguien renombra una hoja.

Preguntas frecuentes

¿Por qué obtengo «subíndice fuera del intervalo» al referenciar una hoja?

El nombre de pestaña que pasaste no existe — normalmente porque alguien renombró la hoja, o hay un espacio sobrante o un error de tipeo. Referencia por CodeName (fijado en el VBE), que el usuario no puede cambiar, o envuelve la búsqueda y verifica que la hoja exista primero.

¿Qué es un CodeName de hoja y dónde lo fijo?

El CodeName es el nombre interno que usa VBA (Sheet1, Sheet2, …), visible en el Explorador de Proyectos del VBE. Fíjalo en la ventana Propiedades (F4) → (Name). A diferencia del nombre de pestaña, el usuario no puede cambiarlo desde Excel, así que es el asa más fiable.

¿Cuál es la diferencia entre Sheets y Worksheets en VBA?

Worksheets contiene solo hojas de cuadrícula estándar. Sheets contiene todos los tipos de hoja, incluidas las de gráfico. Si tu código usa .Range o .Cells, itera Worksheets — una hoja de gráfico no tiene celdas y se cae.

¿Necesito Seleccionar o Activar una hoja para editarla?

No. ThisWorkbook.Worksheets("Data").Range("A1").Value = 1 funciona sin seleccionar nada. .Select/.Activate son artefactos de la grabadora de macros que ralentizan la macro y crean errores de hoja equivocada.

Probado en

Probado en: Excel 365 (Windows 11), VBA 7.1 — verificado por última vez el 13/06/2026.

Guías relacionadas: VBA Workbook · VBA ActiveSheet · VBA Range · VBA For Loop · VBA Dictionary