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

Str en VBA en Excel — la trampa del espacio inicial y por qué CStr casi siempre es lo correcto

|

Str en VBA en Excel — la trampa del espacio inicial y por qué CStr casi siempre es lo correcto

TL;DRStr convierte un número en texto, pero es una vieja función de BASIC que esconde dos trampas. Primera: Str(42) devuelve " 42" con un espacio inicial (reserva una columna para el signo). Segunda: Str es ciega a la configuración regional: siempre usa un punto decimal ., incluso en una máquina alemana que espera una coma. Eso hace que Str sea estupenda para escribir archivos independientes de la configuración regional y errónea para cualquier cosa que vea un usuario. La opción por defecto para «número a texto» es CStr (sin espacio, respeta la configuración regional) o Format (control total). Eche mano de Str solo cuando quiera deliberadamente un separador . fijo, y aun así, la mayoría del código no debería hacerlo.

Este es el complemento de VBA CStr, CDate y Val, que cubre la conversión de texto en números y fechas. Este artículo va en la otra dirección: convertir un número en texto y, en concreto, por qué la función Str, de aspecto tan obvio, suele ser la que conviene evitar.

Lo que aprenderás

  • La trampa del espacio inicial: por qué Str(42) es " 42" y qué rompe eso
  • Por qué Str ignora su configuración regional, y cuándo eso resulta útil de verdad
  • Str frente a CStr frente a Format: cuál usar y cuándo
  • El par Str/Val frente al par CStr/CDbl

El modelo mental: Str es una reliquia con dos minas

Piense en Str como una herramienta de una época anterior de BASIC, creada cuando los números se imprimían en columnas de ancho fijo. Sigue comportándose así: deja sitio para un signo menos y no le importa en qué país está usted. Ambos comportamientos tenían sentido en 1985 y sorprenden a la gente en 2026.

Sub TheTwoLandmines()
    Debug.Print "[" & Str(42) & "]"     ' -> "[ 42]"   ¡espacio inicial!
    Debug.Print "[" & Str(-42) & "]"    ' -> "[-42]"   el signo ocupa el hueco
    Debug.Print Str(3.14)               ' -> "3.14"   siempre un punto, sea cual sea la configuración regional
End Sub

Mina 1: el espacio inicial

Str siempre reserva el primer carácter para el signo. Los números positivos reciben ahí un espacio; los negativos, el -. Así que Str(42) son tres caracteres: espacio, 4, 2. Esto rompe en silencio tres cosas:

Sub LeadingSpaceBreaksThings()
    ' 1) La concatenación gana un espacio de más
    Debug.Print "Total: " & Str(42)     ' -> "Total:  42"   (dos espacios)

    ' 2) Las comparaciones fallan
    Debug.Print (Str(42) = "42")        ' -> False   (" 42" <> "42")

    ' 3) Escrito en una celda, es texto-con-un-espacio:
    '    parece un número, pero ISNUMBER es False y la ordenación se rompe
    Range("A1").Value = Str(42)
End Sub

La gente lo «arregla» con Trim(Str(n)), que funciona pero es un olor a código (code smell): está tapando la elección de la función equivocada. El arreglo de verdad es usar una función que no añada el espacio desde el principio.

Mina 2: Str es ciega a la configuración regional

Str siempre emite un . como separador decimal, con independencia de la configuración regional de Windows. En una máquina configurada en alemán (que usa , para los decimales), Str(3.14) sigue siendo "3.14".

Este es el único punto en el que Str se gana el sueldo. Cuando escribe un CSV, una sentencia SQL, JSON o cualquier formato legible por máquina, usted quiere un separador . fijo para que el archivo se interprete igual en todas partes. Str se lo da gratis, mientras que CStr emitiría 3,14 en una máquina alemana y corrompería su archivo.

Pero para cualquier cosa que lea una persona, esa ceguera a la configuración regional es un error: un usuario alemán espera 3,14, y Str le mostrará 3.14.

El arreglo: CStr por defecto, Format para tener control

