Générer valeurs aléatoires entre bornes dont la somme déterminée

Résolu
Izy3834 Messages postés 8 Statut Membre -  
ccm81 Messages postés 11033 Statut Membre -
Bonjour tout le monde!

voilà j'ai beau chercher sur internet je ne trouve pas de solution à mon problème, peut-être pourrez-vous m'aider??

Alors je travaille sous Excel 2007 et je pensais écrire un code dans visual basic.

En effet j'aimerai générer des valeurs aléatoires entre bornes, par exemple sur les cellules A1 à A20. Mais je voudrais que la somme de ces valeurs soit égale à un certain nombre.

Sub alea()

Randomize
RandomNumber = Int((99 * Rnd) + 1)
Range("C1") = RandomNumber
End Sub

Ici j'ai réussi à générer une valeur aléatoire entre 0 et 100 mais sur une seule cellule, comment faire pour générer sur une plage?? et la question de la somme reste un mystère....help

Merci d'avance pour vos réponses!

9 réponses

  1. ccm81 Messages postés 11033 Statut Membre 2 434
     
    Une procédure plus rapide à l'exécution qui fait tout dans un tableau en mémoire avant de le transposer dans la feuille

    Const plage = "A1:A20"
    Const total = 10000
    Const mini = 100
    Const maxi = 1000

    Public Sub tirageR()
    Dim n As Long, tot As Long, a As Long, k As Long, d As Long, T
    If Range(plage).Columns.Count > 1 Then Exit Sub
    n = Range(plage).Cells.Count
    ReDim T(1 To n)
    tot = 0
    For k = 1 To n
    a = mini + Int((maxi - mini + 1) * Rnd)
    tot = tot + a
    T(k) = a
    Next k
    If tot < total Then
    d = total - tot
    For k = 1 To d
    a = 1 + Int(n * Rnd)
    If T(a) < maxi Then
    T(a) = T(a) + 1
    Else
    k = k - 1
    End If
    Next k
    ElseIf tot > total Then
    d = tot - total
    For k = 1 To d
    a = 1 + Int(n * Rnd)
    If T(a) > mini Then
    T(a) = T(a) - 1
    Else
    k = k - 1
    End If
    Next k
    End If
    Range(plage) = Application.Transpose(T)
    End Sub

    Cdlmnt
    1
    1. Izy3834 Messages postés 8 Statut Membre
       
      ça fonctionne, ça fonctionne!! Merci infiniment pour votre aide, je n'y serais jamais parvenue sans vous!
      Bon comme vous l'avez fait remarquer il ne faut pas prendre une valeur de b trop grande (ce qui est un peu contraignant car il s'agit de valeur de rayonnement et je ne choisi pas les ordres de grandeurs) mais ça devrait le faire.
      Je n'ai pas encore essayé votre dernière manipulation mais en tout cas merci!!
      0
  2. cs_Le Pivert Messages postés 8437 Statut Contributeur 730
     
    Bonjour,

     Dim c As Range
    For Each c In Range("A1:B50")'a adapter à la plage
    c.Value = Int(Rnd * 99) + c
    Next c

    0
  3. cs_Le Pivert Messages postés 8437 Statut Contributeur 730
     
    Autant pour moi, c'est comme cela:

     Dim c As Range
    For Each c In Range("A1:B50")
    c.Value = Int(Rnd * 99)
    Next c

    0
  4. ccm81 Messages postés 11033 Statut Membre 2 434
     
    Bonjour

    Peut être ceci

    https://www.cjoint.com/?3ArrBhDINWx

    Ctrl+t pour lancer la macro
    Alt-F11 pour acceder au code (dans Module 1)

    Cdlmnt
    0
    1. Izy3834 Messages postés 8 Statut Membre
       
      merci beaucoup de votre aide.
      Cependant quelque chose m'échappe dans le script, comment renseigne-t-on l'intervalle/les bornes??
      0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. Izy3834 Messages postés 8 Statut Membre
     
    merci à tous pour vos réponses!
    0
  7. ccm81 Messages postés 11033 Statut Membre 2 434
     
    maxi = 100 ' total à obtenir
    n =Range(plage).Cells.Count ' nombre de cellules de la plage à traiter
    et j'ai pris une valeur "raisonnable" pour le tirage: de 1 à a
    avec a = 2 * maxi \ n
    mais tu peux la définir autrement

    RQ. Je n'ai pas compris la même chose que cs_Le Pivert que je salue au passage
    0
    1. Izy3834 Messages postés 8 Statut Membre
       
      Merci infiniment pour votre aide! J'ai réussi à changer la borne supérieur par contre pour la borne inférieur je coince encore...
      0
  8. ccm81 Messages postés 11033 Statut Membre 2 434
     
    Pour un entier aléatoire h de a à b compris (a < b)
    h = a + Int((b - a + 1) * Rnd)

    Cdlmnt
    0
    1. Izy3834 Messages postés 8 Statut Membre
       
      Bonjour,

      je suis vraiment désolée de vous solliciter encore mais je bloque sur cette borne et c'est tout ce qui me sépare de mes résultats!

      Par exemple si je veux une somme totale de 10000, une borne inférieure de 50, et une borne supérieure de 1000.

      Je mets constmaxi = 10000
      a=1000\n
      b=1000 (en ayant mis plus haut b As long)

      puis je remplace k = Int(a * Rnd) + 1 par
      k=a+Int((b-a+1)*Rnd) dans le code mais malheureusement la borne inférieure n'est pas prise en compte, auriez-vous une idée?

      merci beaucoup de votre aide
      0
  9. ccm81 Messages postés 11033 Statut Membre 2 434
     
    Ta valeur de b (maxi pour le tirage) me semble bien grande, il faut la choisir nettement inférieure au total à obtenir
    Un exemple
    https://www.cjoint.com/?3AsoMGA6CSj

    Attention lien modifié

    Cdlmnt
    0
  10. ccm81 Messages postés 11033 Statut Membre 2 434
     
    Pour des valeurs un peu grandes (total=10000), il te faut prendre la dernière solution (tout en mémoire), sinon ça va se trainer un peu. Sans compter qu'il manque un test ici pour éviter le dépassement du maxi
    If tot < total Then
    d = total - tot
    For k = 1 To d
    a = 1 + Int(n * Rnd)
    If Range(plage).Cells(a, 1) < maxi Then
    Range(plage).Cells(a, 1) = Range(plage).Cells(a, 1) + 1
    Else
    k = k - 1
    End If
    Next

    Bonne fin de journée
    0