TL;DR —
Worksheets.Adddevuelve la hoja que acaba de crear. Captura ese valor de retorno —Set ws = Worksheets.Add(...)— y nunca tendrás que adivinar cuál es la hoja nueva. Las dos cosas que hacen tropezar a todo el mundo son la posición y el nombre: unWorksheets.Adda secas coloca la hoja a la izquierda de la hoja activa (no al final), y no puedes pasar el nombre en la llamada aAdd: fijas.Namedespués, donde un nombre duplicado, en blanco o demasiado largo lanza el error en tiempo de ejecución 1004.
Sub AddMonthSheet()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets.Add(After:=Worksheets(Worksheets.Count))
ws.Name = "Sep 2026" ' <= 31 caracteres, unico, sin : \ / ? * [ ]
End Sub
Worksheets.Add es el código que hay detrás de Inicio ▸ Insertar ▸ Insertar hoja y del pequeño
+ que hay junto a las pestañas. Es una de las primeras cosas que hace una macro de informes, y
falla siempre en los mismos dos sitios: la hoja aparece donde no esperabas, o la línea que la
renombra revienta. Ambos problemas desaparecen en cuanto tratas Add como una fábrica que te
entrega la hoja terminada, en lugar de como un comando que te deja a ti la tarea de ir a buscarla.
Lo que aprenderás
- El modelo mental —
Adddevuelve la hoja nueva, así que captúrala y deja de usarActiveSheet - La única regla que evita casi todos los fallos — asigna el valor de retorno a una variable
Worksheet - Por qué un
Adda secas coloca la hoja a la izquierda, y cómo lo arreglanBeforeyAfter - Por qué no puedes nombrar la hoja dentro de
Add, y las reglas que hacen que.Namelance 1004 - Cómo añadir una hoja solo si no existe ya
El modelo mental: Add te entrega la hoja
Worksheets.Add no es un comando de disparar y olvidar. Es una función que crea una hoja y devuelve
una referencia a ella. El error más común con diferencia es tirar esa referencia a la basura:
Worksheets.Add ' la hoja nueva se crea... y luego se pierde
Worksheets(Worksheets.Count).Name = "Data" ' adivinando donde acabo
La segunda línea es una conjetura. Da por hecho que la hoja nueva es la última, cosa que por defecto no es cierta, así que renombra la pestaña equivocada. Todo lo que viene después —escribir encabezados, dar formato, añadir fórmulas— apunta entonces a una hoja elegida por azar. Captura el valor de retorno en su lugar y las conjeturas desaparecen para siempre:
Dim ws As Worksheet
Set ws = Worksheets.Add
ws.Name = "Data" ' esta es sin ambiguedad la hoja que acabas de crear
Una vez que ws contiene el objeto de verdad, la posición deja de importar para la corrección:
puedes poner la hoja donde te apetezca y tu código sigue hablando con la correcta.
La regla que más importa: asigna el valor de retorno
Toda rutina fiable que añade una hoja empieza igual: Set ws = Worksheets.Add(...). Esta es la regla
que elimina una categoría entera de fallos, porque las dos alternativas frágiles se rompen en
condiciones de lo más normales:
ActiveSheetdespués deAddnormalmente apunta a la hoja nueva, pero no si un evento, unCalculateu otra línea movieron el foco antes. Es una convención, no una garantía.Sheets(Sheets.Count)da por hecho que la hoja nueva es la última, lo cual solo es cierto si la añadiste ahí.
El valor de retorno es la única referencia que siempre es correcta, de inmediato, sin importar dónde acabó la hoja ni qué se ejecute a continuación. Trata «añadir una hoja» y «quedarte con la hoja» como un único paso indivisible.
La posición: Before, After y por qué el valor por defecto cae a la izquierda
Worksheets.Add acepta los argumentos Before:= y After:= —una hoja delante de la cual insertar,
o detrás—. Pasa como mucho uno. Sin ninguno, Excel inserta la hoja nueva justo antes de la hoja
activa, cosa que sorprende a casi todo el mundo la primera vez: la gente espera «el final» y en
cambio la pestaña aparece en mitad del libro.
Para añadir al final —la posición que de verdad quieren la mayoría de las macros—, ancla a la última
hoja con After:
Set ws = Worksheets.Add(After:=Worksheets(Worksheets.Count)) ' siempre la ultima
Set ws = Worksheets.Add(Before:=Worksheets(1)) ' siempre la primera
Worksheets(Worksheets.Count) es el modismo para «la última hoja de cálculo». Fíjate en que cuenta
hojas de cálculo, no todas las hojas: si el libro también tiene hojas de gráfico, Sheets.Count y
Worksheets.Count no coinciden. En la duda, posiciona de forma explícita; nunca te fíes del valor
por defecto de izquierda-de-la-activa en código que van a leer otras personas.
El nombre es donde Add revienta
No hay ningún argumento Name en Add. Creas la hoja y luego fijas .Name sobre el objeto que
capturaste. Ese segundo paso es donde vive el error en tiempo de ejecución 1004, porque Excel impone
reglas estrictas a los nombres de hoja, y son las mismas reglas tanto si estás nombrando una hoja
recién creada como si estás renombrando una vieja:
- 31 caracteres como máximo
- Debe ser único dentro del libro (sin distinguir mayúsculas) — un duplicado es el fallo número uno
- No puede estar en blanco
- No puede contener
: \ / ? * [ ]
Incumple cualquiera de ellas y .Name = ... lanza 1004. El detonante más común es volver a ejecutar
una macro que ya creó "Data" una vez: la segunda ejecución choca. Como las reglas son idénticas
para crear y para renombrar, vale la pena blindar el nombre en un único sitio:
Function SafeName(nm As String) As String
nm = Left$(nm, 31)
Dim bad As Variant, ch As Variant
For Each ch In Array(":", "\", "/", "?", "*", "[", "]")
nm = Replace(nm, ch, "-")
Next ch
SafeName = nm
End Function
Eso resuelve la longitud y los caracteres ilegales; la unicidad la resuelves comprobando antes, que es la siguiente sección.
Añade solo si no existe ya
No hay un Exists integrado para las hojas, así que la colisión al reejecutar es cosa tuya evitarla.
Comprueba la colección por nombre antes de añadir, y reutiliza la hoja si ya está ahí:
Function GetOrAddSheet(nm As String) As Worksheet
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If StrComp(ws.Name, nm, vbTextCompare) = 0 Then
Set GetOrAddSheet = ws ' reutiliza la que ya existe
Exit Function
End If
Next ws
Set GetOrAddSheet = ThisWorkbook.Worksheets.Add(After:=Worksheets(Worksheets.Count))
GetOrAddSheet.Name = nm ' libre para nombrar - sabemos que no esta en uso
End Function
Este es el patrón que hace idempotente una macro que añade hojas —segura de ejecutar dos veces— en
lugar de una que funciona la primera vez y lanza 1004 para siempre a partir de ahí. El criterio:
nunca llames a Add y a .Name a ciegas en una rutina que podría ejecutarse más de una vez; busca
primero el nombre, y o reutiliza o crea.
Cómo te ayuda ExcelMaster
Añadir una hoja parece una sola línea y esconde tres decisiones —capturar el valor de retorno, elegir una posición y producir un nombre legal y único—, y equivocarse en cualquiera de ellas falla en silencio (renombra la pestaña equivocada) o a gritos (error 1004 en la segunda ejecución).
ExcelMaster te deja decir lo
que quieres —«añade una hoja mensual al final con el nombre del mes actual, y reutilízala si ya
existe»— y escribe la captura Set ws = Worksheets.Add(After:=...), añade en el sitio correcto, sanea
el nombre según las reglas de 31 caracteres y de caracteres ilegales, y comprueba primero la
colección para que una segunda ejecución reutilice la hoja en vez de reventar. Tú conservas el libro
y el código.
Preguntas frecuentes
¿Cómo añado una hoja y le pongo nombre en VBA?
Captura el valor de retorno y fija .Name sobre él:
Set ws = Worksheets.Add(After:=Worksheets(Worksheets.Count)) y luego ws.Name = "Data". No hay
ningún argumento Name en el propio Add. El nombre debe tener 31 caracteres o menos, ser único en
el libro, no estar en blanco y no contener : \ / ? * [ ], o .Name lanza el error en tiempo de
ejecución 1004.
¿Por qué mi hoja nueva aparece en la posición equivocada?
Porque un Worksheets.Add a secas inserta la hoja justo antes de la hoja activa, no al final.
Contrólalo con Before:= o After:=. Para añadir al final, usa
Worksheets.Add(After:=Worksheets(Worksheets.Count)); para ponerla primera, usa
Worksheets.Add(Before:=Worksheets(1)).
¿Por qué obtengo el error 1004 al añadir o nombrar una hoja?
Casi siempre es una violación de las reglas de nombres, y normalmente un duplicado. Los nombres de
hoja deben ser únicos, así que volver a ejecutar una macro que ya creó "Data" choca en la segunda
ejecución. Los nombres también deben tener 31 caracteres o menos, no estar en blanco y no contener
: \ / ? * [ ]. Comprueba el nombre en la colección antes de añadir, y sanea la cadena primero.
¿Cómo añado una hoja solo si no existe ya?
No hay ningún método Exists, así que recorre la colección Worksheets y compara nombres con
StrComp(ws.Name, nm, vbTextCompare) = 0. Si encuentras una coincidencia, reutiliza esa hoja; si no,
llama a Add y ponle nombre. Envolver esto en una función GetOrAddSheet hace que la macro sea
segura de ejecutar repetidamente.
¿Cómo añado una hoja justo al final del libro?
Ancla a la última hoja de cálculo: Worksheets.Add(After:=Worksheets(Worksheets.Count)).
Worksheets(Worksheets.Count) es la última hoja de cálculo, así que insertar después de ella añade
al final. Usa Sheets.Count en lugar de Worksheets.Count solo si quieres deliberadamente contar
también las hojas de gráfico.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 14/09/2026.
Guías relacionadas: VBA Copy Sheet · VBA Delete Sheet · VBA Worksheets · VBA Worksheet · VBA ThisWorkbook
