TL;DR —
Range.NumberFormates la capa de visualización: cambia cómo se lee un número guardado y nunca toca el número en sí.Range("A1").Value = 5.4999conRange("A1").NumberFormat = "0"muestra 5 en pantalla — peroA1.Valuesigue siendo5.4999, yA1 + A1es10.9998. NumberFormat no es redondear. Esta es la capa donde «la apariencia frente al valor» te cuesta dinero de verdad, porque una fecha es solo un número de serie disfrazado, yNumberFormates el disfraz — no el número.
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Report")
ws.Range("A1").Value = 5.4999
ws.Range("A1").NumberFormat = "0" ' muestra 5...
Debug.Print ws.Range("A1").Value ' ...pero el valor sigue siendo 5.4999
De las tres capas de formato — Font para el texto,
Interior para el relleno, y NumberFormat para la visualización — esta es
la que engaña a la gente, porque el disfraz es convincente. Una fuente en rojo nunca hace pensar a
nadie que el valor cambió. Una celda que muestra 5, desde luego que sí. Esta guía se construye
alrededor de ese único hecho: NumberFormat cambia lo que ves, nunca lo que está guardado, y en
cuanto lo tienes claro, las fechas, la moneda, los porcentajes y el clásico error de «mis totales no
cuadran» cobran todos sentido.
Lo que aprenderás
- El modelo mental —
NumberFormates la capa de visualización, y la visualización no es el valor - La regla más importante — no es redondear, y el número guardado no cambia
- Por qué una fecha es un número de serie disfrazado
NumberFormat(la propiedad de la celda) frente a la funciónFormat(una cadena)- El lenguaje de los códigos de formato —
#,0, las cuatro secciones, moneda y color - La trampa de configuración regional —
NumberFormatfrente aNumberFormatLocal
El modelo mental: NumberFormat es la capa de visualización
Cada celda guarda un valor y, por separado, una regla de cómo dibujar ese valor. NumberFormat es
esa regla. Ponerla en "0.00", "$#,##0", "yyyy-mm-dd" o "0%" cambia la presentación — los
glifos que Excel pinta — mientras que el número subyacente queda intacto en Range.Value. Piensa en
la celda como algo que contiene un número, y en NumberFormat como una lente que le pones delante.
Cambia la lente y la vista cambia; el número que hay detrás no se mueve.
Esa separación es todo el tema. Es la razón por la que puedes mostrar el mismo 0.5 como 50%,
0.50 o 1/2 sin cambiar nunca el valor que usan las fórmulas — y por la que ocultar decimales para
la visualización no hace que desaparezcan.
La regla más importante: no es redondear
Dilo una vez y no lo olvides nunca: NumberFormat no redondea el valor guardado. Redondea la
imagen.
ws.Range("A1").Value = 5.4999
ws.Range("A2").Value = 5.4999
ws.Range("A1:A2").NumberFormat = "0" ' ambas se muestran como 5
ws.Range("A3").Formula = "=A1+A2" ' muestra 11? No - muestra 10.9998 redondeado a la vista...
' La suma real es 10.9998. El formato oculto los decimales; no los elimino.
Este es el error de NumberFormat más habitual de todos: formatea una columna a "0" para «dejarla
limpia», y luego mira cómo un total sale desviado por uno porque cada celda sigue arrastrando
decimales que el ojo no ve. Si necesitas que el valor en sí sea de verdad 5, tienes que cambiar el
valor, no el formato:
ws.Range("A1").Value = WorksheetFunction.Round(ws.Range("A1").Value, 0) ' ahora si es de verdad 5
Regla general: da formato cuando solo necesitas que se vea bien; Round cuando el número tiene que
estar bien. Los informes que deben cuadrar al céntimo redondean los valores; los cuadros de mando
que solo necesitan leerse limpios dan formato a la visualización. Confundir los dos es como las hojas
de cálculo acaban «desviadas por un error de redondeo».
Una fecha es un número de serie disfrazado
Las fechas hacen vívida la separación entre apariencia y valor. Excel guarda una fecha como un número
de serie — días desde el 1899-12-30 — y una fecha «es» una fecha solo por su NumberFormat:
ws.Range("B1").Value = 45900 ' solo un numero
ws.Range("B1").NumberFormat = "yyyy-mm-dd" ' ahora se LEE como fecha - el numero sigue siendo 45900
De aquí salen directamente dos consecuencias. Primera: para obtener una fecha real, con la que se
pueda hacer matemáticas, tienes que poner un valor de fecha real en la celda
(ws.Range("B1").Value = DateSerial(2025, 9, 15)) y luego darle formato — dar formato por sí solo
sobre el valor equivocado muestra una fecha equivocada. Segunda: aplicar "yyyy-mm-dd" a una cadena
de texto como "2025-09-15" no hace nada útil: el texto no tiene ningún número de serie detrás,
así que no hay número que disfrazar. Si las fechas llegan como texto, conviértelas (CDate, o
consulta VBA CStr para el problema inverso) antes de dar formato. El disfraz
solo funciona sobre un número real.
NumberFormat frente a la función Format
Hay dos cosas en VBA con «format» en el nombre, y confundirlas es una fuente real de errores. Son opuestas en un sentido importante:
Range.NumberFormates una propiedad de la celda. Fija una regla de visualización persistente y deja el número subyacente totalmente intacto y editable. Esto es lo que quieres en una hoja de cálculo.Format(value, "pattern")es una función que devuelve una String. Se trata en VBA Format, y sirve para construir texto — un cuadro de mensaje, un nombre de archivo, una etiqueta concatenada — no para dar formato a una celda.
La trampa es usar Format para meter un «número formateado» en una celda:
ws.Range("C1").Value = Format(1234.5, "$#,##0.00") ' escribe la CADENA "$1,234.50"
' C1 ahora es texto. No puedes hacerle SUM, ordenarlo numericamente ni graficarlo.
Esa celda parece con formato, pero ahora contiene texto, y su número ha desaparecido. La versión correcta conserva el número y fija la regla de visualización:
ws.Range("C1").Value = 1234.5
ws.Range("C1").NumberFormat = "$#,##0.00" ' muestra $1,234.50, sigue siendo un numero real
La regla: NumberFormat para celdas, Format para cadenas. Si el resultado tiene que seguir
siendo un número, nunca lo hagas pasar por Format.
El lenguaje de los códigos de formato
Los códigos de formato son un pequeño lenguaje, y cuatro reglas leen casi todos:
0es un dígito forzado,#es uno opcional."0.00"siempre muestra dos decimales (5pasa a5.00);"#.##"muestra hasta dos y descarta los ceros finales (5se queda en5).,agrupa los millares."#,##0"convierte1234567en1,234,567.- Los símbolos literales pasan tal cual.
$,%, los espacios y el texto entre comillas aparecen como se escriben —"$#,##0.00","0%"(que además multiplica por 100 para la visualización),"0.0 kg". - Los puntos y coma lo dividen en secciones:
positive;negative;zero;text. Esta es la potente:
' Positivos en negro, negativos en rojo entre parentesis, cero como guion, texto entre comillas literal.
ws.Range("D2:D100").NumberFormat = "#,##0.00;[Red](#,##0.00);\-;@"
[Red] (y otros nombres de color entre corchetes) fija el color de visualización por sección, y @
es el marcador de posición del texto. Rara vez necesitas las cuatro secciones, pero saber que existen
te permite leer cualquier cadena de formato que te encuentres. Para las fechas los tokens son
d/m/y y h/m/s — "yyyy-mm-dd hh:mm" — con la peculiaridad de que m significa mes
después de y o d, y minuto después de h.
La trampa de configuración regional: NumberFormat frente a NumberFormatLocal
La última trampa muerde en los libros compartidos. NumberFormat siempre usa códigos de formato en
inglés de EE. UU. — , para los millares, . para el decimal, m/d/y para las fechas — sin
importar la configuración regional que tenga el usuario. NumberFormatLocal usa los símbolos
locales del usuario (en alemán, . agrupa los millares y , es el decimal).
ws.Range("E1").NumberFormat = "#,##0.00" ' portable: mismo resultado en toda maquina
ws.Range("E2").NumberFormatLocal = "#.##0,00" ' codigos al estilo aleman - solo correcto en configuracion regional alemana
Escribe tus macros contra NumberFormat con códigos de EE. UU. y se comportarán igual en todas
partes. Echa mano de NumberFormatLocal solo cuando lees o igualas a propósito lo que un usuario
tecleó en su propia configuración regional. Meter códigos al estilo local en NumberFormat (o al
revés) es un error sutil que funciona en tu máquina y se rompe en la de un colega.
Cómo ayuda ExcelMaster
NumberFormat esconde más decisiones que cualquier otra capa de formato: si necesitas redondear el
valor o solo la visualización, si una celda de fecha contiene un serial real o una cadena de texto,
si una celda «con formato» es en secreto texto de Format, y cuál de NumberFormat o
NumberFormatLocal mantiene el código portable. Cada giro equivocado devuelve una celda de aspecto
plausible con un número roto detrás.
ExcelMaster te deja decir
qué aspecto deben tener los números. Pídele «muestra la columna D como moneda con los negativos en
rojo» o «haz que las fechas se lean como 2025-09-15», y fija NumberFormat en la celda — manteniendo
el valor como un número real con el que se puede hacer matemáticas — redondea con Round cuando el
total tiene que cambiar de verdad, y usa códigos de formato de EE. UU. portables. Te quedas con el
libro y con el código; te ahorras el informe que cuadró mal porque los decimales solo estaban
ocultos, no eliminados.
Preguntas frecuentes
¿NumberFormat cambia el valor real de una celda en VBA?
No. Range.NumberFormat cambia solo cómo se muestra el número guardado. Una celda que contiene
5.4999 formateada como "0" muestra 5 pero sigue conteniendo 5.4999, y las fórmulas usan el
valor completo — así que las sumas pueden parecer «desviadas por uno». Para cambiar el valor en sí,
usa WorksheetFunction.Round(value, digits) y vuelve a asignarlo; dar formato por sí solo nunca
redondea el número guardado.
¿Cómo formateo una celda como moneda o fecha en VBA?
Fija el valor, luego el formato. Para moneda, Range("A1").Value = 1234.5 y luego
Range("A1").NumberFormat = "$#,##0.00". Para una fecha, Range("B1").Value = DateSerial(2025, 9, 15)
y luego Range("B1").NumberFormat = "yyyy-mm-dd". Fijar solo el formato sobre una cadena de texto no
hace nada, porque no hay ningún número subyacente que mostrar.
¿Cuál es la diferencia entre NumberFormat y la función Format?
Range.NumberFormat es una propiedad de celda que fija una regla de visualización y mantiene el valor
como un número real. Format(value, "pattern") es una función que devuelve una String. Usa
NumberFormat en las celdas de la hoja; usa Format para construir texto para mensajes, nombres de
archivo o etiquetas. Escribir Format(...) en una celda la convierte en texto que ya no puedes sumar
ni graficar.
¿Por qué mis totales salen mal después de formatear los números?
Porque NumberFormat oculta los decimales sin eliminarlos. Formatear una columna a "0" muestra
números enteros, pero cada celda sigue guardando sus decimales, así que el total real los incluye y
puede diferir de la suma de las cifras mostradas. Si el total tiene que coincidir con lo que se
muestra, redondea los valores con WorksheetFunction.Round en lugar de solo formatearlos.
¿Cuál es la diferencia entre NumberFormat y NumberFormatLocal?
NumberFormat usa códigos de formato en inglés de EE. UU. (coma para los millares, punto para el
decimal) en todas las máquinas, así que es portable. NumberFormatLocal usa los símbolos regionales
del usuario, que varían según la configuración regional. Escribe las macros contra NumberFormat
para un comportamiento coherente en todas partes, y usa NumberFormatLocal solo cuando igualas a
propósito lo que un usuario ve en su propia configuración.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 11/08/2026.
Guías relacionadas: VBA Font · VBA Color de celda · VBA Format · VBA CStr · VBA Range
