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

VBA Named Range en Excel — Names.Add, RefersTo, y por qué tu referencia se desvía

|

VBA Named Range en Excel — Names.Add, RefersTo, y por qué tu referencia se desvía

TL;DR — Un named range es una fórmula almacenada, no una etiqueta. Range("B2:B50").Name = "SalesData" es la forma de una línea de crear uno; Names.Add Name:="TaxRate", RefersTo:="=Sheet1!$B$1" es la forma larga. Las dos cosas que pillan a todo el mundo: RefersTo necesita un = inicial y signos $ absolutos (quítale el $ y el nombre se desvía en silencio a una celda distinta cada vez que lo usas), y un nombre tiene un ámbito — todo el libro o una sola hoja. Lee un nombre con Range("TaxRate").Value o el atajo [TaxRate].

' Una linea: ambito de libro, absoluto - el caso comun
Range("B2:B50").Name = "SalesData"

' Forma larga, con un ambito explicito y formula RefersTo
ThisWorkbook.Names.Add Name:="TaxRate", RefersTo:="=Config!$B$1"

Debug.Print Range("TaxRate").Value          ' lee el valor al que apunta el nombre
Range("SalesData").Interior.Color = vbYellow ' usa el nombre como cualquier Range

Todo el mundo echa mano de los named ranges para dejar de esparcir Range("$B$2") por toda una macro, y entonces se topa con una ristra de pequeños misterios: el nombre apunta a la celda equivocada, o a texto literal, o el mismo nombre significa dos cosas distintas en dos hojas, o un nombre sobrevive a una columna borrada y envenena cada fórmula que lo usaba. Todos vienen de una sola idea que vale la pena retener: un nombre es una fórmula RefersTo almacenada que Excel reevalúa en cada uso — así que las reglas que gobiernan las fórmulas (el = inicial, los $ absolutos, el calificador de hoja) son exactamente las reglas que gobiernan los nombres.

Lo que aprenderás

  • El modelo mental — un nombre es una fórmula almacenada, no un apodo
  • Crear un nombre — el Range.Name de una línea frente a Names.Add con RefersTo
  • Por qué $ decide entre un nombre estable y uno que se desvía con la celda activa
  • Ámbito — todo el libro frente a una sola hoja, y la colisión que provoca
  • Leer y usar un nombre, y los nombres constantes que no tienen celdas
  • Limpiar los nombres #REF! y el lastre de nombres ocultos que dejan detrás

El modelo mental: un nombre es una fórmula almacenada

Cuando creas un named range, Excel no etiqueta la celda. Almacena una fórmula RefersTo y la resuelve cada vez que aparece el nombre. SalesData no es «la celda B2:B50» congelada en su sitio — es la fórmula =Sheet1!$B$2:$B$50, evaluada bajo demanda. Lee Range("SalesData") y Excel ejecuta esa fórmula y te entrega lo que resuelva ahora.

Por eso todo lo de abajo trata en realidad de escribir bien la fórmula RefersTo:

ThisWorkbook.Names.Add Name:="SalesData", RefersTo:="=Sheet1!$B$2:$B$50"
Debug.Print ThisWorkbook.Names("SalesData").RefersTo   ' =Sheet1!$B$2:$B$50

RefersTo es una cadena que debe empezar por =, exactamente igual que al teclear en el Administrador de nombres. Quítale el =RefersTo:="Sheet1!$B$2" — y no obtienes un error; obtienes un nombre que apunta al texto literal «Sheet1!$B$2», que casi nunca es lo que querías. Ten presente que «es una fórmula» y el = deja de ser un misterio.

Crear un nombre: el de una línea y la forma larga

Para el caso común — un nombre absoluto y con ámbito de libro — asigna .Name a un rango y listo:

Range("B2:B50").Name = "SalesData"      ' ambito de libro, absoluto, una linea

Echa mano de Names.Add cuando necesitas fijar el ámbito de forma explícita, referirte a un nombre por fórmula, o guardar una constante en lugar de celdas:

ThisWorkbook.Names.Add Name:="TaxRate", RefersTo:="=Config!$B$1"   ' ambito de libro
Worksheets("Jan").Names.Add Name:="Region", RefersTo:="=Jan!$A$1:$A$9" ' ambito de hoja
ThisWorkbook.Names.Add Name:="VAT", RefersTo:="=0.2"              ' una constante, sin celdas

