Testé sur : Excel 365 v2509 · Excel 2021 · Excel 2019 · dernière vérification le 10/06/2026
En bref — CStr, CDate, Val, CLng et CDbl sont les fonctions de conversion : elles changent le type d'une valeur — du texte en vrai nombre, du texte en vraie date, un nombre en texte. C'est l'inverse de Format, qui ne change que l'apparence d'une valeur. Saisissez la différence et vous coupez la plus grande source de bugs de données silencieux en VBA.
Sub ConvertDemo()
Debug.Print CStr(1234.5) ' "1234.5" nombre -> texte
Debug.Print CDbl("1234.5") * 2 ' 2469 texte -> nombre, puis vrai calcul
Debug.Print CLng("42") ' 42 texte -> entier Long
Debug.Print CDate("2026-04-01") ' une vraie date que l'on peut trier et soustraire
Debug.Print Val("12px") ' 12 lit les chiffres, s'arrête au premier non-chiffre
End Sub
Le modèle mental : la conversion change ce que la valeur EST
Une tournée de nettoyage dans ce groupe : Trim rend les données propres, Format les fait paraître justes, et les fonctions C… les mettent au bon type. Ce sont trois tâches différentes, et le péché capital est de confondre les deux dernières.
Une cellule qui affiche 2026-04-01 peut être une vraie date (triable, soustrayable, filtrable par mois) ou bien du texte qui en a juste l'air. Format produit le second type ; CDate le premier. Quand vos dates ne se trient pas ou que vos « nombres » ne s'additionnent pas, vous avez presque toujours du texte là où il fallait une vraie valeur typée — et le correctif est une conversion, pas plus de formatage. Prenez CDate/CDbl/CLng pour transformer le texte en ce qu'il prétend être, et CStr pour aller délibérément dans l'autre sens.
La règle unique : CDate lit les dates ambiguës selon les paramètres régionaux de la machine
C'est la règle qui corrompt silencieusement les données dans une équipe :
CDateanalyse une chaîne de date selon les paramètres régionaux du PC où il s'exécute.CDate("01/02/2026")est le 2 janvier sur une machine américaine et le 1er février sur une européenne. Même classeur, même code, données différentes — et rien ne lève d'erreur.
Aucun avertissement, car les deux lectures sont des dates valides. Le bug ne sort que lorsque le fichier passe à un collègue aux réglages différents, ou tourne sur un serveur configuré pour une autre région — et d'ici là, les mauvaises dates sont gravées dans un mois de rapports.
' ⚠ DANGER — le résultat dépend du PC qui l'exécute
d = CDate("01/02/2026") ' 2 janv. aux États-Unis, 1er févr. dans la plupart de l'Europe
' ✓ SÛR — construire la date à partir de ses morceaux, indépendant des paramètres régionaux
d = DateSerial(2026, 2, 1) ' toujours le 1er février, sur toutes les machines
Le correctif est d'arrêter complètement de donner des chaînes ambiguës à CDate. Quand vous maîtrisez la source, découpez les morceaux et construisez la date avec DateSerial(année, mois, jour) — il prend trois nombres et ne peut pas être mal lu. Quand vous devez accepter "01/02/2026", faites un Split sur "/" et décidez l'ordre vous-même au lieu de le laisser aux paramètres régionaux. Ne traitez CDate comme sûr que pour les formats non ambigus comme l'ISO "2026-04-01".
Le second piège : Val est aveugle aux paramètres régionaux, CDbl non
Les deux transforment du texte en nombre, mais ils ne s'accordent pas sur le séparateur décimal, et ce désaccord dévore les données françaises :
Valtraite toujours.comme la virgule décimale et,comme un point d'arrêt. Il ignore les espaces et lit de gauche à droite jusqu'à un caractère non numérique.Val("12px")→12.Val("1,234.5")→1(la virgule l'arrête).CDblrespecte les paramètres régionaux. Sur une machine où la virgule est le séparateur décimal,CDbl("3,14")→3,14.
La même chaîne change donc de sens selon votre choix :
' Un utilisateur sur un PC français tape "3,14" pour trois virgule quatorze
Debug.Print Val("3,14") ' 3 <- la virgule l'arrête ; le ",14" est silencieusement perdu
Debug.Print CDbl("3,14") ' 3,14 <- conscient des paramètres régionaux, la valeur voulue
La règle qui vous protège : Val pour les chaînes au format anglais fixe que vous maîtrisez (réduire "12px" à 12, lire un CSV que vous avez exporté vous-même avec des décimales en .) ; CDbl/CLng pour tout ce qu'un utilisateur a tapé ou qui vient d'une source localisée. Les mélanger, c'est ainsi qu'une colonne de prix français perd discrètement ses décimales.
Le troisième piège : CLng arrondit, et pas comme vous le pensez
CLng et CInt ne tronquent pas — ils arrondissent, avec l'arrondi du banquier (à l'entier pair le plus proche) :
Debug.Print CLng(2.5) ' 2 <- arrondit au nombre PAIR, pas vers le haut
Debug.Print CLng(3.5) ' 4
Debug.Print Int(2.7) ' 2 <- Int/Fix tronquent à la place
Si vous voulez « toujours arrondir au-dessus » ou « couper les décimales », CLng est le mauvais outil — prenez Int, Fix ou WorksheetFunction.Round. Et souvenez-vous : CInt déborde au-dessus de 32 767 ; prenez CLng pour tout ce qui pourrait être un comptage réel.
Encore un, côté texte : CStr(123) donne "123", mais l'ancien Str(123) donne " 123" avec un espace de tête réservé au signe — et Str utilise toujours ., quels que soient les paramètres régionaux. Pour un nombre-vers-texte propre, CStr (ou Format quand vous voulez une apparence précise) bat Str à chaque fois.
Quand utiliser quoi
| Vous avez… | Utilisez | Pourquoi |
|---|---|---|
| Un nombre que vous voulez en texte | CStr(n) |
Propre, conscient des paramètres régionaux, sans espace de tête |
| Texte → nombre, d'un utilisateur ou d'une source localisée | CDbl / CLng |
Respecte le séparateur décimal régional |
| Texte → nombre, format anglais fixe que vous maîtrisez | Val(s) |
Toujours décimale en ., s'arrête aux non-chiffres |
| Texte → vraie date, non ambiguë (ISO) | CDate("2026-04-01") |
Analyse un format clair en toute sécurité |
| Une date à partir de morceaux ambigus | DateSerial(a, m, j) |
Indépendant des paramètres régionaux, illisible à tort |
| Juste une chaîne d'affichage, valeur inchangée | Format | Cosmétique seulement — ne change pas le type |
L'avis tranché : ne laissez jamais les paramètres régionaux décider de vos données
Voici la ligne : la conversion implicite et CDate sur des chaînes ambiguës sont des bombes à retardement, pas des commodités. Le code qui fait someDate = rng.Value ou CDate(celluleTexte) et qui « marche » sur votre machine est le même code qui produit silencieusement février au lieu de janvier sur le serveur. Il passe tous les tests que vous lancez, parce que vous les lancez sur votre PC.
Alors convertissez délibérément et sans ambiguïté. Construisez les dates avec DateSerial. Analysez les nombres utilisateurs avec CDbl, les chaînes fixes avec Val, et sachez lequel vous tenez. Quand une colonne entière arrive en « nombres stockés en texte », le vrai correctif n'est pas une passe de formatage — c'est une conversion à la frontière d'import, une fois, avec les paramètres régionaux verrouillés. Les équipes qui se brûlent sont celles qui ont fait confiance à la lecture implicite ; les autres sont celles qui ont décidé le format elles-mêmes.
Erreurs de conversion courantes (et le correctif)
| Symptôme | Cause | Correctif |
|---|---|---|
| Dates fausses d'un mois sur un autre PC | CDate a lu un jj/mm vs mm/jj ambigu |
Construire avec DateSerial(a, m, j) |
| Les décimales françaises perdent tout après la virgule | Val a traité , comme un arrêt |
Utiliser CDbl pour l'entrée localisée |
Incompatibilité de type sur CDate/CDbl |
La chaîne n'était pas une date/un nombre valide | Tester IsDate(s) / IsNumeric(s) d'abord |
| L'arrondi tombe sur une valeur inattendue | CLng/CInt utilisent l'arrondi du banquier |
Utiliser Int/Fix, ou WorksheetFunction.Round |
Dépassement de capacité en convertissant un grand comptage |
CInt plafonne à 32 767 |
Utiliser CLng |
| Le nombre-vers-texte a un espace de tête | Str() utilisé, qui réserve une place au signe |
Utiliser CStr() |
Quand les conversions s'accumulent — décrivez les données voulues
Vous ne vouliez pas une visite de CDate contre DateSerial. Vous vouliez « lis cet export, où les dates sont en jj/mm et les montants utilisent des virgules, et charge-le correctement dans mon modèle ». Le temps d'avoir gardé IsDate, verrouillé les paramètres régionaux, choisi CDbl plutôt que Val et reconstruit les dates ambiguës, la tuyauterie de conversion est la macro. ExcelMaster Agent vous laisse décrire les données à la place — « les dates de la colonne A sont jour en premier, les montants en B utilisent une virgule décimale ; convertis-les en vraies dates et nombres » — et écrit du Python qui les analyse sans ambiguïté, en sauvegardant d'abord votre classeur. Essayer gratuitement →
Guides liés
- VBA Trim — pourquoi il ne supprime pas vos espaces (et le correctif Chr(160))
- VBA Format — dates, nombres & pourquoi le formatage casse vos calculs
- VBA InStr — trouver du texte dans une chaîne
- VBA Split — transformer une chaîne en tableau
- Boucle For VBA dans Excel — 8 exemples concrets
FAQ
Comment convertir une chaîne en nombre en VBA ?
Utilisez CDbl ou CLng pour les entrées d'utilisateurs ou de sources localisées, car ils respectent le séparateur décimal régional : CDbl("3,14") vaut 3,14 sur une machine à virgule décimale. N'utilisez Val que pour les chaînes au format anglais fixe que vous maîtrisez, puisque Val traite toujours . comme la décimale et s'arrête au premier non-chiffre.
Quelle est la différence entre CStr et Str en VBA ?
CStr convertit un nombre en texte proprement et suit les paramètres régionaux ; Str réserve un espace de tête pour le signe (donc Str(123) est " 123") et utilise toujours . comme décimale, peu importe la région. Préférez CStr pour nombre-vers-texte.
Pourquoi CDate donne-t-il la mauvaise date en VBA ?
Parce que CDate analyse les chaînes ambiguës comme "01/02/2026" selon les paramètres régionaux de la machine — 2 janv. aux États-Unis, 1er févr. dans une grande partie de l'Europe. Construisez les dates à partir de morceaux avec DateSerial(2026, 2, 1) pour les rendre indépendantes des paramètres régionaux, et réservez CDate aux formats non ambigus comme l'ISO "2026-04-01".
CLng arrondit-il ou tronque-t-il en VBA ?
CLng (et CInt) arrondissent, avec l'arrondi du banquier — CLng(2.5) vaut 2, CLng(3.5) vaut 4. Pour tronquer les décimales, utilisez Int ou Fix ; pour arrondir au-dessus, WorksheetFunction.Round. Notez que CInt déborde au-dessus de 32 767, alors utilisez CLng pour les valeurs plus grandes.
Comment éviter une Incompatibilité de type lors d'une conversion en VBA ?
Testez l'entrée d'abord : If IsNumeric(s) Then n = CDbl(s) et If IsDate(s) Then d = CDate(s). Ces garde-fous empêchent une chaîne non numérique ou une date invalide de lever une erreur d'exécution en plein milieu d'une boucle.
