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

VBA NumberFormat dans Excel — changer l'affichage d'un nombre sans changer sa valeur

|

VBA NumberFormat dans Excel — changer l'affichage d'un nombre sans changer sa valeur

En brefRange.NumberFormat est la couche d'affichage : elle change la façon dont un nombre stocké se lit sans jamais toucher au nombre lui-même. Range("A1").Value = 5.4999 avec Range("A1").NumberFormat = "0" affiche 5 à l'écran — mais A1.Value vaut toujours 5.4999, et A1 + A1 fait 10.9998. NumberFormat n'est pas un arrondi. C'est la couche où l'« apparence contre valeur » vous coûte réellement de l'argent, car une date n'est qu'un numéro de série costumé, et NumberFormat est le costume — pas le nombre.

Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Report")
ws.Range("A1").Value = 5.4999
ws.Range("A1").NumberFormat = "0"           ' affiche 5...
Debug.Print ws.Range("A1").Value            ' ...mais la valeur reste 5.4999

Des trois couches de mise en forme — Font pour le texte, Interior pour le remplissage, et NumberFormat pour l'affichage — c'est celle qui trompe les gens, parce que le déguisement est convaincant. Une police rouge ne fait jamais croire à personne que la valeur a changé. Une cellule qui affiche 5, elle, le fait absolument. Ce guide s'articule autour de ce seul fait : NumberFormat change ce que vous voyez, jamais ce qui est stocké, et une fois cela acquis, les dates, la monnaie, les pourcentages et le classique bug « mes totaux ne tombent pas juste » prennent tous leur sens.

Ce que vous allez apprendre

  • Le modèle mental — NumberFormat est la couche d'affichage, et l'affichage n'est pas la valeur
  • La règle la plus importante — ce n'est pas un arrondi, et le nombre stocké reste inchangé
  • Pourquoi une date est un numéro de série déguisé
  • NumberFormat (la propriété de la cellule) face à la fonction Format (une chaîne)
  • Le langage des codes de format — #, 0, les quatre sections, la monnaie et la couleur
  • Le piège des paramètres régionaux — NumberFormat face à NumberFormatLocal

Le modèle mental : NumberFormat est la couche d'affichage

Chaque cellule stocke une valeur et, séparément, une règle sur la façon de dessiner cette valeur. NumberFormat est cette règle. La régler sur "0.00", "$#,##0", "yyyy-mm-dd" ou "0%" change la présentation — les glyphes qu'Excel peint — tandis que le nombre sous-jacent reste intact dans Range.Value. Voyez la cellule comme contenant un nombre, et NumberFormat comme une lentille que vous placez devant. Changez la lentille et la vue change ; le nombre derrière, lui, ne bouge pas.

Cette séparation, c'est tout le sujet. C'est pourquoi vous pouvez afficher le même 0.5 sous la forme 50%, 0.50 ou 1/2 sans jamais changer la valeur qu'utilisent les formules — et pourquoi masquer des décimales à l'affichage ne les fait pas disparaître.

La règle la plus importante : ce n'est pas un arrondi

Dites-le une fois et ne l'oubliez jamais : NumberFormat n'arrondit pas la valeur stockée. Il arrondit l'image.

ws.Range("A1").Value = 5.4999
ws.Range("A2").Value = 5.4999
ws.Range("A1:A2").NumberFormat = "0"        ' les deux affichent 5
ws.Range("A3").Formula = "=A1+A2"           ' affiche 11 ? Non - il montre 10.9998 arrondi a l'affichage...
' La vraie somme est 10.9998. Le format a masque les decimales ; il ne les a pas supprimees.

C'est le bug NumberFormat le plus courant de tous : formater une colonne en "0" pour « faire propre », puis voir un total tomber à côté d'une unité parce que chaque cellule porte encore des décimales que l'œil ne voit pas. Si vous voulez que la valeur elle-même soit réellement 5, vous devez changer la valeur, pas le format :

ws.Range("A1").Value = WorksheetFunction.Round(ws.Range("A1").Value, 0)   ' maintenant c'est vraiment 5

Règle empirique : formatez quand il suffit que ça ait l'air juste ; Round quand le nombre doit être juste. Les rapports qui doivent tomber juste au centime près arrondissent les valeurs ; les tableaux de bord qui doivent seulement se lire proprement formatent l'affichage. Confondre les deux, c'est ainsi que les feuilles de calcul finissent « fausses d'une erreur d'arrondi ».

Une date est un numéro de série déguisé

