Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

Petite question VBA

  • Initiateur de la discussion Initiateur de la discussion JJ1
  • 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 !

J

JJ1

Guest
(Re)Bonjour,

Je voudrais inscrire en C1 un nombre parmi L1:Q1:
(code de Pierre-Jean)

tablo = Range("L1:Q1")
Randomize
Set Dico = CreateObject("Scripting.dictionary")
While Dico.Count < 1
xx = Int((UBound(tablo, 2) * Rnd) + 1)
X = tablo(1, xx)
Dico(X) = X
Wend
Range("C1").Resize(, 1) = Dico.keys

Est-il utile de faire Dictionary ou existe-t-il plus simple?
merci.
 
Re : Petite question VBA

Bonsour®
au vu de l'exemple
les nombres de 1 à 70 peuvent être présent dans chaque tableau

le tirage isole un nombre par tranche (sans doublon ni en nombre ni en tranche)
7 tranches=7 nombres
il ne suffit alors que de choisir n(3, puis 2, puis 7) nombres parmi ceux sortis
 
Re : Petite question VBA

Bonsoir JJ1, Modeste geedee,

JJ1 puisque tu t'es cassé la tête à mettre des formules dans la feuille autant s'en servir :

Code:
Sub Tirage()
Dim n As Long
Randomize
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Do
If n = 10000 Then MsgBox "Pas de résultat !": Exit Do 'sécurité
n = n + 1
[V3] = [A5:T5].Cells(Int(20 * Rnd) + 1)
[W3] = [A5:T5].Cells(Int(20 * Rnd) + 1)
[X3] = [A5:T5].Cells(Int(20 * Rnd) + 1)
[Y3] = [A6:T6].Cells(Int(20 * Rnd) + 1)
[Z3] = [A6:T6].Cells(Int(20 * Rnd) + 1)
[AA3] = [A6:T6].Cells(Int(20 * Rnd) + 1)
[AB3] = [A7:T7].Cells(Int(20 * Rnd) + 1)
[AC3] = [A7:T7].Cells(Int(20 * Rnd) + 1)
Calculate
Loop While [AF1] = 0 Or [AG1] > 8
Application.Calculation = xlCalculationAutomatic
[V3].ClearComments
[V3].AddComment n & " itérations"
[V3].Comment.Shape.TextFrame.AutoSize = True
End Sub
Edit : 10000 itérations en 25 secondes sur Win7 - Excel 2010.

Normalement il en faut quelques dizaines.

Fichier joint.

A+
 

Pièces jointes

Dernière édition:
Re : Petite question VBA

Bonjour JJ1, le forum,

Si l'on ne veut pas se servir des formules de la feuille :

Code:
Sub Tirage()
Dim a, n As Long, d1 As Object, d2 As Object, i As Byte, P As Range, x#
Randomize
a = Array("A5:T5", "A5:T5", "A5:T5", "A6:T6", "A6:T6", "A6:T6", "A7:T7", "A7:T7")
Do
  If n = 10000 Then MsgBox "Pas de résultat !": Exit Do 'sécurité
  n = n + 1
  Set d1 = CreateObject("Scripting.dictionary")
  Set d2 = CreateObject("Scripting.dictionary")
  For i = 0 To UBound(a)
    Set P = Range(a(i))
    x = P(Int(P.Count * Rnd) + 1)
    d1(x) = ""
    d2(Application.Min(Int(x / 10), 6)) = ""
  Next
Loop While d1.Count < 8 Or d2.Count < 7
[V3:AC3] = d1.keys
[V3].ClearComments
[V3].AddComment n & " itérations"
[V3].Comment.Shape.TextFrame.AutoSize = True
End Sub
10000 itérations prennent maintenant 11 secondes, la macro est donc 3 fois plus rapide.

Fichier (3).

A+
 

Pièces jointes

Re : Petite question VBA

Re,

Amusant, avec un seul objet Dictionary et le tableau VBA b cette macro est plus rapide :