Las dos valen; la diferencia es el control. Range.Name = es lo más rápido y correcto para un rango sencillo; Names.Add es lo que usas en cuanto importa el ámbito o un destino que no es un rango.

Por qué $ decide entre un nombre estable y uno que se desvía

Este es el bug de los named ranges que la gente no sabe explicar: «mi nombre apunta a una celda distinta cada vez que ejecuto la macro». La causa es un nombre relativo — un RefersTo sin signos $.

' SE DESVIA - referencia relativa, resuelta contra la celda ACTIVA
ThisWorkbook.Names.Add Name:="Prev", RefersTo:="=Sheet1!A1"

' ESTABLE - referencia absoluta, siempre la misma celda
ThisWorkbook.Names.Add Name:="Anchor", RefersTo:="=Sheet1!$A$1"

Un nombre relativo se guarda relativo a donde estuviera la celda activa cuando se creó, y Excel lo reancla a la celda activa en cada uso — así que Prev podría resolverse a A1, luego a D5, luego a Z99, según la selección. Los nombres relativos son una función real y a veces útil (un nombre que significa «la celda de una a la izquierda»), pero si no lo hiciste a propósito, parece cosa de fantasmas. Escribe $ tanto en la columna como en la fila salvo que quieras específicamente que el nombre se mueva. Cuando usas Range.Name =, obtienes el absoluto automáticamente — una razón más para que sea el valor por defecto más seguro.

Ámbito: todo el libro frente a una sola hoja

Cada nombre vive en un ámbito. ThisWorkbook.Names.Add (y Range.Name =) crea un nombre con ámbito de libro, visible desde cualquier parte. Worksheets("Jan").Names.Add crea un nombre con ámbito de hoja, visible solo en esa hoja — lo que permite que Jan y Feb tengan cada una su propio nombre Region apuntando a sus propios datos.

La trampa es confundirlos:

Worksheets("Jan").Names.Add Name:="Region", RefersTo:="=Jan!$A$1:$A$9"
' Desde un modulo estandar, esto NO ve de forma fiable el nombre local de la hoja:
' Debug.Print Range("Region").Address   ' puede fallar o dar con otra Region
Debug.Print Worksheets("Jan").Range("Region").Address   ' calificalo -> funciona

A un nombre con ámbito de hoja hay que llegar a través de su hojaWorksheets("Jan").Range("Region") — no con un Range("Region") a secas desde un módulo. Decide a conciencia: una única constante para todo el archivo (TaxRate) es de ámbito de libro; una región que se repite por hoja (Region en cada pestaña mensual) es de ámbito de hoja, y la calificas cada vez. Consulta VBA Worksheet para direccionar hojas.

Leer, usar, y la trampa del nombre constante

Un nombre de rango se comporta como cualquier Range. Léelo, escríbelo, dale formato:

Range("TaxRate").Value = 0.19            ' escribe en la celda nombrada
Debug.Print Range("SalesData").Cells.Count
Set rng = ThisWorkbook.Names("SalesData").RefersToRange  ' el objeto Range

Range("TaxRate").Value lee el valor; [TaxRate] es un atajo para lo mismo (es Evaluate("TaxRate")). Pero fíjate en la última línea de arriba: .RefersToRange solo funciona cuando el nombre apunta a celdas. Si guardaste una constanteNames.Add Name:="VAT", RefersTo:="=0.2" — no hay ningún rango detrás, así que Range("VAT") y .RefersToRange lanzan un error, mientras que [VAT] y Evaluate("VAT") devuelven correctamente 0.2. Ten claro qué tipo de nombre tienes antes de tratarlo como celdas. Para saber cómo se resuelve un nombre como fórmula, consulta VBA Formula.

Limpiar los nombres #REF! y el lastre de nombres ocultos

Borra las filas o columnas que cubre un nombre y el nombre no muere — su RefersTo se convierte en =#REF!, una mina activa que rompe cada fórmula que referencia el nombre. Los nombres también viajan cuando copias una hoja, acumulándose en silencio hasta que un libro carga miles de nombres ocultos y rotos y se arrastra hasta la lentitud. Por ambas cosas auditar los nombres es una tarea de mantenimiento, no una configuración de una sola vez:

Dim nm As Name
For Each nm In ThisWorkbook.Names
    If InStr(1, nm.RefersTo, "#REF!") > 0 Then
        Debug.Print "broken: " & nm.Name & " -> " & nm.RefersTo
        nm.Delete                      ' quita la mina
    End If
Next nm

Recorre ThisWorkbook.Names, marca cualquiera cuyo RefersTo contenga #REF!, y hazles Delete. Ejecuta el mismo bucle con nm.Visible = False en la condición para encontrar los nombres ocultos que arrastró una hoja pegada. Un nombre es barato de crear y fácil de olvidar — trata la lista de nombres como algo que limpias, no solo que llenas.

Cómo ayuda ExcelMaster

Los errores de named range que cuestan tiempo de verdad no son erratas — son el nombre relativo que se desvía porque faltaba un $, el nombre con ámbito de hoja que un módulo no ve, el .RefersToRange que explota con un nombre constante, y el nombre #REF! que nadie notó hasta que salió mal un informe. Cada uno se ejecuta; solo que se resuelve en el lugar equivocado.

ExcelMaster escribe los nombres como lo haría un desarrollador cuidadoso. Pídele «nombra la celda del tipo impositivo y úsala en el cálculo», y crea un nombre absoluto y con ámbito de libro, lo referencia en todas partes en lugar de codificar a mano $B$1, y elige el ámbito de hoja solo cuando la región de verdad se repite por pestaña. Lee los valores nombrados con la llamada correcta para nombres de rango frente a nombres constantes, y puede auditar y limpiar los nombres #REF! rotos que un libro ha ido coleccionando. Tú nombras lo que quieres decir; él conecta la referencia para que una fila insertada nunca la rompa en silencio.

Preguntas frecuentes

¿Cómo creo un named range en VBA?

La forma más corta es asignar la propiedad Name de un rango: Range("B2:B50").Name = "SalesData", que crea un nombre absoluto y con ámbito de libro. Para más control usa Names.Add: ThisWorkbook.Names.Add Name:="TaxRate", RefersTo:="=Config!$B$1". La cadena RefersTo debe empezar por =, y casi siempre quieres referencias $ absolutas para que el nombre no se desvíe.

¿Cuál es la diferencia entre el ámbito de libro y el de hoja para un nombre?

Un nombre con ámbito de libro (ThisWorkbook.Names.Add o Range.Name =) es visible desde cada hoja y cada módulo. Un nombre con ámbito de hoja (Worksheets("Jan").Names.Add) es visible solo en esa hoja, así que hojas distintas pueden reutilizar el mismo nombre para sus propios datos. A un nombre con ámbito de hoja se llega a través de su hoja: Worksheets("Jan").Range("Region"), no un Range("Region") a secas.

¿Cómo obtengo el rango al que se refiere un nombre en VBA?

Usa ThisWorkbook.Names("SalesData").RefersToRange para obtener el objeto Range, o simplemente Range("SalesData") para un nombre con ámbito de libro. Para leer su valor, Range("SalesData").Value o el atajo [SalesData]. .RefersToRange solo funciona con nombres que apuntan a celdas — un nombre constante como =0.2 no tiene rango y hay que leerlo con Evaluate o [Name].

¿Por qué mi named range apunta a #REF! en VBA?

Porque se borraron las celdas a las que se refería. Borrar las filas o columnas que cubre un nombre no borra el nombre; en su lugar su RefersTo se convierte en =#REF!, y cada fórmula que usa el nombre se rompe. Audítalos recorriendo ThisWorkbook.Names y comprobando si nm.RefersTo contiene #REF!, y luego llama a nm.Delete sobre los rotos.

¿Cómo borro un named range en VBA?

Llama a .Delete sobre el nombre: ThisWorkbook.Names("SalesData").Delete, o recorre ThisWorkbook.Names y borra por una condición (por ejemplo, cualquiera cuyo RefersTo contenga #REF!). Borrar el nombre no toca las celdas; solo elimina el nombre definido, que es como limpias los nombres rotos y ocultos que se acumulan cuando se copian hojas.

Probado en

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

Guías relacionadas: VBA Range · VBA Cell Value · VBA Formula · VBA Worksheet · VBA Offset