Les dates rendent limpide la séparation apparence-contre-valeur. Excel stocke une date sous forme de numéro de série — le nombre de jours depuis le 1899-12-30 — et une date n'« est » une date qu'à cause de son NumberFormat :

ws.Range("B1").Value = 45900                 ' juste un nombre
ws.Range("B1").NumberFormat = "yyyy-mm-dd"   ' maintenant il SE LIT comme une date - le nombre reste 45900

Deux conséquences en découlent directement. Primo, pour obtenir une vraie date calculable, vous devez mettre une vraie valeur de date dans la cellule (ws.Range("B1").Value = DateSerial(2025, 9, 15)) puis la formater — formater seul sur une mauvaise valeur affiche une mauvaise date. Secundo, appliquer "yyyy-mm-dd" à une chaîne de texte comme "2025-09-15" ne sert à rien : le texte n'a aucun numéro de série derrière lui, il n'y a donc aucun nombre à habiller. Si les dates arrivent sous forme de texte, convertissez-les (CDate, ou voir VBA CStr pour le problème inverse) avant de les formater. Le costume ne fonctionne que par-dessus un vrai nombre.

NumberFormat face à la fonction Format

Il y a deux choses en VBA qui portent « format » dans leur nom, et les confondre est une vraie source de bugs. Elles sont opposées sur un point important :

  • Range.NumberFormat est une propriété de la cellule. Elle pose une règle d'affichage persistante et laisse le nombre sous-jacent pleinement intact et modifiable. C'est ce que vous voulez sur une feuille de calcul.
  • Format(value, "pattern") est une fonction qui renvoie une String. Elle est traitée dans VBA Format, et elle sert à construire du texte — une boîte de message, un nom de fichier, un libellé concaténé — pas à formater une cellule.

Le piège consiste à utiliser Format pour placer un « nombre formaté » dans une cellule :

ws.Range("C1").Value = Format(1234.5, "$#,##0.00")   ' ecrit la CHAINE "$1,234.50"
' C1 est maintenant du texte. Impossible de la SUM, de la trier numeriquement ou d'en faire un graphique.

Cette cellule a l'air formatée, mais elle contient désormais du texte, et son nombre a disparu. La version correcte garde le nombre et pose la règle d'affichage :

ws.Range("C1").Value = 1234.5
ws.Range("C1").NumberFormat = "$#,##0.00"            ' affiche $1,234.50, toujours un vrai nombre

La règle : NumberFormat pour les cellules, Format pour les chaînes. Si le résultat doit rester un nombre, ne le faites jamais transiter par Format.

Le langage des codes de format

Les codes de format sont un petit langage, et quatre règles permettent de lire la quasi-totalité d'entre eux :

  • 0 est un chiffre forcé, # un chiffre optionnel. "0.00" affiche toujours deux décimales (5 devient 5.00) ; "#.##" en affiche jusqu'à deux et supprime les zéros de fin (5 reste 5).
  • , groupe les milliers. "#,##0" transforme 1234567 en 1,234,567.
  • Les symboles littéraux passent tels quels. $, %, les espaces et le texte entre guillemets apparaissent tels qu'écrits — "$#,##0.00", "0%" (qui multiplie aussi par 100 pour l'affichage), "0.0 kg".
  • Les points-virgules le découpent en sections : positive;negative;zero;text. C'est la règle puissante :
' Positif en noir, negatifs en rouge entre parentheses, zero en tiret, texte entre guillemets affiche tel quel.
ws.Range("D2:D100").NumberFormat = "#,##0.00;[Red](#,##0.00);\-;@"

[Red] (et les autres noms de couleur entre crochets) fixe la couleur d'affichage par section, et @ est l'emplacement du texte. Vous avez rarement besoin des quatre sections, mais savoir qu'elles existent vous permet de lire n'importe quelle chaîne de format que vous croisez. Pour les dates, les jetons sont d/m/y et h/m/s"yyyy-mm-dd hh:mm" — avec cette bizarrerie que m signifie mois après y ou d, et minute après h.

Le piège des paramètres régionaux : NumberFormat face à NumberFormatLocal

Le dernier piège mord sur les classeurs partagés. NumberFormat utilise toujours les codes de format anglais américains, pour les milliers, . pour la décimale, m/d/y pour les dates — quels que soient les paramètres régionaux de l'utilisateur. NumberFormatLocal utilise les symboles locaux de l'utilisateur (en allemand, . groupe les milliers et , est la décimale).

