** NORMAS DEL FORO **
Inicio del foro Inicio del foro > Access y VBA > Access y VBA
  Mensajes nuevos Mensajes nuevos RSS - AddItem sin repetidos en cuadro de lista
  Preguntas frecuentes Preguntas frecuentes  Buscar en el foro   Eventos   Registro Registro  Iniciar sesion Iniciar sesion

Tema cerradoAddItem sin repetidos en cuadro de lista

 Responder Responder
Autor
Mensaje
Adrianet Ver desplegable
Habitual
Habitual
Avatar

Unido: 26/Marzo/2015
Localización: Valencia
Estado: Sin conexión
Puntos: 135
Enlace directo a este mensaje Tema: AddItem sin repetidos en cuadro de lista
    Enviado: 30/Julio/2022 a las 12:17
hola amigos del foro,...
sigo peleándome con los cuadros de lista,...
en esta ocasión, estoy construyendo un pequeña aplicación para gestionar boletos de lotería (primitiva y bonoloto, en los que hay 6 valores asignados entre 49 posibles)
para ello utilizo la función Rdn ,.. generando numeros aleatorios
en mi pequeño formulario tengo esté código, ...

en el cuadro de lista (Lista3) sólo hay un campo, que va recogiendo el número generado

Private Sub BtnGeneraNum_Click()
Dim mivalor, vnum As Integer, contador As Byte

mivalor = ((49 * Rnd) + 1)
TxNum = mivalor


If Me.Lista3.ListCount < 6 Then

vnum = Me.TxNum.Value
Me.Lista3.AddItem vnum
  For i = 0 To Me.Lista3.ListCount - 1
     If Me.Lista3.ItemData(i) = vnum Then
     MsgBox "atención, ese número ya ha sido generado"
     End If
  Next i
 Else
MsgBox "ya están los 6 numeros"
End If

End Sub

*** pero no consigo que me controle los números repetidos, es decir que, dentro de las seis generaciones,  puede salir algún número repetido,..

se trataría de evitar el AddItem cuando surgiera algún repetido, ... pero al mismo tiempo dejar que siga corriendo el código hasta que existan 6 números distintos, .

Todas las búsquedas que he realizado antes de consultar aquí, iban todas en la misma dirección:
para evitar duplicados en lista utilice SELECT DISTINC ....

Pero no es de aplicación a este caso en concreto.

Hay alguna manera de borrar o saltar el número duplicado


saludos a todos.
ADRIAN




Arriba
Mihura Ver desplegable
Administrador
Administrador
Avatar

Unido: 06/Mayo/2005
Localización: En la dehesa
Estado: Sin conexión
Puntos: 14017
Enlace directo a este mensaje Enviado: 30/Julio/2022 a las 12:36
Creo que tienes el problema enfocado con herramientas 'no adecuadas' ... LOL

Te planteo dos posibilidades (hay más, seguro):

Primera:
- te creas una matriz con seis elementos 
- obtienes el número con Rnd
- compruebas en la matriz si existe el número (bucle For i=1 to 6)
   · si no existe lo agregas
- controlas el numero de elementos asignados con un contador (p.ej)


Segunda:
- te creas una matriz numérica con 49 elementos (Dim Matriz(1 To 49) as Integer)
- obtienes número
- compruebas si el elemento de la matriz tiene 0:   Matriz(numero) = 0
   · si tiene 0 le pones un 1
   · vas controlando el numero de elementos que pones un 1
- cuando tengas los seis, barres la matriz y los elementos con 1 son los seleccionados


Por cierto, si te toca quiero mi parte ...   Big smile
Jesús Mansilla Castells.
Saludos desde Móstoles.

Access Aplicaciones
Tecsys.es
Arriba
Adrianet Ver desplegable
Habitual
Habitual
Avatar

Unido: 26/Marzo/2015
Localización: Valencia
Estado: Sin conexión
Puntos: 135
Enlace directo a este mensaje Enviado: 30/Julio/2022 a las 12:56
Hola Jesús, gracias por responder.

A ver, sobre el tema de los array y de las matrices aún estoy sin entrar, ... o sea que desconozco todo sobre este tema, ....  Pero tiempo al tiempo, ... ya llegará, ... y entraré a estudiarlos,.

Respecto a tus respuestas, a primera vista, me gusta más la primera (ya te digo, sin conocer nada sobre matrices), ...

Con esa indicación que haces, estaba pensando en cargar los números generados a una tabla temporal, y luego hacer una comprobación de duplicados, ...
pero luego surgiría la necesidad de generar de nuevo tantos números nuevos como se hayan eliminado por ser repetidos, ... y de nuevo volcarlos a la tabla. Tendría que hacer otra rutina para generar y añadir a tabla los nuevos números generados, ... pero no entraña demasiada dificultad.

