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

VBA Rnd en Excel — números aleatorios, Randomize y la trampa de la secuencia que se repite

|

VBA Rnd en Excel — números aleatorios, Randomize y la trampa de la secuencia que se repite

TL;DRRnd devuelve un Single aleatorio en el rango de 0 hasta (pero sin incluir) 1. Por sí solo no es realmente aleatorio: repite la misma secuencia cada vez que se ejecuta la macro. Llama a Randomize una vez, arriba del todo, para sembrar el generador desde el reloj del sistema y obtener una secuencia distinta en cada ejecución. Para un entero entre lo y hi, usa Int((hi - lo + 1) * Rnd + lo).

Sub RandomInteger()
    Dim n As Long
    Randomize                          ' siembra una vez desde el reloj - hazlo antes de Rnd
    n = Int((6 - 1 + 1) * Rnd + 1)     ' un numero entero de 1 a 6, como una tirada de dado
    Debug.Print n
End Sub

Rnd, Round y Mod son tres herramientas matemáticas que parecen simples y esconden un filo afilado. En Rnd, el filo es que «aleatorio» es una promesa que no cumple hasta que se lo pides —que es por lo que tantas macros eligen al mismo ganador aleatorio una y otra vez—.

Lo que aprenderás

  • El modelo mental — Rnd es un generador pseudoaleatorio con semilla, no aleatoriedad de verdad
  • El error número uno — un resultado «aleatorio» que es idéntico en cada ejecución porque falta Randomize
  • La fórmula correcta para un número entero en un rango, y el desfase de uno que la gente comete
  • Cómo reproducir una secuencia a propósito, para pruebas y demos
  • Cuándo saltarte Rnd por completo — la seguridad, y el RandBetween de la hoja

El modelo mental: Rnd tiene semilla, no es realmente aleatorio

Un ordenador no puede conjurar aleatoriedad de verdad; ejecuta una fórmula que produce números que parecen aleatorios, partiendo de una semilla. Rnd es uno de estos generadores pseudoaleatorios. Dale la misma semilla y produce el mismo flujo de números —lo cual es una ventaja para la reproducibilidad y una trampa si no sabías que pasaba—.

Aquí está la trampa completa. VBA arranca cada sesión con la misma semilla por defecto, así que una macro que solo llama a Rnd reparte la secuencia idéntica en cada ejecución:

Sub SameEveryTime()
    Dim i As Long
    For i = 1 To 3
        Debug.Print Rnd        ' 0.7055475, 0.533424, 0.5795186 ...
    Next i                     ' - y los MISMOS tres numeros la proxima vez, y la siguiente
End Sub

Por eso el sorteo «aleatorio» sigue eligiendo a la misma persona, y la lista «barajada» sale en el mismo orden. Rnd está haciendo exactamente lo que se le dijo; nadie le dijo que empezara en un sitio nuevo.

La solución número uno: Randomize, una vez, arriba del todo

Randomize vuelve a sembrar el generador desde el temporizador del sistema, así que cada ejecución parte de un punto distinto y la secuencia varía de verdad:

Sub DifferentEveryTime()
    Dim i As Long
    Randomize                  ' siembra desde el reloj - toda la macro, no por numero
    For i = 1 To 3
        Debug.Print Rnd        ' ahora tres numeros distintos en cada ejecucion
    Next i
End Sub

Dos reglas hacen que Randomize se porte bien. Llámalo una vez, cerca del principio de la macro —no dentro del bucle—. Sembrar repetidamente desde un reloj rápido puede darte la misma semilla dos veces seguidas y echar por tierra el propósito. Y llámalo antes de Rnd, porque fija el punto de partida del que sacan las siguientes llamadas a Rnd. Un solo Randomize arriba del todo es todo lo que necesita una macro normal.

Un número entero en un rango, sin el desfase de uno

Rnd te da una fracción; casi siempre quieres un entero entre dos límites. La fórmula que lo hace bien vale la pena memorizarla, porque el atajo obvio está mal:

n = Int((hi - lo + 1) * Rnd + lo)      ' BIEN - todo valor lo..hi es posible
n = Int(Rnd * hi) + 1                  ' sutilmente mal cuando lo no es 1 / los bordes fallan

El + 1 dentro del tramo importa: Rnd nunca devuelve 1, así que sin él el valor máximo hi nunca puede salir. Int((6 - 1 + 1) * Rnd + 1) cubre de 1 a 6 inclusive —un dado justo—. Cambia lo y hi y la misma forma cubre cualquier rango inclusivo. Combínalo con Int para descartar la fracción y tendrás enteros limpios y repartidos de forma uniforme.

