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

VBA Rnd dans Excel — nombres aléatoires, Randomize et le piège de la séquence qui se répète

|

VBA Rnd dans Excel — nombres aléatoires, Randomize et le piège de la séquence qui se répète

TL;DRRnd renvoie un Single aléatoire dans l'intervalle allant de 0 jusqu'à 1 (exclu). Livré à lui-même, il n'est pas vraiment aléatoire : il rejoue la même séquence à chaque exécution de la macro. Appelez Randomize une fois, en tête, pour amorcer le générateur à partir de l'horloge du système et obtenir une séquence différente à chaque exécution. Pour un entier entre lo et hi, utilisez Int((hi - lo + 1) * Rnd + lo).

Sub RandomInteger()
    Dim n As Long
    Randomize                          ' amorce une fois depuis l'horloge - a faire avant Rnd
    n = Int((6 - 1 + 1) * Rnd + 1)     ' un entier de 1 a 6, comme un lancer de de
    Debug.Print n
End Sub

Rnd, Round et Mod sont trois outils mathématiques d'allure simple qui cachent un tranchant. Pour Rnd, le tranchant, c'est qu'« aléatoire » est une promesse qu'il ne tient pas tant que vous ne le lui demandez pas — ce qui explique pourquoi tant de macros désignent le même gagnant « aléatoire » à chaque fois.

Ce que vous allez apprendre

  • Le modèle mental — Rnd est un générateur pseudo-aléatoire à graine, pas du vrai hasard
  • Le bug numéro un — un résultat « aléatoire » identique à chaque exécution parce que Randomize manque
  • La bonne formule pour un entier dans un intervalle, et l'erreur d'un cran que les gens commettent
  • Comment reproduire une séquence à dessein, pour les tests et les démonstrations
  • Quand renoncer complètement à Rnd — la sécurité, et le RandBetween de la feuille

Le modèle mental : Rnd est à graine, pas vraiment aléatoire

Un ordinateur ne peut pas faire surgir du vrai hasard ; il exécute une formule qui produit des nombres d'apparence aléatoire, en partant d'une graine. Rnd est l'un de ces générateurs pseudo-aléatoires. Donnez-lui la même graine et il produit le même flux de nombres — ce qui est un atout pour la reproductibilité et un piège si vous ignoriez que cela se passait.

Voici le piège dans son entier. VBA démarre chaque session avec la même graine par défaut, si bien qu'une macro qui se contente d'appeler Rnd distribue la séquence identique à chaque exécution :

Sub SameEveryTime()
    Dim i As Long
    For i = 1 To 3
        Debug.Print Rnd        ' 0.7055475, 0.533424, 0.5795186 ...
    Next i                     ' - et les MEMES trois nombres a l'execution suivante, et la suivante
End Sub

Voilà pourquoi le tirage au sort « aléatoire » désigne toujours la même personne, et pourquoi la liste « mélangée » ressort dans le même ordre. Rnd fait exactement ce qu'on lui a dit ; personne ne lui a dit de repartir d'un nouveau point.

Le correctif numéro un : Randomize, une fois, en tête

Randomize réamorce le générateur à partir de la minuterie du système, si bien que chaque exécution part d'un point différent et que la séquence varie réellement :

Sub DifferentEveryTime()
    Dim i As Long
    Randomize                  ' amorce depuis l'horloge - pour toute la macro, pas par nombre
    For i = 1 To 3
        Debug.Print Rnd        ' trois nombres differents a chaque execution maintenant
    Next i
End Sub

Deux règles font que Randomize se tient bien. Appelez-le une fois, près du début de la macro — pas à l'intérieur de la boucle. Amorcer de façon répétée à partir d'une horloge rapide peut vous donner deux fois de suite la même graine et ruiner l'intérêt de la chose. Et appelez-le avant Rnd, car il fixe le point de départ dont les appels Rnd suivants tirent leurs valeurs. Un seul Randomize en tête, c'est tout ce dont une macro normale a besoin.

Un entier dans un intervalle, sans l'erreur d'un cran

Rnd vous donne une fraction ; vous voulez presque toujours un entier entre deux bornes. La formule qui vise juste mérite d'être mémorisée, car le raccourci évident est faux :

n = Int((hi - lo + 1) * Rnd + lo)      ' BON - chaque valeur lo..hi est possible
n = Int(Rnd * hi) + 1                  ' subtilement faux quand lo n'est pas 1 / bornes decalees

Le + 1 à l'intérieur de l'étendue compte : Rnd ne renvoie jamais 1, donc sans lui la valeur haute hi ne peut jamais sortir. Int((6 - 1 + 1) * Rnd + 1) couvre 1 à 6 inclus — un dé équitable. Changez lo et hi et la même forme couvre n'importe quel intervalle inclusif. Associez-la à Int pour retirer la fraction et vous obtenez des entiers nets, répartis uniformément.

Reproduire une séquence à dessein

