martes, 24 de marzo de 2015

VBA: Listas aleatorias sin repetición combinados con elementos manuales.

Al hilo de una entrada anterior (ver1 y ver2) un lector preguntaba por la forma de ir generando listados aleatorios no duplicados, combinados con otros elementos manuales:
...Somos 20 empleados y estoy tratando de crear una tabla para designar 5 tareas, 2 de ellas designadas por mi (escogidos de una lista desplegable con los nombres de todos los empleados), pero quiero que las otras 3 sean establecidas de manera aleatoria, escogiendo de los empleados que no participaron en las tareas que fueron designadas previamente (desde ahora Tarea1 y Tarea2, respectivamente).
por ejemplo:
Si designé a Empleado1 realizar Tarea 1 y Empleado2 realizar Tarea 2, quiero que las tareas 3,4 y 5 sean realizadas por cualquier empleado menos Emplado1 y Empleado2 y que tampoco un empleado elegido de manera aleatoria, realice otra de las tareas que se designan de manera aleatoria, es decir, si Empleado3 salió escogido para realizar Tarea3, que no pueda ser designado para tareas 4 o 5, o que Empleado4 (escogido aleatoriamente) y que realiza Tarea4, haga tareas 3 o 5 (lo mismo para un empleado escogido para Tarea5)

Las designaciones de las tareas 1 y 2, son establecidas al principio del día....


El matiz con las entradas comentadas al inicio es que en este caso, partiremos de unos elementos introducidos manualmente, combinando por tanto la aleatoriedad 'pura' de los ejemplos primeros, con un punto de 'manualidad'.
Por eso este proceso es algo distinto, ya que nuestro proceso consiste en reiterar los valores aleatorios hasta dar con uno no introducido manualmente ni generado aleatoriamente con anterioridad.


Comenzamos viendo nuestro modelo de datos:

VBA: Listas aleatorias sin repetición combinados con elementos manuales.



Insertamos y ejecutamos el siguiente procedimiento 'AleaIactaEst':

Sub AleaIactaEst()
'recorremos el rango de empleados...
For Each celda In Range("B2:B6")
'definimos una variable estática para el aleatorio....
Static aleaEmpleado As Integer
    'cuando la celda del empleado esté sin rellenar
    'supondremos queremos completarla aleatoriamente
    If celda.Value = Empty Then
inicioEmpleado:
        'nuestro valor aleatorio...
        aleaEmpleado = Int(20 * Rnd + 1)
        x = 0
        'controlamos no esté repetido el aleatorio en el rango
        For Each empleado In Range("B2:B6")
            If empleado.Value = aleaEmpleado Then
                x = x + 1
            End If
        Next empleado
        'si no está repetido completamos el elemento
        If x = 0 Then
            celda.Value = aleaEmpleado
        Else
            'en caso contrario, esto es, exista el valor aleatorio
            'volvemos a generarlo y repetir el proceso
            GoTo inicioEmpleado
        End If
    End If
Next celda

'Repetimos el mismo proceso para las Tareas
For Each celda2 In Range("C2:C6")
Static aleaTarea As Integer
    If celda2.Value = Empty Then
inicioTarea:
        aleaTarea = Int(5 * Rnd + 1)
        y = 0
        For Each tarea In Range("C2:C6")
            If tarea.Value = aleaTarea Then
                y = y + 1
            End If
        Next tarea
        If y = 0 Then
            celda2.Value = aleaTarea
        Else
            GoTo inicioTarea
        End If
    End If
Next celda2

End Sub



Tras ejecutar el procedimiento el resultado será el siguiente, donde se ve con claridad como no hay repeticiones (especialmente en la columna de Tareas):

VBA: Listas aleatorias sin repetición combinados con elementos manuales.


Consiguiendo así nuestro mix aleatorio-manual sin repeticiones...

5 comentarios:

  1. se podría hacer esto sin macros? y si así fuera como se haría?, lo pregunto porque estoy en esa misma situación.
    gracias y un saludo.

    ResponderEliminar
    Respuestas
    1. Hola Juan,
      no me atrevería a confirmarlo 100% pero no me parece posible realizar esto mismo sin programación, ya que el proceso de comprobación de no repetidos no parece plausible con formulación....
      Saludos

      Eliminar
  2. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  3. Hola:
    Está muy bueno, pero tengo el siguiente problema: Tengo una matriz de números telefónicos con diferentes nombres, es decir, ejemplo, tres listas de equipos distintos, con diferentes nombres, pero que podrían coincidir los números (bueno, no todos guardamos un número con el mismo nombre). Necesito que me arroje todas las coincidencias que puedan existir dentro de esta matriz, ya sea por medio de funciones y fórmulas o por medio de VBA ¿Cómo lo puedo hacer o por lo menos empezar?

    ResponderEliminar
    Respuestas
    1. Hola Armando,
      creo que lo más sencillo sería seleccionar esa matriz y luego aplicar el Formato Condicional con la regla de marcar Duplicados.. eso te marcará las coincidencias dentro de ese rango.

      Saludos

      Eliminar