Tirage au sort

Michael -  
ccm81 Messages postés 11033 Statut Membre -
Bonjour,

J'aimerais créer un tirage au sort à l'aide d'un bouton d'action.
40 chiffres à répartir en 3 parties
entre B4:B16
B19:B31
B41:B54

Merci

6 réponses

  1. Vaucluse Messages postés 27336 Date d'inscription   Statut Contributeur Dernière intervention   6 453
     
    Bonjour
    est ce que ceci ferait l'affaire

    http://www.cijoint.fr/cjlink.php?file=cj201105/cijgP4hQb5.xls

    revenez si besoin

    crdlmnt
    0
    1. Michael
       
      Bonjour, merci celà fonctionne, le seul soucis s'est qu'il y a des doublons par moment et je n'arrive pas à l'intégrer à ma feuille de calcul.
      0
    2. Vaucluse Messages postés 27336 Date d'inscription   Statut Contributeur Dernière intervention   6 453
       
      excuser moi, un mauvais positionnement de la copie dans la macro
      essayez avec celui ci:
      http://www.cijoint.fr/cjlink.php?file=cj201105/cijfmJldXc.xls
      ça devrait aller mieux!
      revenez si problème
      crdlmnt
      0
  2. ccm81 Messages postés 11033 Statut Membre 2 434
     
    bonjour a tous les deux

    une autre proposition qui fonctionne dans un temps raisonnable si la plage n'est pas trop vaste

    Option Explicit
    Option Base 1

    Private Sub CommandButton1_Click()
    Const plage1 = "B4:B16"
    Const plage2 = "B19:B31"
    Const plage3 = "B41:B54"
    Const n = 40
    Dim T(n) As Long
    Dim c
    Dim plage As Range
    Dim k As Long, i As Long, a As Long
    Dim Trouve As Boolean
    Set plage = Union(Range(plage1), Range(plage2), Range(plage3))
    For k = 1 To n
      T(k) = 0
    Next k
    T(1) = 1 + Int(n * Rnd)
    For k = 2 To n
      Do
        Trouve = False
        a = 1 + Int(n * Rnd)
        For i = 1 To k - 1
          Trouve = Trouve Or a = T(i)
        Next i
      Loop Until Not Trouve
      T(k) = a
    Next k
     Set plage = Union(Range(plage1), Range(plage2), Range(plage3))
    k = 0
    For Each c In plage
      k = k + 1
      c.Value = T(k)
    Next c
    End Sub


    bonne suite
    0
    1. Michael
       
      Bonjour, solution beaucoup plus simple il est vrai.
      J'ai juste un soucis, lorsque j'ouvre le visual basic et que je rentre la progr cela fonctionne TB en actionnant le bouton "Exécuter". Or, une fois visual basic fermé, l'on me notifie en message d'alerte que : Impossible d'exécuter la macro !Bouton1_clic'. Il est possible qu'elle ne soit pas disponible dans ce classeur ou que toutes les macros soient desactivés"
      J'ai pourtant, il me semble activé les macros du fichier...
      0
  3. ccm81 Messages postés 11033 Statut Membre 2 434
     
    re

    j'avais choisi l'option de mettre un bouton (activeX) dans la feuille, mais on peut se débrouiller sans en mettant la procedure dans un module moyennant quelques modifs

    Option Explicit
    Option Base 1
    
    Public Sub Tirage()
    Const plage1 = "B4:B16"
    Const plage2 = "B19:B31"
    Const plage3 = "B41:B54"
    Const n = 40
    Dim T(n) As Long
    Dim c
    Dim plage As Range
    Dim k As Long, i As Long, a As Long
    Dim Trouve As Boolean
    For k = 1 To n
      T(k) = 0
    Next k
    T(1) = 1 + Int(n * Rnd)
    For k = 2 To n
      Do
        Trouve = False
        a = 1 + Int(n * Rnd)
        For i = 1 To k - 1
          Trouve = Trouve Or a = T(i)
        Next i
      Loop Until Not Trouve
      T(k) = a
    Next k
    With Sheets(1) ' ici tu mets ton n° de feuille ou son "nom"
      Set plage = Union(.Range(plage1), .Range(plage2), .Range(plage3))
      k = 0
      For Each c In plage
        k = k + 1
        c.Value = T(k)
      Next c
    End With
    End Sub


    tu as les deux options ici

    http://www.cijoint.fr/cjlink.php?file=cj201105/cijK8P0Fxh.xls

    bonne suite
    0
  4. michel_m Messages postés 18903 Date d'inscription   Statut Contributeur Dernière intervention   3 320
     
    Bonjour à tous

    Une ptite rapide

    Sub tirage_sans_remise() 
    Dim gagnants As Object 
    Dim cptr As Byte 
    Dim elus 
    
    Randomize 
    Set gagnants = CreateObject("scripting.dictionary") 
    For cptr = 1 To 40 
         tirage = Int(Rnd * 200) + 1 
         If Not gagnants.exists(tirage) Then 
              gagnants.Add tirage, tirage 
         Else 
              cptr = cptr - 1 
         End If 
    Next 
    elus = gagnants.items 
    
    Application.ScreenUpdating = False 
    Range("B4").Resize(40, 1) = Application.Transpose(elus) 
    Range("A17:A18").EntireRow.Insert 
    Range("A32:A40").EntireRow.Insert 
    
    
    End Sub 
    

    Michel
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. ccm81 Messages postés 11033 Statut Membre 2 434
     
    re
    une autre solution, moins sophistiquée que celle de michel, mais ....

    Option Explicit 
    
    Private Sub CommandButton1_Click() 
    Const plage1 = "B4:B16" 
    Const plage2 = "B19:B31" 
    Const plage3 = "B41:B54" 
    Const n = 40 
    Dim T(40) As Long 
    Dim c 
    Dim plage As Range 
    Dim k As Long, a As Long, b As Long 
    For k = 1 To n 
      T(k) = k 
    Next k 
    For k = 1 To n 
      a = 1 + Int(40 * Rnd) 
      b = T(k) 
      T(k) = T(a) 
      T(a) = b 
    Next k 
    Set plage = Union(Range(plage1), Range(plage2), Range(plage3)) 
    k = 0 
    For Each c In plage 
      k = k + 1 
      c.Value = T(k) 
    Next c 
    End Sub 

    bonne journée
    0
    1. michel_m Messages postés 18903 Date d'inscription   Statut Contributeur Dernière intervention   3 320
       
      Bonjour ccm

      pourquoi "sophistiqué" ?
      0
    2. ccm81 Messages postés 11033 Statut Membre 2 434
       
      bonjour michel,

      ça doit être dû à mon ignorance concernant l'objet "scripting.dictionary", qui permet de façon simple de voir si un élément appartient au dictionnaire
      je découvre ...
      donc ça remplacerait la notion d'ensemble au sens math du terme ?

      au passage je me suis permis une petite modif

      For cptr = 1 To 40
        Do
          tirage = Int(Rnd * 40) + 1
        Loop Until (Not gagnants.exists(tirage))
        gagnants.Add tirage, tirage
      Next cptr


      une question pourquoi le 2° tirage dans gagnants.Add tirage, tirage ?

      merci
      0
  7. michel_m Messages postés 18903 Date d'inscription   Statut Contributeur Dernière intervention   3 320
     
    re,

    pour la petite modif, le demandeur ne semble (ou plutôt j'ai mal lu) pas avoir dit qu'il s'agissait de nombres 1 à 40, j'ai mis 200 comme j'aurais pu mettre 12345

    l'objet dictionary est un truc "magique" de VBA: il ne prend que les éléments uniques et possède une clé et un item par exemple on cherche la 1° ligne où
    on recontre une ref, ce qui est très rapide car n'obligeant pas une gestion d'erreur (on error resume..)

    clé=cells(lig,col)
    ref=cells(lig,col).row
    if not dico.exists(cle) then
        dici.add clé, ref


    pour retrouver la ligne rapidement
    clé_out=cells(lig1, col1).value
    if dico.exist(cells(clé_out)
    ligne=dico.item(clé_out)


    dans notre cas comme la clé et la ref sont les m^mes on marque add cle, cle

    a noter que ref peut-etre du type range("A1:T1") ou une variable-tableau ou...

    d'autre part le dico peut être restitué sous forme de variable-tableaux
    liste_ref=dico.items
    liste_cle=liste.keys

    la restitution dans les cellules est ainsi très rapide par l'instruction que j'ai employé
    Range("B4").Resize(40, 1) = Application.Transpose(elus) 


    je te mets ci joint une démo faite sur ccm, sans coucou de remerciement de la part du demandeur comme d'hab, pour une traduction d'une moyenne de 54000 mots tirés au sort sur 10000 lignes avec un dico anglais-francais de 1000 mots

    la démo t'indique le temps passé 0,8 secondes avec mon vieux coucou
    https://www.cjoint.com/?0ErmQtgkXBp

    d'autre part si tu ne le connais pas un tuto sur les variables tableaux
    https://silkyroad.developpez.com/vba/tableaux/

    crois moi, ca vaut le coup d'investir dans ces 2 possibilités car ca ouvre de sacrées solutions surtout dans des grands tableaux

    En espèrant que cela t'interessera...

    0
    1. ccm81 Messages postés 11033 Statut Membre 2 434
       
      re

      merci pour tes explications, qui vont occuper les longues veillées de printemps
      l'exemple "interprete" est impressionnant de rapidité (0.5 s sur ma machine de 2 ans d'age)

      A part pour quelques situations de simulation ou de tri je n'ai jamais eu l'occasion de traiter de grands tableaux,

      j'avais évoqué la notion d'ensemble qu'on rencontre en delphi ou en pascal (set of) bien commode, mais qui n'a rien à voir, côté taille, avec le dictionnaire de VBA.

      dans ton classeur interprete, il y a deux petites erreurs dans la procedure traduire
      - la declaration de derlig_lex le "integer" est mal tapé
      - derlig = ------ (Cells (cells a pris un "." intempestif )

      pour la modif du post 10, en fait c'était surtout pour le
      if then else qui oblige à une modification acrobatique de la variable cptr de la boucle for

      merci encore
      0