Sub TheRightTools()
    ' CStr — sin espacio inicial, respeta la configuración regional del usuario. La opción por defecto.
    Debug.Print "[" & CStr(42) & "]"        ' -> "[42]"
    Debug.Print CStr(3.14)                  ' -> "3,14" en una máquina alemana

    ' Format — control total sobre los dígitos, el relleno y los separadores de miles
    Debug.Print Format(42, "0")             ' -> "42"
    Debug.Print Format(1234.5, "#,##0.00")  ' -> "1,234.50" (o su equivalente regional)
    Debug.Print Format(7, "000")            ' -> "007"
End Sub

Esta es la decisión resumida en una tabla que puede llevar en la cabeza:

  • CStr — número → texto para uso general. Sin espacio, consciente de la configuración regional. Su opción por defecto.
  • Format — cuando necesita relleno, decimales fijos o separadores de miles.
  • Str — solo cuando necesita específicamente un . independiente de la configuración regional para un archivo o un protocolo, y acepta (o quita con Trim) el espacio inicial.

El criterio, dicho sin rodeos: en 2026, un Str() pelado en código nuevo es casi siempre o bien un error, o bien un caso especial de escritura de archivos sin comentar. Si lo que quiere decir es «dame este número como texto», escriba CStr. Si lo que quiere decir es «da formato a este número», escriba Format. Reserve Str para el caso concreto de salida independiente de la configuración regional, y ponga al lado un comentario que explique por qué.

El par Str/Val frente al par CStr/CDbl

Estas funciones vienen emparejadas, cada par consciente o no de la configuración regional; mezclarlas es justo lo que hace que los viajes de ida y vuelta corrompan los datos en silencio:

  • StrVal — ambas ciegas a la configuración regional (siempre .). Val("3.14") es 3.14 en cualquier máquina; Val, además, se detiene en el primer carácter no numérico. Use este par para la E/S de archivos de formato fijo.
  • CStrCDbl — ambas conscientes de la configuración regional. CDbl respeta la coma regional; CStr la emite. Use este par para los viajes de ida y vuelta de valores que ve el usuario.

El error que hay que evitar es cruzar los pares: escribir con Str (punto) y leer de vuelta con CDbl en una máquina de configuración regional con coma hace que el número cambie. Mantenga cada viaje de ida y vuelta dentro de un mismo par.

Cómo ayuda ExcelMaster

El código VBA de número a texto suele existir para construir una exportación o una etiqueta: una etiqueta de precio, un campo de CSV, un número de factura con relleno de ceros. ExcelMaster genera eso a partir de una descripción —«exporta estos importes como texto con dos decimales y un ID con cero a la izquierda»— y acierta con la configuración regional y el relleno sin que usted tenga que elegir entre Str, CStr y Format ni descubrir el espacio inicial por las malas.

Seguirá escribiendo conversiones en línea dentro de sus macros. Pero para trabajos del tipo «produce esta exportación con formato», describir el formato es mejor que elegir a mano la función de conversión.

Preguntas frecuentes

¿Cuál es la diferencia entre Str y CStr en VBA?

Str añade un espacio inicial delante de los números positivos y siempre usa un punto decimal ., sea cual sea la configuración regional. CStr no añade espacio y respeta la configuración regional del usuario. Para la conversión general de «número a texto», use CStr; use Str solo cuando necesite un . independiente de la configuración regional para un archivo o un protocolo.

¿Por qué Str de VBA pone un espacio delante del número?

Str reserva el primer carácter para el signo: un espacio para los números positivos, un - para los negativos. Es un vestigio de la impresión numérica de ancho fijo. Para quitarlo, use CStr (que nunca añade el espacio) o envuélvalo como Trim(Str(n)), aunque CStr es el arreglo más limpio.

¿Str de VBA respeta el separador decimal regional?

No. Str siempre emite un . incluso en máquinas configuradas con coma decimal (alemán, francés, etc.). Eso resulta útil para escribir CSV/SQL que deben interpretarse igual en todas partes, pero es erróneo para valores que se muestran a los usuarios: para esos, use CStr o Format.

¿Cómo convierto un número en una cadena en VBA?

Use CStr(number) como opción por defecto: sin espacio inicial y consciente de la configuración regional. Use Format(number, "0.00") cuando necesite decimales, relleno o separadores de miles concretos. Reserve Str(number) solo para la salida a archivos independiente de la configuración regional.

Probado en

Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación 14-06-2026.

Guías relacionadas: VBA CStr · VBA Format · VBA Concatenate · VBA UCase & LCase · VBA Trim