En bref —
Range.NumberFormatest 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.4999avecRange("A1").NumberFormat = "0"affiche 5 à l'écran — maisA1.Valuevaut toujours5.4999, etA1 + A1fait10.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é, etNumberFormatest 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 —
NumberFormatest 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 fonctionFormat(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 —
NumberFormatface à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.NumberFormatest 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 :
0est un chiffre forcé,#un chiffre optionnel."0.00"affiche toujours deux décimales (5devient5.00) ;"#.##"en affiche jusqu'à deux et supprime les zéros de fin (5reste5).,groupe les milliers."#,##0"transforme1234567en1,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
