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

VBA VarType y TypeName en Excel — pregúntale a un valor qué es antes de usarlo

|

VBA VarType y TypeName en Excel — pregúntale a un valor qué es antes de usarlo

TL;DR — Todo Variant lleva una etiqueta de tipo. VarType la devuelve como número (vbDouble es 5, vbString es 8), y TypeName la devuelve como palabra ("Double", "String", "Range"). En Excel, la etiqueta del valor de una celda la pone la celda, no tu código: un número entero llega como Double, un número con formato de moneda como Currency redondeado a cuatro decimales, uno con formato de fecha como Date, un error como Error, y un rango de varias celdas como una matriz. Pregunta por la etiqueta en los bordes de tu código, donde los valores llegan de celdas, de la selección del usuario o de un parámetro Variant, y declara tipos reales en todo lo demás.

Debug.Print TypeName(Range("A1").Value)   ' Double, String, Date, Boolean, Error, Empty...
Debug.Print VarType(Range("A1").Value)    ' 5, 8, 7, 11, 10, 0...
Debug.Print TypeName(Selection)           ' Range, o ChartArea, Rectangle, Picture...

Este es el segundo artículo de una serie sobre preguntarle a un valor qué es: IsEmpty comprueba una sola etiqueta, aquí VarType y TypeName leen cualquier etiqueta, e IsNull comprueba la etiqueta que significa «mixto o desconocido». La idea de la serie es que un valor de VBA lleva una etiqueta de tipo aparte de su contenido, y estas funciones leen la etiqueta, no el aspecto del valor.

Lo que aprenderás

  • El modelo mental: la etiqueta la pone la celda, no tu código
  • Constantes de VarType y cadenas de TypeName
  • Por qué un número entero es un Double, y un formato de moneda redondea tus datos
  • VarType mira a través de los objetos; TypeName los nombra
  • La trampa de la matriz: una celda frente a varias
  • Comprobar qué ha seleccionado el usuario
  • Dónde preguntar, y dónde declarar en su lugar

El modelo mental: la etiqueta la pone la celda, no tu código

Cuando escribes Dim total As Double, el tipo lo decides tú. Cuando lees Range("A1").Value, no: Excel te entrega un Variant, y lo que hay dentro lo decide la celda. La misma línea de código recibe un número en una fila, texto en la siguiente, un error en la tercera y nada en la cuarta.

VarType y TypeName te dejan ver esa decisión antes de actuar sobre ella. No convierten nada y nunca fallan: solo informan de la etiqueta.

Constantes de VarType y cadenas de TypeName

Las etiquetas que encontrarás al trabajar con Excel, con sus dos nombres:

Celda o valor VarType constante TypeName
celda sin tocar 0 vbEmpty "Empty"
mixto o desconocido 1 vbNull "Null"
cualquier número, incluido 42 5 vbDouble "Double"
número con formato de moneda 6 vbCurrency "Currency"
número con formato de fecha 7 vbDate "Date"
texto 8 vbString "String"
#N/A, #DIV/0! y otros errores 10 vbError "Error"
VERDADERO o FALSO 11 vbBoolean "Boolean"
el valor de un rango de varias celdas 8204 vbArray + vbVariant "Variant()"

Una variable Long da 3 (vbLong), una Integer da 2, y una variable de objeto da "Range", "Worksheet", "Workbook" o "Nothing" con TypeName. TypeName siempre devuelve el nombre en inglés, en cualquier idioma de Office, así que es seguro compararlo con una cadena.

La forma natural de usar la etiqueta es un Select Case que trate cada clase de celda:

Sub DescribeCell(ByVal c As Range)
    Dim v As Variant
    v = c.Value
    Select Case VarType(v)
        Case vbEmpty:              Debug.Print c.Address, "empty"
        Case vbString:             Debug.Print c.Address, "text: " & v
        Case vbDouble, vbCurrency: Debug.Print c.Address, "number: " & v
        Case vbDate:               Debug.Print c.Address, "date: " & Format$(v, "yyyy-mm-dd")
        Case vbBoolean:            Debug.Print c.Address, "logical: " & v
        Case vbError:              Debug.Print c.Address, "error: " & c.Text
    End Select
End Sub

Por qué un número entero es un Double, y un formato de moneda redondea tus datos

Dos sorpresas salen del mismo hecho: Excel guarda todos los números como Double, y .Value los viste según el formato de la celda.

Un número entero es un Double. Una celda que contiene 42 devuelve vbDouble, no vbLong. El código que comprueba If VarType(c.Value) = vbLong nunca coincide con una celda. Para preguntar «¿es un número entero?», comprueba primero la etiqueta y después el valor, en dos pasos, porque el And de VBA evalúa los dos lados e Int falla con texto: If VarType(v) = vbDouble Then isWhole = (v = Int(v)).

El formato cambia la etiqueta. Si una celda tiene formato de moneda, .Value devuelve un Currency; si tiene formato de fecha, devuelve un Date. Un compañero que cambia el formato de una columna cambia lo que recibe tu código, sin tocar un solo valor. Además, Currency solo guarda cuatro decimales, así que una celda con formato de moneda que contiene un tipo de cambio de 1,234567 se lee como 1,2346.

.Value2 no aplica ese disfraz: devuelve un Double para números, fechas y moneda por igual, con toda la precisión. En código de cálculo, lee .Value2:

Debug.Print TypeName(Range("B2").Value)    ' Currency  (B2 con formato $)
Debug.Print TypeName(Range("B2").Value2)   ' Double

