XL 2021 Tentatives de modifier aléatoirement l'ordre dans une colonne de cellules, le nombre de cellules concernées pouvant varier.

  • Initiateur de la discussion Initiateur de la discussion MATLEA
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

MATLEA

XLDnaute Occasionnel
Bonjour chers experts,

J'ai une question concernant l'élimination des cellules vides dans une colonne de données après application d'une formule de randomisation mais avec un nombre d'entrées pouvant varier. Voir fichier essai joint.

Merci encore pour vos conseils et solutions
 

Pièces jointes

Solution
Bonjour.
Ne pouvez vous Mettre sous forme de tableau vos listes afin qu'elle aient exactement le nombre de lignes renseignées ?
Sinon, ceci a l'air de marcher, en G3, propagé sur 15 lignes :
Code:
=Hasard(LIGNE()-2;DECALER($F$3;0;0;NBVAL($F$3:$F$17);1);Tutu)
Bonjour.
Ne pouvez vous Mettre sous forme de tableau vos listes afin qu'elle aient exactement le nombre de lignes renseignées ?
Sinon, ceci a l'air de marcher, en G3, propagé sur 15 lignes :
Code:
=Hasard(LIGNE()-2;DECALER($F$3;0;0;NBVAL($F$3:$F$17);1);Tutu)
 
Dernière édition:
Bonjour Matlea, Dranreb,
Ou peut être en modifiant Lmax dans Hasard avec :
VB:
   If TypeOf Donné Is Range Then
      Dim T, i%: T = Donné
      For i = 1 To UBound(T)
          If T(i, 1) = "" Then Exit For
      Next i
      Set RngDon = Donné: LMax = i - 1
ou plus simple à priori :
VB:
If TypeOf Donné Is Range Then
      Set RngDon = Donné: LMax = Application.CountIf(Donné, "><")
 
Dernière édition:
Bonjour.
Ne pouvez vous Mettre sous forme de tableau vos listes afin qu'elle aient exactement le nombre de lignes renseignées ?
Sinon, ceci a l'air de marcher, en G3, propagé sur 15 lignes :
Code:
=Hasard(LIGNE()-2;DECALER($F$3;0;0;NBVAL($F$3:$F$17);1);Tutu)
Merci Dranreb,

Ca a en effet l'air de marcher avec la formule proposée.
Merci aussi Sylvanu mais n'étant pas un expert je ne sais pas comment utiliser vos infos;
Bonne soirée
 
Merci aussi Sylvanu mais n'étant pas un expert je ne sais pas comment utiliser vos infos;
Je n'ai fait que modifié votre propre macro. Dans "Function Hasard" ligne 15 vous avez :
VB:
If TypeOf Donné Is Range Then
   Set RngDon = Donné: LMax = RngDon.Rows.Count
Je l'ai remplacé par :
Code:
If TypeOf Donné Is Range Then
   Set RngDon = Donné: LMax = Application.CountIf(Donné, "><")
En d'autres termes j'ai remplacé :
Code:
 LMax = RngDon.Rows.Count
 par
LMax = Application.CountIf(Donné, "><")
 

Pièces jointes

@sylvanu, j'ai reconnu cette fonction perso comme étant de moi, non de @MATLEA.
Je ne suis pas trop favorable à une modification de cette partie du code parce qu'elle est exécutée à chaque invocation.
Ce qui est exécuté plus rarement est derrière If Now - HDernUti > 1 / 86400 Or LMax <> L Or Graine <> GrnPréc Then
De toutes façon elle a été conçue pour une utilisation optimale en formule à références structurées d'un tableau Excel, donc une plage ayant fait l'objet de la commande "Mettre sous forme de tableau" du groupe Styles du menu Accueil.
 
Bonsoir Dranreb,
Je ne comprends pas trop votre argumentation.
Quelle différence faites vous entre :
VB:
DECALER($F$3;0;0;NBVAL($F$3:$F$17);1)
et
LMax = Application.CountIf(Donné, "><")
Dans les deux cas les expressions seront évaluées à chaque invocation que ce soit en formules ou en VBA, donc au niveau temporel cela ne devrait pas trop changer.
 