Parce que Rnd est à graine, vous pouvez transformer son déterminisme en avantage. Pour des tests, des démonstrations, ou un bug que vous devez recréer, amorcez avec un nombre fixe pour que les données « aléatoires » soient identiques à chaque exécution :

Randomize 42                 ' meme graine -> meme sequence, a chaque fois

Randomize avec un argument numérique amorce de façon déterministe, si bien que les appels Rnd qui suivent reproduisent le même flux. Il existe aussi Rnd avec un argument négatif — Rnd(-1) — qui redémarre une séquence reproductible liée à ce nombre, et Rnd(0), qui renvoie simplement à nouveau le dernier nombre. La conclusion est symétrique : si un résultat doit différer d'une exécution à l'autre, Randomize depuis l'horloge ; s'il doit être reproductible, Randomize avec une constante. Un hasard que vous ne pouvez pas contrôler est un bug dans les deux cas.

Quand ne pas utiliser Rnd

Rnd est fait pour l'échantillonnage, le brassage et la génération de données de test — pas pour quoi que ce soit qui doive rester indevinable. C'est un générateur pseudo-aléatoire prévisible, alors ne l'utilisez jamais pour des mots de passe, des jetons ou des codes de sécurité ; une personne déterminée peut reproduire sa sortie. Pour cela, utilisez une API cryptographique.

Et si vous avez seulement besoin d'un entier aléatoire déposé dans des cellules, la fonction de la feuille est souvent plus simple : Application.WorksheetFunction.RandBetween(lo, hi) renvoie directement un entier inclusif, sans formule Int. Rnd a toutefois un vrai avantage sur les RAND()/RANDBETWEEN de la feuille : ces derniers sont volatils et se recalculent à chaque modification, si bien que les valeurs échantillonnées changent sans cesse. Rnd se déclenche une seule fois quand la macro s'exécute et les nombres restent en place — exactement ce que vous voulez quand un échantillon doit être tiré puis figé.

Comment ExcelMaster vous aide

Rnd échoue de façons qui ressemblent à un bon fonctionnement : le tirage s'exécute, des nombres apparaissent, et ce n'est que plus tard que quelqu'un remarque que ce sont les mêmes nombres que la dernière fois — ou que le haut de l'intervalle ne sort jamais, ou qu'un code « sécurisé » se reproduit trivialement.

ExcelMaster vous laisse dire à quoi sert le hasard — « choisis 20 lignes au hasard à auditer » ou « attribue à chaque commande un relecteur aléatoire » — et il amorce avec Randomize pour que les exécutions diffèrent vraiment, utilise la forme Int((hi - lo + 1) * Rnd + lo) pour que chaque valeur soit atteignable, et vous oriente vers une source cryptographique dès que le mot « sécurisé » surgit. Vous gardez le classeur et le code.

Questions fréquentes

Pourquoi mon nombre aléatoire VBA reste-t-il le même à chaque fois ?

Parce que vous n'avez pas appelé Randomize. Rnd part de la même graine par défaut à chaque session, il rejoue donc la séquence identique à chaque exécution. Ajoutez Randomize une fois près du début de la macro, avant tout Rnd, pour amorcer le générateur à partir de l'horloge du système et obtenir des nombres différents à chaque exécution.

Comment générer un nombre aléatoire entre deux valeurs en VBA ?

Utilisez Int((hi - lo + 1) * Rnd + lo). Par exemple, Int((6 - 1 + 1) * Rnd + 1) donne un entier de 1 à 6 inclus. Le + 1 à l'intérieur de l'étendue est essentiel — Rnd ne renvoie jamais 1, donc sans lui la borne supérieure ne peut jamais sortir. Appelez Randomize d'abord.

Quelle est la différence entre Rnd et Randomize ?

Rnd produit le prochain nombre pseudo-aléatoire de la séquence ; Randomize fixe la graine dont cette séquence part. Rnd seul part toujours de la même graine, vous obtenez donc les mêmes nombres à chaque exécution. Randomize (depuis l'horloge, ou depuis un nombre fixe) change le point de départ.

Comment obtenir la même séquence aléatoire à chaque exécution pour un test ?

Amorcez avec une constante : Randomize 42. La même graine numérique reproduit la même séquence de valeurs Rnd, ce qui est exactement ce que vous voulez pour rendre un test ou une démonstration reproductible. Utilisez Randomize sans argument (graine d'horloge) quand vous voulez au contraire que l'exécution diffère.

Puis-je utiliser VBA Rnd pour des mots de passe ou des codes de sécurité ?

Non. Rnd est un générateur pseudo-aléatoire prévisible — sa sortie peut être reproduite — il n'est donc pas sûr pour des mots de passe, des jetons ou quoi que ce soit qui doive rester indevinable. Utilisez-le pour l'échantillonnage, le brassage et les données de test ; utilisez une API cryptographique pour la sécurité.

Testé dans

Testé dans : Excel 365 (Windows 11), VBA 7.1 — vérifié le 18/09/2026.

Guides associés : VBA Round · VBA Mod · VBA For Loop · VBA WorksheetFunction · VBA Timer