ws.Range("E1").NumberFormat = "#,##0.00"        ' portable : meme resultat sur chaque machine
ws.Range("E2").NumberFormatLocal = "#.##0,00"   ' codes a l'allemande - justes seulement en locale allemande

Écrivez vos macros avec NumberFormat et des codes américains, et elles se comportent partout de façon identique. Ne recourez à NumberFormatLocal que lorsque vous lisez ou reproduisez délibérément ce qu'un utilisateur a saisi dans ses propres paramètres régionaux. Donner des codes à la mode locale à NumberFormat (ou l'inverse) est un bug subtil qui marche sur votre machine et casse sur celle d'un collègue.

Comment ExcelMaster aide

NumberFormat cache plus de décisions que n'importe quelle autre couche de mise en forme : faut-il arrondir la valeur ou seulement l'affichage, une cellule de date contient-elle un vrai numéro de série ou une chaîne de texte, une cellule « formatée » est-elle secrètement du texte issu de Format, et lequel de NumberFormat ou NumberFormatLocal garde le code portable. Chaque mauvais virage renvoie une cellule d'apparence plausible avec un nombre cassé derrière.

ExcelMaster vous laisse dire à quoi les nombres doivent ressembler. Demandez-lui d'« afficher la colonne D en monnaie avec les négatifs en rouge » ou de « faire lire les dates comme 2025-09-15 », et il pose NumberFormat sur la cellule — en gardant la valeur sous forme de vrai nombre calculable — arrondit avec Round quand le total doit réellement changer, et utilise des codes de format américains portables. Vous gardez le classeur et le code ; vous vous épargnez le rapport qui tombait faux parce que les décimales n'étaient que masquées, pas supprimées.

Questions fréquentes

NumberFormat change-t-il la valeur réelle d'une cellule en VBA ?

Non. Range.NumberFormat ne change que la façon dont le nombre stocké est affiché. Une cellule contenant 5.4999 formatée en "0" affiche 5 mais contient toujours 5.4999, et les formules utilisent la valeur complète — les sommes peuvent donc sembler « fausses d'une unité ». Pour changer la valeur elle-même, utilisez WorksheetFunction.Round(value, digits) et réaffectez-la ; le seul formatage n'arrondit jamais le nombre stocké.

Comment formater une cellule en monnaie ou en date en VBA ?

Définissez la valeur, puis le format. Pour la monnaie, Range("A1").Value = 1234.5 puis Range("A1").NumberFormat = "$#,##0.00". Pour une date, Range("B1").Value = DateSerial(2025, 9, 15) puis Range("B1").NumberFormat = "yyyy-mm-dd". Définir le format seul sur une chaîne de texte ne fait rien, car il n'y a aucun nombre sous-jacent à afficher.

Quelle est la différence entre NumberFormat et la fonction Format ?

Range.NumberFormat est une propriété de cellule qui pose une règle d'affichage et garde la valeur sous forme de vrai nombre. Format(value, "pattern") est une fonction qui renvoie une String. Utilisez NumberFormat sur les cellules d'une feuille ; utilisez Format pour construire du texte destiné aux messages, aux noms de fichiers ou aux libellés. Écrire Format(...) dans une cellule la transforme en texte que vous ne pouvez plus additionner ni porter dans un graphique.

Pourquoi mes totaux tombent-ils faux après que j'ai formaté les nombres ?

Parce que NumberFormat masque les décimales sans les supprimer. Formater une colonne en "0" affiche des nombres entiers, mais chaque cellule stocke encore ses décimales, si bien que le vrai total les inclut et peut différer de la somme des chiffres affichés. Si le total doit correspondre à ce qui est montré, arrondissez les valeurs avec WorksheetFunction.Round plutôt que de seulement les formater.

Quelle est la différence entre NumberFormat et NumberFormatLocal ?

NumberFormat utilise des codes de format anglais américains (virgule pour les milliers, point pour la décimale) sur chaque machine, il est donc portable. NumberFormatLocal utilise les symboles régionaux de l'utilisateur, qui varient selon les paramètres régionaux. Écrivez vos macros avec NumberFormat pour un comportement cohérent partout, et n'utilisez NumberFormatLocal que lorsque vous reproduisez délibérément ce qu'un utilisateur voit dans ses propres réglages.

Testé dans

Testé dans : Excel 365 (Windows 11), VBA 7.1 — dernière vérification le 11/08/2026.

Guides associés : VBA Font · VBA Cell Color · VBA Format · VBA CStr · VBA Range