Code:
Sub Tirage()
Dim a, ub As Byte, n As Long, d As Object, b(6) As Byte, i As Byte, P As Range, x#
Randomize
a = Array("A5:T5", "A5:T5", "A5:T5", "A6:T6", "A6:T6", "A6:T6", "A7:T7", "A7:T7")
ub = UBound(a)
Do
  If n = 10000 Then MsgBox "Pas de résultat !": Exit Do 'sécurité
  n = n + 1
  Set d = CreateObject("Scripting.Dictionary")
  Erase b 'RAZ
  For i = 0 To ub
    Set P = Range(a(i))
    x = P(Int(P.Count * Rnd) + 1)
    d(x) = ""
    b(Application.Min(Int(x / 10), 6)) = 1
  Next
Loop While d.Count <= ub Or Application.Sum(b) < 7
[V3:AC3] = d.keys
[V3].ClearComments
[V3].AddComment n & " itérations"
[V3].Comment.Shape.TextFrame.AutoSize = True
End Sub
10000 itérations en 7,5 secondes...

Fichier (4).

A+
 

Pièces jointes

Re : Petite question VBA

Re,

En fait ce qui prend du temps c'est la création des objets Dictionary.

Dans la boucle il faut seulement les vider avec RemoveAll :

Code:
Sub Tirage()
Dim a, ub As Byte, n As Long, d1 As Object, d2 As Object, i As Byte, P As Range, x#
Randomize
a = Array("A5:T5", "A5:T5", "A5:T5", "A6:T6", "A6:T6", "A6:T6", "A7:T7", "A7:T7")
ub = UBound(a)
Set d1 = CreateObject("Scripting.Dictionary")
Set d2 = CreateObject("Scripting.Dictionary")
Do
  If n = 10000 Then MsgBox "Pas de résultat !": Exit Do 'sécurité
  n = n + 1
  d1.RemoveAll: d2.RemoveAll 'RAZ
  For i = 0 To ub
    Set P = Range(a(i))
    x = P(Int(P.Count * Rnd) + 1)
    d1(x) = ""
    d2(IIf(x < 70, Int(x / 10), 6)) = ""
  Next
Loop While d1.Count <= ub Or d2.Count < 7
[V3:AC3] = d1.keys
[V3].ClearComments
[V3].AddComment n & " itérations"
[V3].Comment.Shape.TextFrame.AutoSize = True
End Sub
10000 itérations en 1,98 secondes.

Remarque : en utilisant le tableau b du post #19 à la place de d2 la durée reste la même.

Fichier (5).

A+
 

Pièces jointes

Dernière édition:
Re : Petite question VBA

Re,

Ben non, ce n'était pas fini :

Code:
Sub Tirage()
Dim t, ncol%, a, ub As Byte, n As Long, d1 As Object, d2 As Object
Dim i As Byte, x#
Randomize
t = [A5:T7] 'matrice, bien plus rapide
ncol = UBound(t, 2)
a = Array(1, 1, 1, 2, 2, 2, 3, 3) 'lignes
ub = UBound(a)
Set d1 = CreateObject("Scripting.Dictionary")
Set d2 = CreateObject("Scripting.Dictionary")
Do
  If n = 10000 Then MsgBox "Pas de résultat !": Exit Do 'sécurité
  n = n + 1
  d1.RemoveAll: d2.RemoveAll 'RAZ
  For i = 0 To ub
    x = t(a(i), Int(ncol * Rnd) + 1)
    d1(x) = ""
    d2(IIf(x < 60, Int(x / 10), 6)) = ""
  Next
Loop While d1.Count <= ub Or d2.Count < 7
[V3:AC3] = d1.keys
[V3].ClearComments
[V3].AddComment n & " itérations"
[V3].Comment.Shape.TextFrame.AutoSize = True
End Sub
10000 itérations en 0,33 seconde 😉

Fichier (6).

A+
 

Pièces jointes

Dernière édition:
- 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
Assurez vous de marquer un message comme solution pour une meilleure transparence.

Discussions similaires

Réponses
3
Affichages
918
Réponses
12
Affichages
750
A
  • Question Question
Réponses
3
Affichages
595
R
  • Question Question
Réponses
2
Affichages
986
Rousseau Benoit
R
  • Suggestion Suggestion
Recherche & référence DicoCountOrder
Réponses
0
Affichages
2 K
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…