TL;DR —
Rnddevuelve unSinglealeatorio en el rango de0hasta (pero sin incluir)1. Por sí solo no es realmente aleatorio: repite la misma secuencia cada vez que se ejecuta la macro. Llama aRandomizeuna 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 entreloyhi, usaInt((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 —
Rndes 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
Rndpor completo — la seguridad, y elRandBetweende 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
