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

VBA Rnd in Excel — Zufallszahlen, Randomize und die Falle der sich wiederholenden Folge

|

VBA Rnd in Excel — Zufallszahlen, Randomize und die Falle der sich wiederholenden Folge

KurzfassungRnd gibt einen zufälligen Single im Bereich von 0 bis (aber ohne) 1 zurück. Für sich allein ist es nicht wirklich zufällig: Es spielt bei jedem Lauf des Makros die gleiche Folge ab. Rufen Sie Randomize einmal ganz oben auf, um den Generator aus der Systemuhr zu seeden und bei jedem Lauf eine andere Folge zu bekommen. Für eine ganze Zahl zwischen lo und hi verwenden Sie Int((hi - lo + 1) * Rnd + lo).

Sub RandomInteger()
    Dim n As Long
    Randomize                          ' einmal aus der Uhr seeden - vor Rnd ausfuehren
    n = Int((6 - 1 + 1) * Rnd + 1)     ' eine ganze Zahl von 1 bis 6, wie ein Wuerfelwurf
    Debug.Print n
End Sub

Rnd, Round und Mod sind drei Mathematik-Werkzeuge, die einfach aussehen und eine scharfe Kante verbergen. Bei Rnd ist die Kante, dass „zufällig" ein Versprechen ist, das es erst hält, wenn Sie es darum bitten — weshalb so viele Makros jedes einzelne Mal denselben zufälligen Gewinner ziehen.

Was Sie lernen

  • Das Denkmodell — Rnd ist ein Pseudozufallsgenerator mit Startwert, keine echte Zufälligkeit
  • Der Fehler Nummer eins — ein „zufälliges" Ergebnis, das bei jedem Lauf identisch ist, weil Randomize fehlt
  • Die korrekte Formel für eine ganze Zahl in einem Bereich, und der Off-by-one-Fehler, den viele machen
  • Wie Sie eine Folge absichtlich reproduzieren, für Tests und Demos
  • Wann Sie Rnd ganz auslassen — Sicherheit, und das RandBetween des Arbeitsblatts

Das Denkmodell: Rnd hat einen Startwert, ist nicht wirklich zufällig

Ein Computer kann keine echte Zufälligkeit herbeizaubern; er führt eine Formel aus, die Zahlen erzeugt, die zufällig aussehen, ausgehend von einem Startwert (Seed). Rnd ist einer dieser Pseudozufallsgeneratoren. Geben Sie ihm denselben Startwert, erzeugt er denselben Strom von Zahlen — was ein Vorteil für die Reproduzierbarkeit ist und eine Falle, wenn Sie nicht wussten, dass es passiert.

Hier ist die Falle in voller Länge. VBA startet jede Sitzung mit demselben Standard-Startwert, also teilt ein Makro, das nur Rnd aufruft, bei jedem Lauf die identische Folge aus:

Sub SameEveryTime()
    Dim i As Long
    For i = 1 To 3
        Debug.Print Rnd        ' 0.7055475, 0.533424, 0.5795186 ...
    Next i                     ' - und die GLEICHEN drei Zahlen beim naechsten Lauf, und dem naechsten
End Sub

Darum zieht die „zufällige" Verlosung immer wieder dieselbe Person, und die „gemischte" Liste kommt in derselben Reihenfolge heraus. Rnd tut genau das, was man ihm gesagt hat; niemand hat ihm gesagt, an einer neuen Stelle zu beginnen.

Die Lösung Nummer eins: Randomize, einmal, ganz oben

Randomize setzt den Startwert des Generators neu aus dem Systemtimer, sodass jeder Lauf von einem anderen Punkt aus startet und die Folge tatsächlich variiert:

Sub DifferentEveryTime()
    Dim i As Long
    Randomize                  ' aus der Uhr seeden - fuers ganze Makro, nicht pro Zahl
    For i = 1 To 3
        Debug.Print Rnd        ' jetzt drei andere Zahlen bei jedem Lauf
    Next i
End Sub

Zwei Regeln bringen Randomize dazu, sich richtig zu verhalten. Rufen Sie es einmal auf, nahe dem Anfang des Makros — nicht innerhalb der Schleife. Wiederholtes Seeden aus einer schnellen Uhr kann Ihnen zweimal hintereinander denselben Startwert geben und den Sinn zunichtemachen. Und rufen Sie es vor Rnd auf, denn es setzt den Startpunkt, aus dem die folgenden Rnd-Aufrufe schöpfen. Ein Randomize ganz oben ist alles, was ein normales Makro braucht.

Eine ganze Zahl in einem Bereich, ohne den Off-by-one-Fehler

Rnd gibt Ihnen einen Bruchteil; Sie wollen fast immer eine ganze Zahl zwischen zwei Grenzen. Die Formel, die es richtig macht, sollte man sich merken, denn die naheliegende Abkürzung ist falsch:

n = Int((hi - lo + 1) * Rnd + lo)      ' RICHTIG - jeder Wert lo..hi ist moeglich
n = Int(Rnd * hi) + 1                  ' subtil falsch, wenn lo nicht 1 ist / Raender daneben

Das + 1 innerhalb der Spanne ist entscheidend: Rnd gibt nie 1 zurück, ohne es kann der obere Wert hi also nie vorkommen. Int((6 - 1 + 1) * Rnd + 1) deckt 1 bis 6 einschließlich ab — ein fairer Würfel. Ändern Sie lo und hi, und dieselbe Form deckt jeden einschließenden Bereich ab. Kombinieren Sie sie mit Int, um den Bruchteil fallen zu lassen, und Sie haben saubere, gleichmäßig verteilte ganze Zahlen.

Eine Folge absichtlich reproduzieren

