Bueno Cesar, la verdad que tenes suerte por dos motivos: el primero, vivir en una localidad tan hermosa como San Martin de los Andes y el segundo que es sábado a la noche, la nena más chica no nos está dejando mirar una buena película y entonces me puse a revisar el blog, en donde hace pocos minutos levantaste tu consulta, a la cual le diste caracter de urgente.
Te comento: Excel tiene funciones específicas para generar números aleatorios y también podemos hacerlo mediante macros. Utilizaré esta segunda opción para resolver tu problema, dado que incorporas una condición: que de los 10 números ninguno se repita... algo bastante complicado de resolver mediante funciones. Si te parece bien dale una leída a
este post, que habla sobre las fórmulas.
[+/-] Ver el resto / Ocultar
Recordemos: la funcion
RND() de
VBA (al igual que
ALEATORIO() de Excel) devuelve un nro aleatorio cualquiera, mayor a cero y menor a 1. En este caso Cesar me solicita que los numeros generados deben estar dentro del rango
1 --> 50. Entonces debemos hacer una pequenia función:
(limite superior - limite inferior + 1) * RND + limite inferior
en el ejemplo planteado esto nos quedaría:
(50 - 1 + 1) * RND + 1
o como el límite inferior es 1 (y entonces ese -1 + 1 quedaría anulado), podría ser:
(50 * RND) + 1
Los numeros aleatorios vienen con decimales. Para quitarlos, simplemente hacemos:
Int((50 * RND) + 1)
Hasta aqui ya sabemos como generar un numero aleatorio en VBA. Veamos ahora una de las posibles formas de resolver el tema de seleccionar 10 que no se repitan. Para los que no lo sepan, si ejecutamos varias veces la funcion RND el mismo numero se puede repetir, como apreciamos en la imagen de abajo:
aunque todos los numeros fueron generados al azar.... varios de ellos se repiten.
Los pasos lógicos:
1) genero un numero aleatorio
2) busco en los registros si ese numero existe
3) si existe, genero un nuevo aleatorio y busco otra vez
4) si no existe, lo almaceno.
5) repito todos los pasos anteriores hasta que la cantidad de numeros almacenados sea igual a 10.
Para codificar los 5 pasos anteriores existen miles de variantes, de las cuales se me ocurre la siguiente:
Sub GenerarAleatorios()
Dim Aleatorio, LimiteInferior, LimiteSuperior, X As Byte
Dim CantidadTotal As Integer
Dim Registro As String
Dim Matrix() As String
Randomize
LimiteInferior = 1
LimiteSuperior = 50
CantidadTotal = 10
While X < CantidadTotal
'generamos el primer nro aleatorio
Aleatorio = Int((LimiteSuperior - LimiteInferior + 1) _
* Rnd + LimiteInferior)
'con la funcion Instr() busco al numero. Si Instr() me
'devuelve 0, no encontró el valor buscado, entonces lo
'agrego a la cadena:
If InStr(1, Registro, Aleatorio) = 0 Then
'y lo almaceno. a la cadena de texto le agrego un
'punto y coma (;). veremos mas adelante el por que
Registro = Registro & Aleatorio & ";"
'aumento a X en 1, para que cuando este contador
'llegue a 10 se produzca la salida del bucle:
X = X + 1
End If
Wend
'el bucle de arriba me generó, por ejemplo, una cadena de
'texto así: 39;15;45;23;32;18;5;4;9;10;
'como primer medida vamos a quitar ese último punto y coma
Registro = Left(Registro, Len(Registro) - 1)
'siguiendo con el hipotético ejemplo, a estas alturas la
'variable registro queda: 39;15;45;23;32;18;5;4;9;10
'como separé a cada uno de los numeros con el mismo carac
'ter, ahora me resulta factible aplicar la función Split()
'para crear una matriz a partir de esa cadena de texto:
Matrix() = Split(Registro, ";")
'colocamos los resultados en un rango de la planilla, para
'que sean visualizados por el usuario:
Columns("A:A").EntireColumn.ClearContents
For X = 0 To UBound(Matrix)
Cells((X + 1), 1).Value = Matrix(X)
Next X
'borramos la matriz, para liberar recursos
Erase Matrix
End Sub
La primera ejecución de la macro me devolvió los siguientes valores:
La segunda:
Y las sucesivas también generaron 10 numeros aleatorios que no se repiten.
Cesar: espero que este ejemplo te sea de utilidad y puedas aplicarlo sin problemas a tu rifa. Suerte
Comentarios
Publicar un comentario