Fonction Alea()

Bonjour

Je voudrais refaire une fonction de type ALEA() qui venait  d'un pack de  macro complémentaire nommée  " NB_1.XLA "la fonction s'appelait " Alea_SR ".malheureusement avec excel 2021 cela ne fonctionne plus C'est une macro fonction qui fonctionne  en plage ,tout en revoyant des nombres aleatoire sans doublons Si quelqu'un peut se pencher sur mon problème , j'en serais heureux 

Merci d'avance.

je ne sais pas comment envoyer mon classeur d'exemple?

21 réponses

Résumé de la discussion

Excel 2021 ne fait plus fonctionner l’UDF Alea_SR issue du pack NB_1.XLA, censée générer une grille de tirages aléatoires sans doublons sur une plage. Deux solutions majeures ont été discutées : une approche Power Query qui actualise les tirages non répétitifs en fonction d’un nombre de tirages défini, et une proposition VBA d’une fonction Alea_SR(l, c) retournant une matrice 2D d’éléments uniques via un dictionnaire. Des difficultés apparaissent toutefois, notamment le blocage de l’actualisation dans certains classeurs et le besoin de recalcul en série, ce qui limite l’usage immédiat. Enfin, plusieurs intervenants cherchent encore une solution opérationnelle et échangent des essais (exemples de zones à sélectionner, apprentissage des modes de calcul, demandes d’exemples de classeur), sans qu’un consensus clair n’émerge.

