Probado en: Excel 365 v2509 · Excel 2021 · Excel 2019 · última verificación el 10/06/2026
Resumen — Format toma un valor y un código de formato y te devuelve una cadena con el aspecto que pediste. Es estupendo para construir nombres de archivo, mensajes y etiquetas de informe — y una fábrica de errores silenciosos en cuanto escribes su resultado en una celda de datos, porque esa celda pasa a contener texto, no un número ni una fecha.
Sub FormatDemo()
Debug.Print Format(1234.5, "#,##0.00") ' 1.234,50
Debug.Print Format(0.75, "0.0%") ' 75,0%
Debug.Print Format(Now, "yyyy-mm-dd") ' 2026-06-10
Debug.Print Format(Now, "dddd d mmmm") ' miércoles 10 junio
Debug.Print Format(38740, "#,##0 €") ' 38.740 €
End Sub
La firma, con los dos argumentos opcionales que casi todos olvidan:
Format(expression, [format], [firstDayOfWeek], [firstWeekOfYear])
' el valor código para cálculo del día, rara vez necesario
El modelo mental: Format es maquillaje, no cirugía
Format cambia cómo se ve un valor, nunca lo que es. Dale el número de serie de fecha 46183 y el código "yyyy-mm-dd", y obtienes la cadena "2026-06-10". El valor subyacente no cambia de tipo al entrar — pero lo que sale es siempre una String. Esa es la frase más importante sobre Format: la salida es texto.
Tenlo presente y toda la herramienta encaja. Usa Format cuando el destino es una cadena — un cuadro de mensaje, un nombre de hoja, un nombre de archivo "informe_" & Format(Date, "yyyymmdd") & ".xlsx", una etiqueta que estás concatenando. No lo uses cuando el destino es una celda que debe seguir siendo número o fecha, porque estarías vertiendo texto en un hueco sobre el que el resto de tu libro espera calcular.
La regla única: Format devuelve una String — y por eso rompe los cálculos aguas abajo
Esta es la regla que explica el desastre de Format más común:
En el momento en que escribes
cell.Value = Format(unaFecha, "yyyy-mm-dd"), esa celda deja de ser una fecha y se convierte en texto que parece una fecha. No se ordena cronológicamente, no se filtra por mes, y=SUMAsobre una columna de «números formateados» devuelve0.
Aquí está la trampa, completamente armada:
' ⚠ MAL — llena la columna de texto que solo parece numérico
Range("C2").Value = Format(1234.5, "#,##0.00") ' la celda ahora contiene la CADENA "1.234,50"
' =SUMA(C:C) la ignora. La ordenación trata "1.234,50" como texto. Los gráficos la saltan.
Si lo que de verdad quieres es que la celda se muestre con separadores de miles y siga siendo un número real, no usas Format en absoluto — ajustas el formato de número de la celda y dejas el valor en paz:
' ✓ BIEN — el valor sigue siendo numérico, solo cambia la visualización
Range("C2").Value = 1234.5
Range("C2").NumberFormat = "#,##0.00" ' SUMA, ordenación, gráficos siguen funcionando
Esa distinción — Format produce texto, NumberFormat cambia la visualización — es todo el juego. Grábala: Format para cadenas, NumberFormat para celdas.
La segunda trampa: m significa mes, hasta que no
Los códigos de fecha y hora comparten la letra m, y esa ambigüedad muerde a todos al menos una vez:
- Un
"mm"aislado son meses:Format(Now, "mm")→06. - Ese mismo
"mm"justo después de"hh:"se lee como minutos:Format(Now, "hh:mm")→09:05. La cercanía a la hora invierte su significado. - Para un tiempo transcurrido sin hora al lado,
"mm:ss"dames:segundo— casi nunca lo que querías. Usa el token de minuto explícito de VBA,n:Format(t, "nn:ss").
Debug.Print Format(Now, "yyyy-mm-dd hh:mm:ss") ' 2026-06-10 09:05:30 (primer mm = mes, segundo = minutos)
Debug.Print Format(Now, "mm:ss") ' 06:30 <- MES:segundo, la sorpresa clásica
Debug.Print Format(Now, "nn:ss") ' 05:30 <- minutos, el arreglo
Los dígitos de relleno tienen su propia regla, digna de saberse: 0 fuerza un dígito (rellena con ceros), # muestra un dígito solo si existe. Format(5, "00") → 05; Format(5, "##") → 5. Así rellenas con ceros los números de factura o mantienes un entero limpio.
Formatos con nombre y los hermanos Format*
No siempre necesitas un código personalizado. VBA trae formatos con nombre y funciones hermanas sensibles a la configuración regional:
Debug.Print Format(1234.5, "Currency") ' 1.234,50 € (usa la moneda regional de la máquina)
Debug.Print Format(Now, "Short Date") ' 10/06/2026 (orden regional)
Debug.Print Format(0.75, "Percent") ' 75,00%
Debug.Print FormatCurrency(1234.5, 2) ' 1.234,50 €
Debug.Print FormatNumber(1234.5, 2) ' 1.234,50
Debug.Print FormatPercent(0.75, 1) ' 75,0%
Debug.Print FormatDateTime(Now, vbLongDate) ' miércoles, 10 de junio de 2026
Los formatos con nombre y los hermanos Format* respetan la configuración regional de la máquina — una ventaja para la visualización de cara al usuario y un peligro para datos que pretendes ir y volver: "Short Date" es 6/10/2026 en EE. UU. y 10/06/2026 en la mayor parte de Europa. Cuando necesites una cadena fija e independiente de la máquina (un nombre de archivo, una clave CSV, una marca de tiempo ISO), deletrea el código explícitamente — "yyyy-mm-dd" — y nunca "Short Date".
Cuándo usar cuál
| Quieres… | Usa | Por qué |
|---|---|---|
| Una cadena para un mensaje, nombre de archivo o etiqueta | Format(valor, código) |
La salida es texto — justo lo que necesitas |
| Que una celda se muestre formateada pero siga numérica | Range.NumberFormat = código |
El valor sigue siendo número; SUMA/orden/gráficos funcionan |
| Una cadena de moneda/número regional | FormatCurrency / FormatNumber |
Sigue la configuración regional |
| Una cadena de fecha fija, independiente de la máquina | Format(d, "yyyy-mm-dd") |
El código explícito ignora el orden regional |
| Convertir de verdad texto de vuelta a número/fecha | CStr / CDate / Val | Format solo va valor → texto, nunca al revés |
La opinión: si aterriza en una celda, es NumberFormat, no Format
Esta es la línea que defiendo: Format casi nunca debería escribir en una celda de datos. El noventa por ciento de los tickets «mi SUMA da cero» y «mis fechas no se ordenan» se rastrean hasta alguien que usó Format donde quería NumberFormat. Los dos se leen casi igual en el código, que es exactamente por qué el error es tan común y tan invisible en la revisión.
Así que conviértelo en un hábito con una separación clara. ¿Construir una cadena — el nombre de una pestaña, una línea de registro, una marca de archivo, texto que metes en un MsgBox? Format. ¿Hacer que una celda se vea bien y siga siendo un número o fecha con la que el libro pueda calcular? NumberFormat, valor intacto. Acierta esa separación y desaparece toda una clase de errores de datos silenciosos. Y recuerda la calle de sentido único: Format solo va valor → texto. Para el otro sentido — texto que debería ser un número o fecha de verdad — necesitas CStr, CDate y Val, no Format.
Errores frecuentes de Format (y el arreglo)
| Síntoma | Causa | Arreglo |
|---|---|---|
=SUMA sobre la columna devuelve 0 |
Se escribió Format() (texto) en las celdas |
valor + Range.NumberFormat, sin Format |
| Las fechas no se ordenan cronológicamente | Las celdas tienen texto formateado, no fechas | Guardar la fecha real, ajustar NumberFormat |
mm muestra el mes, no los minutos |
mm aislado es el mes |
Usar nn, o poner mm junto a hh |
| La fecha invierte día/mes en otro PC | Se usó "Short Date" (regional) |
Usar un "yyyy-mm-dd" explícito |
| Falta el cero inicial en un código | Se usó # (dígito opcional) |
Usar 0 para forzar el dígito: "00" |
| El número aparece como texto tras una macro | Resultado de Format asignado a .Value |
Asignar el número; formatear vía NumberFormat |
Cuando el formato es media macro — describe el resultado en su lugar
Formatear nunca es el objetivo; el informe lo es. Querías «una hoja mensual donde los importes se muestren en euros, las fechas en ISO, y los totales sigan cuadrando» — y en cambio estás tres capas dentro decidiendo si este mm es un mes, si esta columna es texto o número, y por qué el gráfico saltó una fila. ExcelMaster Agent te deja enunciar el resultado en español sencillo — «formatea la columna C como moneda, la columna A como yyyy-mm-dd, mantenlas numéricas para que los totales funcionen» — y escribe Python que ajusta formatos de número en vez de convertir tus datos en texto, haciendo antes una copia de seguridad del archivo. Prueba gratis →
Guías relacionadas
- VBA Trim — por qué no elimina tus espacios (y la solución Chr(160))
- VBA CStr, CDate y Val — convertir texto a números y fechas correctamente
- VBA InStr — encontrar texto dentro de una cadena
- VBA Split — convertir una cadena en una matriz
- Bucle For en VBA — 8 ejemplos del mundo real
Preguntas frecuentes
¿Qué hace la función Format en VBA?
Format convierte un valor en una cadena formateada usando un código — Format(1234.5, "#,##0.00") devuelve el texto "1.234,50". Cambia cómo se ve el valor, no lo que es, y el resultado es siempre texto.
¿Cómo formateo una fecha en VBA?
Con un código explícito: Format(Now, "yyyy-mm-dd") da 2026-06-10; Format(Now, "dd/mm/yyyy") da el día primero. Evita el "Short Date" con nombre si la cadena debe ser igual en cada máquina, porque sigue la configuración regional de cada PC.
¿Por qué mi VBA Format muestra el mes en lugar de los minutos?
Porque m significa mes por defecto. Un "mm" aislado es el mes; solo significa minutos cuando va justo después de "hh:". Para un tiempo transcurrido, usa el token de minuto explícito de VBA: Format(t, "nn:ss").
¿Por qué SUMA devuelve 0 después de formatear una columna con VBA?
Casi con seguridad escribiste resultados de Format() en las celdas, lo que guarda texto que solo parece numérico. Guarda el número real y ajusta la apariencia con Range.NumberFormat = "#,##0.00" en su lugar — entonces SUMA, ordenación y gráficos vuelven a funcionar.
¿Cuál es la diferencia entre Format y NumberFormat en VBA?
Format devuelve una cadena de texto; Range.NumberFormat cambia cómo se muestra una celda mientras el valor guardado sigue siendo un número o fecha de verdad. Usa Format para construir cadenas, y NumberFormat para que las celdas se vean bien sin romper los cálculos.