Oui, mais je n'ai pas dit que le bricolage de la formule pour que ça passe était la meilleure solution. J'ai commencer par suggérer de mettre la plage sous forme de tableau.
Si j'avais voulu qu'elle puisse être utilisée normalement sur des plages classiques non forcément entièrement renseignées je l'aurais peut être plutôt écrite comme ça :
VB:
Option Explicit
Private HDernUti As Date, TN°() As Long, GrnPréc As Double
Public Function Hasard(ByVal Rang As Long, ByVal Donné, Optional ByVal Graine As Double) As Variant
Rem. ——— Renvoie dans une cellule une information choisie aléatoirement d'une plage.
'  Arguments :
'     Rang:   Rang dans la permutation du numéro souhaité.
'     Donné:  Deux possibilités :
'        1) — Une expression du numéro le plus élevé, la fonction en renvoyant un de 1 à Donné.
'        2) — Une plage d'une colonne contenant les valeurs possibles, la fonction renvoyant l'une d'elles.
'     Graine: Base de départ de la série. Si omis l'ordre des numéros sera différent à chaque évaluation.
'  Principe important: Cette fonction étant conçue pour une validation normale, non matricielle,
'     elle construit un tableau sur lequel elle se base, ensuite, à chaque invocation,
'     tant qu'il est récent de moins d'une seconde depuis sa dernière utilisation.
   Dim RngDon As Range, LMax As Long, L As Long, P As Long
   If TypeOf Donné Is Range Then
      Set RngDon = Donné: LMax = RngDon.Rows.Count
   ElseIf IsNumeric(Donné) Then
      LMax = Donné
   Else: Hasard = CVErr(xlErrValue): Exit Function: End If
   On Error Resume Next: L = UBound(TN°): On Error GoTo 0
   If Now - HDernUti > 1 / 86400 Or LMax <> L Or Graine <> GrnPréc Then
Rem. Ajout :
      LMax = RngDon(1, 1).End(xlDown).Row - RngDon.Row + 1
'
      ReDim TN°(1 To LMax): TN°(1) = 1
      If Graine <= 0 Then Randomize Else Rnd -1: Randomize Graine
      For L = 2 To LMax: P = Int(Rnd * L) + 1: If P < L Then TN°(L) = TN°(P)
         TN°(P) = L: Next L
      GrnPréc = Graine: End If
   On Error Resume Next: L = TN°(Rang) ': On Error GoTo 0
   If Err Then
      Hasard = IIf(RngDon Is Nothing, 0, "")
   ElseIf RngDon Is Nothing Then: Hasard = L
   Else: Hasard = RngDon(L, 1).Value: End If
   HDernUti = Now
   End Function
 
Dernière édition:
Non, là on n'étudie le cas que quand il faut recalculer toute la séquence des rangs aléatoires dans TN°
Remarque: en l'était ça ne marche pas si la fonction est paramétrée pour renvoyer uniquement ces numéros et que RngDon est donc Nothing.
 
Bonjour et merci Dranreb et Sylvanu,
J'ai pris connaissance de vos argumentaires et suis bien incapable de donner un quelconque avis. J'étais parti sur l'utilisation de la formule proposée par Dranreb du type =Hasard(LIGNE()-2;DECALER($F$3;0;0;NBVAL($F$3:$F$17);1);Tutu).
En toute fin que me conseilleriez vous, cette formule ou une modification de la macro et alors quelle modification?

Merci et bonne journée
 
Je créé donc un vrai tableau excel. Dans la 1ère cellule de la colonne 1 j'entre la référence de la 1ère cellule de la colonne dont je veux modifier l'ordre puis je tire vers le bas. Dans la seconde colonne j'entre la formule de hasard, par exemple =Hasard(LIGNE()-3;$A$4:$A$67;Tutu) et je tire vers le bas jusqu'à 67. J'espère que la référence structurée est prise en compte. Ai-je oublié quelque chose?
Merci
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Réponses
11
Affichages
898
Retour