Bobot (l’IA à votre service)
  1. Bonjour

    Ca ne va pas , parce que le renvoi de la formule doit se faire sur plusieurs cellules et

    sans doublons

    Merci

    0
    1. Re,

      Ca ne va pas , parce que le renvoi de la formule doit se faire sur plusieurs cellules
      
      

      merci de joindre un fichier 

      Slts

      0
      1. Bonjour,

        Une fonction ne peut pas remplir une plage de cellules, mais seulement la cellule dans laquelle elle se trouve, (à l'exception des fonctions à propagation). Donne un exemple d'utilisation de cette fonction.

        Daniel


        0
        1. Essaie :

          Function Alea_SR(l As Long, c As Long)
            Dim Tabl(), I As Long, J As Long, Var As Double
            Set dico = CreateObject("scripting.dictionary")
            Randomize
            ReDim Tabl(1 To l, 1 To c)
            For I = 1 To UBound(Tabl, 1)
              For J = 1 To UBound(Tabl, 2)
                Var = Rnd
                Do While dico.exists(Var)
                  Var = Rnd
                  dico.Add Var, Var
                Loop
                Tabl(I, J) = Rnd
              Next J
            Next I
            Alea_SR1 = Tabl
          End Function

          Les paramètres à passer sont le nombre de lignes et de colonnes :

          Daniel


          0
          1. Oups, erreur. Voici le code corrigé :

            Function Alea_SR(l As Long, c As Long)
              Dim Tabl(), I As Long, J As Long, Var As Double, Dico As Object
              Set Dico = CreateObject("scripting.dictionary")
              Application.Volatile
              Randomize
              ReDim Tabl(1 To l, 1 To c)
              For I = 1 To UBound(Tabl, 1)
                For J = 1 To UBound(Tabl, 2)
                  Var = Rnd
                  Do While Dico.exists(Var)
                    Var = Rnd
                    Dico.Add Var, Var
                  Loop
                  Tabl(I, J) = Var
                Next J
              Next I
              Alea_SR = Tabl
            End Function

            Daniel


            0
            1. Bonjour

              Je te remercie pour ce travail,mais ce n'est pas exactement ce que j'attend.

              Exemple ,j'ai une plage A1:A7 avec des chiffres différents (1,3,5,6,7,9,4)

              et en C1:C5, je sélectionne la plage,et je valide la formule en faisant Ctrl/Maj/Entrée.

              et la formule me renvoie 5 chiffres pris dans la 1ère plage , et me renvoie 5 chiffres différents pris dans la  2 ème plage.

              Svp. comment faire pour envoyer 1 classeur d'exemple.

              0
              1. Bonjour,

                La macro que je t'ai fournie répond exactement à ce que tu as demandé. Essaie d'être précis quand tu formules tes questions.

                "et me renvoie 5 chiffres différents pris dans la  2 ème plage."

                Quelle deuxième plage ? C1:C5 ? Il y a des nombres en C1:C5 ? Je n'y comprends rien !

                Daniel

                0
              2. "Svp. comment faire pour envoyer 1 classeur d'exemple."

                Pour le partager, clique sur :
                https://www.cjoint.com/
                Clique sur le bouton "parcourir". Choisis le fichier à partager. Dans le bas de la page, clique sur le bouton "Créer le lien cjoint". Copie le lien affiché et colle-le dans ta réponse.

                0
            2. Bonjour

              Je vous envoi le lien

              https://www.cjoint.com/c/OBsjmiViV1A

              0
              1. Je ne sais pas le faire. Pour reprendre ton exemple, j'ai besoin d'indiquer la plage source et la plage cible. eg.

                Alea_SR(A1:A7;C1:C5)

                Dis-moi si tu es d 'accord.

                Daniel


                0
                1. Bonjour

                  Non pas la plage cible ! ni la plage source ,la plage source je la sélectionne dans la fonction et la plage cible je la sélectionne quand j'utilise la fonction en validant avec Ctrl/maj/entrée

                  Merci

                  0
                  1. Alors, je ne sais pas faire.

                    Daniel

                    0
                2. Bonjour

                  un proposition avec une colonne intermédiaire

                  col E

                  =ALEA.ENTRE.BORNES(1;9)+(LIGNE()*0,0001)

                  col F

                  =INDIRECT("A"&RANG(E1;E$1:E$5;1))
                  0
                  1. Bonjour,

                    Un essai utilisant Power Query, nativement installé dans ta version 2021.

                    Tu peux mettre ce que tu veux dans la colonne A (autant de lignes que tu veux, et les valeurs que tu veux - chiffres, questions, noms...)

                    Dans la cellule C2, tu indiques le nombre de retours que tu veux (évite juste de mettre plus de tirages que de lignes de la colonne A)

                    Et en colonne E, le résultat

                    Pour effectuer un tirage, ruban "Données", "Actualiser tout"

                    Bonne apm

                    https://www.cjoint.com/c/OBsl1LG8pTF


                    0
                    1. Bonjour

                      Le classeur que vous m'avez fait reste figé ,quand je veux faire "Actualiser tout" ,je ne peux pas car c'est grisé.

                      et en +  j'avais besoin de pouvoir faire des recalcul en série .

                      Merci quand même

                      0
                      1. Re-,

                        A l'ouverture, tu valides bien les 2 messages?

                        Notamment celui-ci :


                        0
                        1. On pourrait mettre simplement un bouton sui appellerait une macro si la plage de résultats a toujours la même cellule de départ.

                          Sub test()
                            Dim C As Range, Var As Integer, Dico As Object
                            Set Dico = CreateObject("Scripting.Dictionary")
                            Randomize
                            With Application
                              .Volatile
                              For Each C In Selection
                                Var = .RandBetween([A1].Row, Cells(Rows.Count, 1).End(xlUp).Row)
                                Var = .Index([A:A], Var)
                                Do While Dico.exists(Var)
                                  Var = .RandBetween([A1].Value, [A9].Value)
                                Loop
                                Dico.Add Var, Var
                                C = Var
                              Next C
                            End With
                          End Sub
                          

                          https://www.cjoint.com/c/OBsqBsTqCs4

                          Daniel


                          0
                          1. Bonsoir

                            la macro fonctionne ,ce qui est très bien ,mais ne serait il pas possible de faire la même chose sous forme de fonction.

                            Merci

                            0
                            1. Perso, je ne sais pas faire.

                              Daniel

                              0
                          2. Bonjour à tous,

                            La nuit porte conseil... Il y a peut-être une possibilité.

                            @ nihcoc :

                            1. Quelle est ta version d'Excel ?

                            2. Essaie la fonction suivante. Ce n'est pas ce que tu attends mais c'est pour voir si je peux faire ce à quoi je pense.

                            Function Alea_SR(l As Long, c As Long)
                              Dim Tabl(), I As Long, J As Long, Var As Double, Dico As Object
                              Set Dico = CreateObject("scripting.dictionary")
                              Application.Volatile
                              Randomize
                              ReDim Tabl(1 To l, 1 To c)
                              For I = 1 To UBound(Tabl, 1)
                                For J = 1 To UBound(Tabl, 2)
                                  Var = Rnd
                                  Do While Dico.exists(Var)
                                    Var = Rnd
                                    Dico.Add Var, Var
                                  Loop
                                  Tabl(I, J) = Var
                                Next J
                              Next I
                              Alea_SR = Tabl
                            End Function
                            

                            Teste en entrant :

                            =Alea_SR(4;5)

                            (sans validation matricielle)

                            Le résultat doit être une plage de cellules de 4 lignes sur 5 colonnes.

                            Daniel


                            0
                            1. bonjour

                              j'ai essayé ta fonction,elle marche ,mais ce n'est pas ce que je cherche exactement.

                              Par contre de mon coté, j'ai réussi a trouvé une fonction qui marche.

                              Merci

                              0
                              1. "mais ce n'est pas ce que je cherche exactement"

                                Ce n'était pas le but. Comme je te l'ai indiqué, il fallait savoir si ta version d'Excel supportait les fonctions à propagation.

                                Dans ce cas, merci de partager ta solution, ça peut servir à tous.

                                Daniel

                                0
                            2. Une solution :

                              Function Alea_SR()
                                Dim Tabl(), Dico As Object, Source As Range, l As Integer, c As Integer
                                Set Dico = CreateObject("scripting.dictionary")
                                Application.Volatile
                                Randomize
                                Set Source = [A1:A9]
                                l = Selection.Rows.Count
                                c = Selection.Columns.Count
                                ReDim Tabl(1 To l, 1 To c)
                                For I = 1 To UBound(Tabl, 1)
                                  For J = 1 To UBound(Tabl, 2)
                                    Var = Application.RandBetween(Source.Row, Source.Row + Source.Rows.Count - 1)
                                    Var = Application.Index(Source, Var)
                                    Do While Dico.exists(Var)
                                      Var = Application.RandBetween(Source.Row, Source.Row + Source.Rows.Count - 1)
                                      Var = Application.Index(Source, Var)
                                    Loop
                                    Tabl(I, J) = Var
                                    Dico.Add Var, Var
                                  Next J
                                Next I
                                Alea_SR = Tabl
                              End Function
                              

                              La fonction utilise la plage A1:A9 comme source de nombres. Au besoin, je peux modifier pour accepter une plage variable.

                              Daniel



                              0
                              1. Bonjour

                                tout d'abord j'utilise excel 2021.

                                j'ai essayé la macro en plage, la macro marche mais dès que je fais un recalcul les chiffres sont identiques.

                                merci

                                voila la macro que j'ai récupéré :

                                Public Function Alea_SR(oussa As Variant) As Variant
                                Application.Volatile
                                Dim Rep, Koi, Tmp, FL, Liste As Variant
                                Dim Large, Haut, Tout, TT, I, J, X, K, Lar, Hau, vol, ligne As Long
                                Dim Tablo As Boolean

                                ki = Application.Caller.Address
                                Haut = Range(ki).Rows.Count
                                Large = Range(ki).Columns.Count
                                Tout = Haut * Large

                                Select Case VarType(oussa)
                                 Case 8204
                                     Koi = oussa
                                     Hau = UBound(Koi, 1): Lar = UBound(Koi, 2)
                                     N = Hau * Lar
                                     Tablo = True
                                     ReDim Liste(1 To N)
                                     For I = 1 To Lar
                                         For J = 1 To Hau
                                             Liste((I - 1) * Hau + J) = Koi(J, I)
                                         Next J
                                     Next I
                                     
                                 Case 2 To 6, 14, 17
                                     N = oussa
                                     If Int(N) <> N Or N < 2 Then
                                         Rep = CVErr(xlErrValue): GoTo FIN
                                     End If
                                      Tablo = False
                                 Case Else
                                     Rep = CVErr(xlErrValue): GoTo FIN
                                 End Select
                                 
                                 If Tout > N Then
                                     TT = N
                                 Else
                                     TT = Tout
                                 End If
                                 
                                 ReDim Rep(0 To Haut - 1, 0 To Large - 1)
                                 ReDim FL(0 To N - 1) As Boolean
                                     
                                 For I = 0 To N - 1
                                     FL(I) = True
                                 Next I
                                     
                                 For I = 0 To Tout - 1
                                     col = Int(I / Haut)
                                     ligne = I - col * Haut
                                     If I < TT Then
                                         ReDim Tmp(0 To N - I)
                                         K = 0
                                         For J = 0 To N - 1
                                             If FL(J) Then
                                                 K = K + 1
                                                 Tmp(K) = J + 1
                                             End If
                                         Next J
                                         
                                         X = Int(1 + (N - I) * Rnd())
                                         FL(Tmp(X) - 1) = False
                                         If Tablo Then
                                             Rep(ligne, col) = Liste(Tmp(X))
                                         Else
                                             Rep(ligne, col) = Tmp(X)
                                         End If
                                     Else
                                         Rep(ligne, col) = Chr(164)
                                     End If
                                 Next I
                                 
                                FIN:
                                 Alea_SR = Rep
                                       
                                 End Function
                                 

                                0
                                • 1
                                • 2