Reproduce una secuencia a propósito

Como Rnd tiene semilla, puedes convertir su determinismo en una ventaja. Para pruebas, demos o un error que necesitas recrear, siembra con un número fijo para que los datos «aleatorios» sean idénticos en cada ejecución:

Randomize 42                 ' misma semilla -> misma secuencia, siempre igual

Randomize con un argumento numérico siembra de forma determinista, así que las llamadas a Rnd que siguen reproducen el mismo flujo. También existe Rnd con un argumento negativo —Rnd(-1)— que reinicia una secuencia repetible atada a ese número, y Rnd(0), que simplemente devuelve otra vez el último número. El titular es simétrico: si un resultado debe diferir entre ejecuciones, Randomize desde el reloj; si debe ser reproducible, Randomize con una constante. La aleatoriedad que no puedes controlar es un error en cualquiera de los dos casos.

Cuándo no usar Rnd

Rnd está hecho para muestrear, barajar y generar datos de prueba —no para nada que deba ser imposible de adivinar—. Es un generador pseudoaleatorio predecible, así que nunca lo uses para contraseñas, tokens o códigos de seguridad; una persona decidida puede reproducir su salida. Para eso, usa una API criptográfica.

Y si solo necesitas un entero aleatorio soltado en las celdas, la función de la hoja suele ser más simple: Application.WorksheetFunction.RandBetween(lo, hi) devuelve directamente un entero inclusivo, sin necesidad de la fórmula Int. Eso sí, una ventaja real de Rnd sobre el RAND()/RANDBETWEEN de la hoja: esos son volátiles y se recalculan con cada edición, así que los valores muestreados cambian sin parar. Rnd se dispara una vez cuando se ejecuta la macro y los números se quedan quietos —justo lo que quieres cuando una muestra debe sacarse y luego congelarse—.

Cómo te ayuda ExcelMaster

Rnd falla de maneras que parecen que funciona: el sorteo se ejecuta, aparecen números, y solo más tarde alguien nota que son los mismos números que la última vez —o que el tope del rango nunca aparece, o que un código «seguro» es trivialmente reproducible—.

ExcelMaster te deja decir para qué sirve la aleatoriedad —«elige 20 filas al azar para auditar» o «asigna a cada pedido un revisor aleatorio»— y siembra con Randomize para que las ejecuciones difieran de verdad, usa la forma Int((hi - lo + 1) * Rnd + lo) para que todo valor sea alcanzable, y te encamina hacia una fuente criptográfica en cuanto aparece la palabra «seguro». Tú conservas el libro y el código.

Preguntas frecuentes

¿Por qué mi número aleatorio de VBA sigue igual cada vez?

Porque no has llamado a Randomize. Rnd parte de la misma semilla por defecto en cada sesión, así que repite la secuencia idéntica en cada ejecución. Añade Randomize una vez cerca del principio de la macro, antes de cualquier Rnd, para sembrar el generador desde el reloj del sistema y obtener números distintos en cada ejecución.

¿Cómo genero un número aleatorio entre dos valores en VBA?

Usa Int((hi - lo + 1) * Rnd + lo). Por ejemplo, Int((6 - 1 + 1) * Rnd + 1) da un número entero de 1 a 6 inclusive. El + 1 dentro del tramo es esencial —Rnd nunca devuelve 1, así que sin él el límite superior nunca puede salir—. Llama primero a Randomize.

¿Cuál es la diferencia entre Rnd y Randomize?

Rnd produce el siguiente número pseudoaleatorio de la secuencia; Randomize fija la semilla de la que parte esa secuencia. Rnd por sí solo siempre parte de la misma semilla, así que obtienes los mismos números en cada ejecución. Randomize (desde el reloj, o desde un número fijo) cambia el punto de partida.

¿Cómo obtengo la misma secuencia aleatoria en cada ejecución para hacer pruebas?

Siembra con una constante: Randomize 42. La misma semilla numérica reproduce la misma secuencia de valores de Rnd, que es justo lo que quieres para hacer repetible una prueba o una demo. Usa Randomize sin argumento (semilla del reloj) cuando prefieras que la ejecución difiera.

¿Puedo usar VBA Rnd para contraseñas o códigos de seguridad?

No. Rnd es un generador pseudoaleatorio predecible —su salida se puede reproducir—, así que no es seguro para contraseñas, tokens ni nada que deba ser imposible de adivinar. Úsalo para muestrear, barajar y generar datos de prueba; usa una API criptográfica para la seguridad.

Probado en

Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 18/09/2026.

Guías relacionadas: VBA Round · VBA Mod · VBA For Loop · VBA WorksheetFunction · VBA Timer