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

VBA CStr, CDate y Val en Excel — convertir texto a números y fechas correctamente

|

VBA CStr, CDate y Val en Excel — convertir texto a números y fechas correctamente

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

ResumenCStr, CDate, Val, CLng y CDbl son las funciones de conversión: cambian el tipo de un valor — texto a número real, texto a fecha real, número a texto. Es lo contrario de Format, que solo cambia cómo se ve un valor. Capta la diferencia y cortas la mayor fuente de errores de datos silenciosos en VBA.

Sub ConvertDemo()
    Debug.Print CStr(1234.5)            ' "1234.5"        número  -> texto
    Debug.Print CDbl("1234.5") * 2      ' 2469            texto   -> número, luego cálculo real
    Debug.Print CLng("42")              ' 42              texto   -> entero Long
    Debug.Print CDate("2026-04-01")     ' una fecha real que se puede ordenar y restar
    Debug.Print Val("12px")             ' 12              lee dígitos, se detiene en el primer no-dígito
End Sub

El modelo mental: la conversión cambia lo que un valor ES

Un recorrido de limpieza por este grupo: Trim deja los datos limpios, Format los hace parecer correctos, y las funciones C… los ponen del tipo correcto. Son tres tareas distintas, y el pecado capital es confundir las dos últimas.

Una celda que muestra 2026-04-01 puede ser una fecha real (ordenable, restable, filtrable por mes) o texto que solo lo parece. Format produce el segundo tipo; CDate el primero. Cuando tus fechas no se ordenan o tus «números» no suman, casi siempre tienes texto donde necesitabas un valor con tipo de verdad — y el arreglo es una conversión, no más formato. Usa CDate/CDbl/CLng para convertir el texto en lo que finge ser, y CStr para ir deliberadamente en el otro sentido.

La regla única: CDate lee fechas ambiguas según la configuración regional de la máquina

Esta es la regla que corrompe en silencio los datos de un equipo:

CDate analiza una cadena de fecha usando la configuración regional del PC en el que se ejecuta. CDate("01/02/2026") es el 2 de enero en una máquina estadounidense y el 1 de febrero en una europea. Mismo libro, mismo código, datos distintos — y nada da error.

No hay aviso, porque ambas lecturas son fechas válidas. El error solo aflora cuando el archivo pasa a un colega con otros ajustes, o se ejecuta en un servidor configurado para otra región — y para entonces las fechas equivocadas están grabadas en un mes de informes.

' ⚠ PELIGRO — el resultado depende del PC que lo ejecute
d = CDate("01/02/2026")          ' 2 ene. en EE. UU., 1 feb. en la mayor parte de Europa

' ✓ SEGURO — construye la fecha a partir de sus partes, independiente de la región
d = DateSerial(2026, 2, 1)       ' siempre el 1 de febrero, en cualquier máquina

El arreglo es dejar de pasarle cadenas ambiguas a CDate por completo. Cuando controlas la fuente, separa las partes y construye la fecha con DateSerial(año, mes, día) — toma tres números y no puede leerse mal. Cuando debes aceptar "01/02/2026", haz un Split por "/" y decide el orden tú mismo en vez de dejárselo a la configuración regional. Trata CDate como seguro solo para formatos no ambiguos como el ISO "2026-04-01".

La segunda trampa: Val es ciego a la región, CDbl no

Ambos convierten texto en número, pero discrepan sobre el separador decimal, y esa discrepancia se come los datos con coma:

  • Val trata siempre . como el punto decimal y , como un tope. Ignora los espacios y lee de izquierda a derecha hasta topar con algo no numérico. Val("12px")12. Val("1,234.5")1 (la coma lo detiene).
  • CDbl respeta la configuración regional. En una máquina donde la coma es el separador decimal, CDbl("3,14")3,14.

Así que la misma cadena cambia de significado según cuál elijas:

' Un usuario en un PC español teclea "3,14" queriendo decir tres coma catorce
Debug.Print Val("3,14")     ' 3      <- la coma lo detiene; el ",14" se pierde en silencio
Debug.Print CDbl("3,14")    ' 3,14   <- consciente de la región, el valor que el usuario quería

La regla que te mantiene a salvo: Val para cadenas en formato inglés fijo que controlas (reducir "12px" a 12, leer un CSV que exportaste tú mismo con decimales en .); CDbl/CLng para todo lo que un usuario haya tecleado o venga de una fuente localizada. Mezclarlos es como una columna de precios en euros pierde discretamente sus decimales.

La tercera trampa: CLng redondea, y no como esperas

CLng y CInt no truncan — redondean, con el redondeo del banquero (al par más cercano):

Debug.Print CLng(2.5)       ' 2   <- redondea al número PAR, no hacia arriba
Debug.Print CLng(3.5)       ' 4
Debug.Print Int(2.7)        ' 2   <- Int/Fix truncan en su lugar

Si quieres «siempre redondear hacia arriba» o «cortar los decimales», CLng es la herramienta equivocada — usa Int, Fix o WorksheetFunction.Round. Y recuerda: CInt desborda por encima de 32.767; usa CLng para cualquier cosa que pueda ser un recuento real.