Weil Rnd einen Startwert hat, können Sie seinen Determinismus in einen Vorteil verwandeln. Für Tests, Demos oder einen Fehler, den Sie nachstellen müssen, seeden Sie mit einer festen Zahl, damit die „zufälligen" Daten bei jedem Lauf identisch sind:

Randomize 42                 ' gleicher Startwert -> gleiche Folge, jedes Mal

Randomize mit einem numerischen Argument seedet deterministisch, sodass die folgenden Rnd-Aufrufe denselben Strom reproduzieren. Es gibt auch Rnd mit einem negativen Argument — Rnd(-1) —, das eine wiederholbare, an diese Zahl gebundene Folge neu startet, und Rnd(0), das einfach die letzte Zahl erneut zurückgibt. Die Kernaussage ist symmetrisch: Muss ein Ergebnis sich zwischen den Läufen unterscheiden, dann Randomize aus der Uhr; muss es reproduzierbar sein, dann Randomize mit einer Konstanten. Zufälligkeit, die Sie nicht steuern können, ist so oder so ein Fehler.

Wann Sie Rnd nicht verwenden sollten

Rnd ist für Stichproben, Mischen und das Erzeugen von Testdaten gebaut — nicht für irgendetwas, das nicht erratbar sein darf. Es ist ein vorhersagbarer Pseudozufallsgenerator, verwenden Sie es also niemals für Passwörter, Tokens oder Sicherheitscodes; eine entschlossene Person kann seine Ausgabe reproduzieren. Nehmen Sie dafür eine kryptografische API.

Und wenn Sie nur eine zufällige ganze Zahl in Zellen ablegen müssen, ist die Arbeitsblattfunktion oft einfacher: Application.WorksheetFunction.RandBetween(lo, hi) gibt direkt eine einschließende ganze Zahl zurück, ohne Int-Formel. Ein echter Vorteil von Rnd gegenüber RAND()/RANDBETWEEN des Blatts ist allerdings: Jene sind volatil und rechnen bei jeder Bearbeitung neu, sodass die gezogenen Werte sich ständig ändern. Rnd feuert einmal, wenn das Makro läuft, und die Zahlen bleiben stehen — genau das, was Sie wollen, wenn eine Stichprobe gezogen und dann eingefroren werden muss.

Wie ExcelMaster hilft

Rnd scheitert auf Weisen, die aussehen, als würde es funktionieren: Die Ziehung läuft, Zahlen erscheinen, und erst später bemerkt jemand, dass es dieselben Zahlen sind wie beim letzten Mal — oder dass das obere Ende des Bereichs nie auftaucht, oder dass sich ein „sicherer" Code trivial reproduzieren lässt.

ExcelMaster lässt Sie sagen, wofür die Zufälligkeit da ist — „wähle 20 zufällige Zeilen zur Prüfung" oder „weise jeder Bestellung einen zufälligen Prüfer zu" — und seedet mit Randomize, damit die Läufe sich wirklich unterscheiden, nutzt die Form Int((hi - lo + 1) * Rnd + lo), damit jeder Wert erreichbar ist, und lotst Sie zu einer kryptografischen Quelle, sobald das Wort „sicher" fällt. Sie behalten die Arbeitsmappe und den Code.

Häufig gestellte Fragen

Warum bleibt meine VBA-Zufallszahl jedes Mal gleich?

Weil Sie Randomize nicht aufgerufen haben. Rnd startet in jeder Sitzung vom selben Standard-Startwert, spielt also bei jedem Lauf die identische Folge ab. Fügen Sie Randomize einmal nahe dem Anfang des Makros ein, vor jedem Rnd, um den Generator aus der Systemuhr zu seeden und bei jedem Lauf andere Zahlen zu bekommen.

Wie erzeuge ich in VBA eine Zufallszahl zwischen zwei Werten?

Verwenden Sie Int((hi - lo + 1) * Rnd + lo). Zum Beispiel gibt Int((6 - 1 + 1) * Rnd + 1) eine ganze Zahl von 1 bis 6 einschließlich. Das + 1 innerhalb der Spanne ist wesentlich — Rnd gibt nie 1 zurück, ohne es kann die obere Grenze also nie vorkommen. Rufen Sie zuerst Randomize auf.

Was ist der Unterschied zwischen Rnd und Randomize?

Rnd erzeugt die nächste Pseudozufallszahl in der Folge; Randomize setzt den Startwert, von dem diese Folge ausgeht. Rnd für sich allein startet immer vom selben Startwert, Sie bekommen also bei jedem Lauf dieselben Zahlen. Randomize (aus der Uhr oder aus einer festen Zahl) ändert den Startpunkt.

Wie bekomme ich für Tests bei jedem Lauf dieselbe Zufallsfolge?

Seeden Sie mit einer Konstanten: Randomize 42. Derselbe numerische Startwert reproduziert dieselbe Folge von Rnd-Werten, was genau das ist, was Sie wollen, um einen Test oder eine Demo wiederholbar zu machen. Nutzen Sie Randomize ohne Argument (Startwert aus der Uhr), wenn der Lauf sich stattdessen unterscheiden soll.

Kann ich VBA Rnd für Passwörter oder Sicherheitscodes verwenden?

Nein. Rnd ist ein vorhersagbarer Pseudozufallsgenerator — seine Ausgabe lässt sich reproduzieren —, also ist es unsicher für Passwörter, Tokens oder alles, was nicht erratbar sein darf. Nutzen Sie es für Stichproben, Mischen und Testdaten; nehmen Sie für Sicherheit eine kryptografische API.

Getestet in

Getestet in: Excel 365 (Windows 11), VBA 7.1 — zuletzt geprüft am 18.09.2026.

Verwandte Anleitungen: VBA Round · VBA Mod · VBA For-Schleife · VBA WorksheetFunction · VBA Timer