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

VBA Format en Excel — fechas, números y por qué el formato rompe tus cálculos

|

VBA Format en Excel — fechas, números y por qué el formato rompe tus cálculos

Probado en: Excel 365 v2509 · Excel 2021 · Excel 2019 · última verificación el 10/06/2026

ResumenFormat 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 =SUMA sobre una columna de «números formateados» devuelve 0.

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" da mes: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

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.