La guía de Value2 trata el lado de las fechas de esa misma diferencia.

VarType mira a través de los objetos; TypeName los nombra

Pasa el propio Range, no su valor, y las dos funciones discrepan:

Debug.Print TypeName(Range("A1"))     ' Range
Debug.Print VarType(Range("A1"))      ' 5 si A1 contiene un numero, no vbObject

VarType mira a través de un objeto que tiene propiedad predeterminada e informa del tipo de esa propiedad. La propiedad predeterminada de un Range es su valor, así que VarType(Range("A1")) describe el contenido de la celda, y solo un objeto sin propiedad predeterminada devuelve vbObject (9). TypeName informa del objeto en sí.

Así que la regla es sencilla: usa TypeName (o TypeOf) para preguntar qué es un objeto, y VarType para preguntar qué es un valor.

La trampa de la matriz: una celda frente a varias

Leer un rango en un Variant es la forma rápida de procesar datos, y esconde una trampa:

Dim data As Variant
data = Range("A2:A" & lastRow).Value
Debug.Print data(1, 1)                ' Run-time error 13 cuando lastRow = 2

Cuando el rango tiene más de una celda, data es una matriz bidimensional. Cuando lastRow es 2 y el rango es una sola celda, data es simplemente el valor de esa celda, e indexarlo falla con el error 13, Type mismatch («No coinciden los tipos» en un Excel en español). Los informes funcionan durante meses y fallan el día en que solo hay una fila.

Compruébalo con IsArray y envuelve tú mismo el valor único:

If Not IsArray(data) Then
    Dim one(1 To 1, 1 To 1) As Variant
    one(1, 1) = data
    data = one
End If

IsArray(v) es la misma prueba que (VarType(v) And vbArray) <> 0. La guía de matrices trata la lectura de rangos en matrices.

Comprobar qué ha seleccionado el usuario

El uso real más habitual de TypeName es una protección al principio de una macro que trabaja con la selección. Puede que el usuario haya hecho clic en un gráfico, una forma o una imagen en lugar de en celdas:

Sub FormatSelectedCells()
    If TypeName(Selection) <> "Range" Then
        MsgBox "Select some cells first."
        Exit Sub
    End If
    Selection.NumberFormat = "#,##0.00"
End Sub

Sin la protección, Selection.NumberFormat lanza el error 438 (Object doesn't support this property or method, «El objeto no admite esta propiedad o método» en un Excel en español) cuando hay un gráfico seleccionado. If Not TypeOf Selection Is Range Then hace la misma comprobación, y el compilador detecta una errata en Range, cosa que no puede hacer con la cadena "Range". Usa TypeOf en la lógica y TypeName cuando quieras mostrar o registrar el nombre. La guía de Selection cubre el resto.

La decisión de criterio: pregunta en los bordes, declara en todo lo demás

VarType y TypeName son controles fronterizos. Úsalos donde los valores entran en tu código desde fuera: el valor de una celda, la selección del usuario, un parámetro Variant, un elemento de una Collection, el resultado de Application.Match. Dentro de tu propio código, declara Long, String, Double y Range, y deja que el compilador haga las comprobaciones.

Si encuentras comprobaciones con VarType repartidas por el centro de una macro, el arreglo de verdad es leer cada valor una vez, comprobar su etiqueta una vez en la frontera y convertirlo allí en una variable declarada. Un único Select Case VarType a la entrada es más claro y más rápido que una docena de comprobaciones If TypeName más adentro.

Cómo ayuda ExcelMaster

Las sorpresas de tipo vienen de los datos, no del código: una columna a la que se le puso formato de moneda, una búsqueda que devuelve #N/A, un filtro que deja una sola fila.

ExcelMaster lee las celdas, los formatos y los errores reales de tu libro antes de escribir el código, para que la macro maneje los tipos que tu hoja contiene de verdad, incluido el caso de una sola fila y las filas con error.

Preguntas frecuentes

¿Qué diferencia hay entre VarType y TypeName en VBA?

VarType devuelve el tipo como número, por ejemplo 5 para Double u 8 para String. TypeName lo devuelve como palabra, por ejemplo "Double" o "Range". Con objetos, TypeName nombra el objeto, mientras que VarType informa del tipo de su propiedad predeterminada.

¿Cómo compruebo el tipo de dato de una celda en VBA?

Usa TypeName(Range("A1").Value) o VarType(Range("A1").Value). Un número devuelve Double; un texto, String; un número con formato de fecha, Date; uno con formato de moneda, Currency; un error, Error; y una celda sin tocar, Empty.

¿Por qué VarType devuelve Double para un número entero?

Excel guarda todos los números como Double, así que una celda que contiene 42 devuelve vbDouble. Para comprobar si es un número entero, prueba v = Int(v) después de confirmar que el valor es numérico.

¿Cómo compruebo si la selección es un rango en VBA?

Usa If TypeName(Selection) = "Range" Then o If TypeOf Selection Is Range Then. Si hay un gráfico o una forma seleccionados, TypeName devuelve en su lugar el nombre de ese objeto.

¿Qué significa VarType 8204?

8204 es vbArray + vbVariant (8192 + 12): una matriz de Variants. Es lo que obtienes del valor de un rango de varias celdas.

Probado en

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

Guías relacionadas: VBA IsEmpty · VBA IsNull · VBA Data Types · VBA Value2 · VBA Array · VBA Selection · VBA Select Case · VBA IsNumeric