Uno más en el lado del texto: CStr(123) da "123", pero el antiguo Str(123) da " 123" con un espacio inicial reservado para el signo — y Str usa siempre ., sin importar la región. Para número-a-texto limpio, CStr (o Format cuando quieres un aspecto concreto) le gana a Str todas las veces.

Cuándo usar cuál

Tienes… Usa Por qué
Un número que quieres como texto CStr(n) Limpio, consciente de la región, sin espacio inicial
Texto → número, de un usuario o fuente localizada CDbl / CLng Respeta el separador decimal regional
Texto → número, formato inglés fijo que controlas Val(s) Siempre decimal en ., se detiene en no-dígitos
Texto → fecha real, no ambigua (ISO) CDate("2026-04-01") Analiza con seguridad un formato claro
Una fecha a partir de partes ambiguas DateSerial(a, m, d) Independiente de la región, no se lee mal
Solo una cadena de visualización, valor sin cambios Format Solo cosmético — no cambia el tipo

La opinión: nunca dejes que la región decida tus datos

Esta es la línea: la conversión implícita y CDate sobre cadenas ambiguas son bombas de relojería, no comodidades. El código que hace someDate = rng.Value o CDate(celdaTexto) y «funciona» en tu máquina es el mismo código que produce en silencio febrero en vez de enero en el servidor. Pasa todas las pruebas que ejecutas, porque las ejecutas en tu PC.

Así que convierte de forma deliberada e inequívoca. Construye fechas con DateSerial. Analiza los números del usuario con CDbl, las cadenas fijas con Val, y sabe cuál tienes en la mano. Cuando una columna entera llega como «números guardados como texto», el verdadero arreglo no es una pasada de formato — es una conversión en la frontera de importación, una vez, con la región fijada. Los equipos que se queman son los que confiaron en la lectura implícita; los demás son los que decidieron el formato ellos mismos.

Errores de conversión frecuentes (y el arreglo)

Síntoma Causa Arreglo
Fechas equivocadas por un mes en otro PC CDate leyó un dd/mm vs mm/dd ambiguo Construir con DateSerial(a, m, d)
Los decimales con coma pierden todo tras la coma Val trató , como un tope Usar CDbl para entrada localizada
No coinciden los tipos en CDate/CDbl La cadena no era una fecha/número válido Probar IsDate(s) / IsNumeric(s) primero
El redondeo cae en un valor inesperado CLng/CInt usan el redondeo del banquero Usar Int/Fix, o WorksheetFunction.Round
Desbordamiento al convertir un recuento grande CInt tope en 32.767 Usar CLng
El número-a-texto tiene un espacio inicial Se usó Str(), que reserva sitio para el signo Usar CStr()

Cuando las conversiones se acumulan — describe los datos que quieres

No querías un recorrido por CDate frente a DateSerial. Querías «lee esta exportación, donde las fechas son dd/mm y los importes usan comas, y cárgala correctamente en mi modelo». Para cuando has protegido IsDate, fijado la región, elegido CDbl sobre Val y reconstruido las fechas ambiguas, la fontanería de conversión es la macro. ExcelMaster Agent te deja describir los datos en su lugar — «las fechas de la columna A van con el día primero, los importes en B usan coma decimal; conviértelos en fechas y números de verdad» — y escribe Python que los analiza sin ambigüedad, haciendo antes una copia de seguridad de tu libro. Prueba gratis →

Guías relacionadas

Preguntas frecuentes

¿Cómo convierto una cadena a número en VBA? Usa CDbl o CLng para entradas de usuarios o de fuentes localizadas, porque respetan el separador decimal regional: CDbl("3,14") es 3,14 en una máquina con coma decimal. Usa Val solo para cadenas en formato inglés fijo que controlas, ya que Val trata siempre . como el decimal y se detiene en el primer no-dígito.

¿Cuál es la diferencia entre CStr y Str en VBA? CStr convierte un número a texto de forma limpia y sigue la configuración regional; Str reserva un espacio inicial para el signo (así Str(123) es " 123") y usa siempre . como decimal, sin importar la región. Prefiere CStr para número-a-texto.

¿Por qué CDate da la fecha equivocada en VBA? Porque CDate analiza cadenas ambiguas como "01/02/2026" según la configuración regional de la máquina — 2 ene. en EE. UU., 1 feb. en buena parte de Europa. Construye fechas a partir de partes con DateSerial(2026, 2, 1) para hacerlas independientes de la región, y reserva CDate para formatos no ambiguos como el ISO "2026-04-01".

¿CLng redondea o trunca en VBA? CLng (y CInt) redondean, con el redondeo del banquero — CLng(2.5) es 2, CLng(3.5) es 4. Para truncar los decimales, usa Int o Fix; para redondear hacia arriba, WorksheetFunction.Round. Ten en cuenta que CInt desborda por encima de 32.767, así que usa CLng para valores mayores.

¿Cómo evito un No coinciden los tipos al convertir en VBA? Prueba la entrada primero: If IsNumeric(s) Then n = CDbl(s) y If IsDate(s) Then d = CDate(s). Estas comprobaciones evitan que una cadena no numérica o una fecha inválida lance un error en plena ejecución del bucle.