Crees que voy por buen camino ?, ... 
gracias por tu atención, y un saludo.
Adrián.


Arriba
Mihura Ver desplegable
Administrador
Administrador
Avatar

Unido: 06/Mayo/2005
Localización: En la dehesa
Estado: Sin conexión
Puntos: 14017
Enlace directo a este mensaje Enviado: 30/Julio/2022 a las 17:06
Lo de usar una tabla temporal es como usar una llave inglesa para clavar un clavo, servir ... sirve, ahora bien ....

Si lo haces así, basta con declarar como índice único el campo número y la misma tabla te impedirá tener repetidos.


Jesús Mansilla Castells.
Saludos desde Móstoles.

Access Aplicaciones
Tecsys.es
Arriba
mounir Ver desplegable
Colaborador
Colaborador


Unido: 09/Febrero/2009
Localización: Asturias-España
Estado: Sin conexión
Puntos: 6479
Enlace directo a este mensaje Enviado: 31/Julio/2022 a las 11:37
Un Saludo.
Arriba
Adrianet Ver desplegable
Habitual
Habitual
Avatar

Unido: 26/Marzo/2015
Localización: Valencia
Estado: Sin conexión
Puntos: 135
Enlace directo a este mensaje Enviado: 01/Agosto/2022 a las 12:18
hola
Gracias Mounir, ... 
Esos ejemplos de Neckito, es donde yo quería llegar.
Me pondré a estudiarlos, .... Ya he visto en una primera ojeada que utiliza matrices, como decía Jesús.

Pero si se me permite la insistencia, sigo sin comprender porque no se puede en un cuadro de lista (que después de leer un poco lo de las matrices, veo que se parecen en su dinámica (filas, columnas, ... empiezan desde valor inicial Cero - salvo que indique miArray(1 to N), ... y otras cosas parecidas)

Mi idea era conseguir esto:
un cuadro de texto donde se muestra un valor generado (con Rdn, limitando su rango)
un cuadro de lista, donde almacenar los 6 valores no repetidos

un código que controlase lo siguiente:
1.- en la primera generación no hay repetición posible, .... entonces se añade a la lista
   con un IF controlar que las acciones siguientes se ejecuten mientras no se superen los 5 elementos que nos quedan para completar la lista
2.- a partir de la segunda generación, ya entramos en la comprobación de duplicados
    2.0 sólo nos queda un rango de 5 elementos para añadir a la lista
    2.1 se comprueba que en la lista existente en ese momento ese valor no existe
    2.2 se añade a la lista
          si existiera ya, está duplicado y no se acepta, entonces no se añade a la lista (es decir no se usa AddItem)
3. terminar cuando haya 6 items en la lista, que es lo mismo que finalizar el IF porque se ha alcanzado los 5 elementos que nos restaban, ...

Bueno, al final no sé si me he hecho un bucle yo mismo y mis pensamientos,. ...

lo dicho, me pongo a estudiar el ejemplo indicado por Mounir, y de paso, entro ya en el tema de las matrices, como me indicaba Jesús.

Gracias a los dos,,.... y saludos a todos los amigos del foro.
Adrián.

pdta. se me queda la espinita clavada por no saber porqué no se puede hacer con el método del cuadro de lista.







Arriba
mounir Ver desplegable
Colaborador
Colaborador


Unido: 09/Febrero/2009
Localización: Asturias-España
Estado: Sin conexión
Puntos: 6479
Enlace directo a este mensaje Enviado: 01/Agosto/2022 a las 12:38
Hola!

No me puse con el ejemplo de Neckkito, pero no lo veo complicado si te he entendido bien.

- Creas una tabla con 8 columnas (ID + 6 campos " uno para cada número" + campo fecha) o una tabla con tres columnas (Id + campo numero+ fecha) a gusto del consumidor. Luego creas un cuadro de lista basado en esta tabla. Así tienes los sorteos guardados en una tabla, de la otra forma, es decir, insertando los números como lista de valores no se guardan al cerrar la aplicación.

- Cuando generes los números agraciados los insertarías en esta tabla y actualizarías el cuadro de lista.

- ¿Te vale así?

Editado por mounir - 01/Agosto/2022 a las 12:43
Un Saludo.
Arriba
Adrianet Ver desplegable
Habitual
Habitual
Avatar

Unido: 26/Marzo/2015
Localización: Valencia
Estado: Sin conexión
Puntos: 135
Enlace directo a este mensaje Enviado: 01/Agosto/2022 a las 13:01
hola Mounir, ...
En realidad, en mi pequeña aplicación ya tenía eso previsto, y tenía estas tablas:

Apuestas, ,,, idApuesta, FechaApuesta, N1,N2,N3,N4,N5,N6, AC1,AC2,AC3,AC4,AC5,AC6,ACComp
 ... N1  primer numero      AC1 .... se asigna 1 si es acierto
                                      ACComp ... se asigna 1 si es acierto en complementario

Sorteos .... idSorteo, FechaSorteo, M1,M2,M3,M4,M5,M6,Complementario

 Luego mediante consultas, o recordsets ya asignaba los aciertos, ...

pero me enfrasqué en lo de recoger los valores en el cuadro de lista, y una vez el lote completo con los seis números, añadía los valores del cuadro de lista a la tabla Apuestas, ...

en fin, ... esto significa que tengo que usar como origen del cuadro una tabla de datos, ... y que el cuadro de lista ya no tendrá 6 filas sino que tendrá una fila con seis columnas, ...

vale, vamos pues, ... 
gracias y un saludo.
Adrián.

Arriba
fcoval Ver desplegable
Asiduo
Asiduo


Unido: 19/Enero/2013
Estado: Sin conexión
Puntos: 225
Enlace directo a este mensaje Enviado: 01/Agosto/2022 a las 13:38
Con lo sencillo que es usar matrices...como bien te ha aconsejado Mihura:

Function Generar6Aleatorios() '6 valores asignados entre 49 posibles

Dim ArrayNumeros(1 To 6) As Integer
Dim ObtenerUnAleatorio As Integer

For i = LBound(ArrayNumeros) To UBound(ArrayNumeros)
    
SacaAleatorio:
                'Obtener un numero aleatorio desde 1-49 que NO este repetido
                ObtenerUnAleatorio = Int((49 * Rnd) + 1)
                For j = LBound(ArrayNumeros) To UBound(ArrayNumeros)
                    If ArrayNumeros(j) <> ObtenerUnAleatorio Then
                        Else
                            'Debug.Print "ESTA REPETIDO :" & ObtenerUnAleatorio
                            GoTo SacaAleatorio:
                    End If
                Next j
                
            ArrayNumeros(i) = ObtenerUnAleatorio
    'Debug.Print ArrayNumeros(i)
Next i

'-- Numeros aleatorios del 1 al 49 ordenados :
Dim ArrayNumerosOrdenada() As Integer
ArrayNumerosOrdenada = OrdenaMatriz(ArrayNumeros, True)

For i = LBound(ArrayNumerosOrdenada) To UBound(ArrayNumerosOrdenada)
    Debug.Print ArrayNumerosOrdenada(i)
Next i



Y esta función de ayuda por si quieres ordenadar los numeros obtenidos:

Public Function OrdenaMatriz(ArrayIn, Ascending As Boolean)

Dim SrtTemp As Variant
Dim i As Long
Dim j As Long

If Ascending = True Then
    For i = LBound(ArrayIn) To UBound(ArrayIn)
         For j = i + 1 To UBound(ArrayIn)
             If ArrayIn(i) > ArrayIn(j) Then
                 SrtTemp = ArrayIn(j)
                 ArrayIn(j) = ArrayIn(i)
                 ArrayIn(i) = SrtTemp
             End If
         Next j
     Next i
Else
    For i = LBound(ArrayIn) To UBound(ArrayIn)
         For j = i + 1 To UBound(ArrayIn)
             If ArrayIn(i) < ArrayIn(j) Then
                 SrtTemp = ArrayIn(j)
                 ArrayIn(j) = ArrayIn(i)
                 ArrayIn(i) = SrtTemp
             End If
         Next j
     Next i
End If

OrdenaMatriz = ArrayIn

End Function

Arriba
Adrianet Ver desplegable
Habitual
Habitual
Avatar

Unido: 26/Marzo/2015
Localización: Valencia
Estado: Sin conexión
Puntos: 135
Enlace directo a este mensaje Enviado: 01/Agosto/2022 a las 13:59
hola Fcoval, gracias por tu aportación en este tema

voy a ver también tu código, ... y sí, es verdad, tengo que ponerme al día con lo de usar matrices, ...

gracias, ya te comentaré como me fué,
un saludo

Adrián

Arriba
mounir Ver desplegable
Colaborador
Colaborador


Unido: 09/Febrero/2009
Localización: Asturias-España
Estado: Sin conexión
Puntos: 6479
Enlace directo a este mensaje Enviado: 01/Agosto/2022 a las 16:56
Hola!

Me ha picado la curiosidad y me puse con el ejemplo, es muy sencillo insertar el sorteo en un cuadro de lista.

- El cuadro de lista en su propiedad "Tipo de origen de la lista = Lista de valores"
- En el código añades lo que está en rojo;-


Me.Nombrelista.AddItem listaAleatorios(i)
    
Next i
    
End Sub
Un Saludo.
Arriba
emiliove Ver desplegable
Administrador
Administrador


Unido: 16/Junio/2009
Localización: Mexico
Estado: Sin conexión
Puntos: 5694
Enlace directo a este mensaje Enviado: 01/Agosto/2022 a las 17:00
A mí me parece todo muy bien pero, yo utilizaría Randomize antes de Rnd.

Saludos.
Arriba
Adrianet Ver desplegable
Habitual
Habitual
Avatar

Unido: 26/Marzo/2015
Localización: Valencia
Estado: Sin conexión
Puntos: 135
Enlace directo a este mensaje Enviado: 02/Agosto/2022 a las 08:25
Hola amigos,
Anoche estuve repasando los diversos códigos sobre el asunto, ...

1.- mi código, que utilizaba un cuadro de lista que recogía los números, ... pero que no me controlaba los repetidos.

2.- el código de ejemplo de Neckito, que usa matrices para las acciones (como me aconsejaba Jesús) y un cuadro de texto para mostrar el resultado

3.- el código que necesitaría si empleara una tabla como origen del cuadro de lista, como decía Mounir

4.- el código de Fcoval, que usa matrices, y siendo diferente en las líneas que usa, obtiene el mismo resultado que Neckito, 

Pues bien, al final, después de cocinar todos los ingredientes, he conseguido Generar seis números aleatorios (del 1 al 49) y que no se repitan y me los vaya mostrando en el cuadro de lista, y que al final avise que ha terminado el proceso porque ya tiene los seis números únicos que se buscaban.
Creo que ya me he sacado la espinita que comentaba antes. Lo he conseguido con el cuadro de lista.

Ahora bien, tengo el compromiso de seguir con el tema, usando los códigos con matrices, y así aprendo a usarlas.
Gracias a todos por toda vuestra atención.

''***************
Pego el código: Generar números aleatorios sin repetición, con rango del 1 al 49.

Private Sub BtnGeneraNum_Click()

Dim mivalor

 If Me.Lista3.ListCount < 6 Then

    For i = 0 To 5

   mivalor = Int((49 * Rnd) + 1)

         If i = 0 Then

         Me.Lista3.AddItem mivalor

         Else

             For j = 0 To i

                   If Me.Lista3.ItemData(j) = mivalor Then

                   i = i - 1

                  Exit For

                  End If

           Next j

     End If

 Next i

 Else

 MsgBox "ya tenemos los 6 números", vbInformation, “FIN DEL PROCESO”

End If

End Sub



Saludos, y gracias.
Adrián.

Arriba
Adrianet Ver desplegable
Habitual
Habitual
Avatar

Unido: 26/Marzo/2015
Localización: Valencia
Estado: Sin conexión
Puntos: 135
Enlace directo a este mensaje Enviado: 02/Agosto/2022 a las 13:36
hola amigos, ...
Me respondo a mí mismo para puntualizar el funcionamiento del código anterior,..
Resulta que he estado realizando pruebas, una y otra vez, y todo parecía correcto, me sacaba en cada lote unos números que no se repetían, ... pero ,... una de tantas ha salido dos veces el mismo número dentro del lote, ... lo cual indica que sigue sin controlar la aparición de repetidos, ...

He modificado el código, y esta vez he usado la matriz de Neckito, ...
y he realizado multitud de pruebas de funcionamiento, ... y todo bien, no ha aparecido ningún caso de números repetidos,...

El código modificado, usando una matriz -ListaNumeros(5) y añadiendo el numero obtenido (con la indicación de Mounir), al cuadro de lista desde la matriz, ..


' código para generar números sin repetidos, con rango del 1 al 49

Private Sub BtnGeneraNum_Click()

Dim mivalor

ReDim ListaNumeros(5)

If Me.Lista3.ListCount < 6 Then

For i = 0 To 5

mivalor = Int((49 * Rnd) + 1)

       If i = 0 Then

      ListaNumeros(i) = mivalor

      Me.Lista3.AddItem ListaNumeros(i)

     Else

           For j = 0 To i

                If ListaNumeros(j) = mivalor Then

                i = i - 1

               Exit For

               End If

         Next j

   End If

 Next i

Else

 MsgBox "Ya tenemos los 6 números"

End If

End Sub


Bueno, pido disculpas por creer que ya había alcanzado el éxito, cuando no era así.

Ahora, ya sí, con este código, con la estructura de Neckito, y con los aportes de los maestros que me han ayudado en este post, y un poquito de mi esquema inicial, creo que ya lo he conseguido.

Gracias.

Pdta. No soy experto en VBA, sino un simple aficionado que va aprendiendo poco a poco, y que ha encontrado en Access VBA una herramienta de trabajo muy potente, que sirviéndome en mi gestión laboral, además me da la satisfacción de aprender cosas nuevas en este mundo de la programación.

Saludos a todos,

Adrián.




Arriba
 Responder Responder
  Compartir tema   

Ir al foro Permisos de foro Ver desplegable