XL 2016 boucles for imbriquées

meamandine

XLDnaute Nouveau
Bonsoir, je suis débutante en VBA et je cherche une solution pour écrire plusieurs boucles for imbriquées (360 variables ) et ayant le même début et fin pour avoir toutes les combinaisons possibles de ces variables .
est- ce- que quelqu'un aurait une solution svp?
 
Dernière édition:

eriiic

XLDnaute Barbatruc
Bonjour à tous,

comme les collègues je pense qu'il va te falloir de la patience pour 360 variables.
C'est long l'éternité, surtout vers la fin ;-)

Une proposition qui te génère les indices dans un tableau :
VB:
Sub test()
    cpt 4, 1, 5, 2 ' 4 compteurs de 1 à 5 au pas de 2
End Sub

Sub cpt(nbVar As Long, debut As Long, fin As Long, Optional pas As Long = 1)
    Dim cpt() As Long, i As Long
    ReDim cpt(1 To nbVar)
    'init
    For i = 1 To nbVar: cpt(i) = debut: Next i
    'génération
    Do
        'visualisation/utilisation
        [A2].Resize(, nbVar) = cpt
        'suivant
        cpt(nbVar) = cpt(nbVar) + pas
        For i = nbVar To 2 Step -1
            If cpt(i) > fin Then
                cpt(i) = debut
                cpt(i - 1) = cpt(i - 1) + pas
            Else
                Exit For
            End If
        Next i
    Loop Until cpt(1) > fin
End Sub

Je me suis basé sur "ayant le même début et fin" bien que ton code exemple utilise 6 variables différentes
eric
 

Dranreb

XLDnaute Barbatruc
Si vous ne me dites pas pourquoi vous croyez en avoir besoin …
Pour touver une combinaison en fonction de son numéro il suffit de prendre pour le nombre de droite le reste de la division de ce numéro diminué de 1 par le nombre de valeurs différentes à produire, et recommencer avec la partie entière du quotient obtenu pour le nombre à sa gauche, et ainsi de suite jusqu'à ce qu'il ne reste plus rien. Chaque nombre obtenu doit bien évidemment être multiplié par le pas, et, si ça ne commence pas à 0, augmenté de la première valeur.
Pourquoi diable ne voulez vous pas me dire pourquoi vous croyez devoir les lister ?
 
Dernière édition:

meamandine

XLDnaute Nouveau
j'ai pas compris ce que tu veux savoir, j'ai un projet à rendre où j'aurai besoin de ça !!!
est ce qu'il y a moyen de faire comme le dernier code que j'ai posté parce qu'il me permettra de remplir ligne par ligne et non pas colonne par colonne comme dans ta démarche
 

Dranreb

XLDnaute Barbatruc
Cette fonction perso renvoie un tableau comme résultat :
VB:
Function ListeCombi(ByVal Début As Double, ByVal Pas As Double, NbVal As Long) As Variant()
   Dim RngAC As Range, T(), L As Long, C As Long, N As Long, R As Long
   Set RngAC = Application.Caller
   ReDim T(1 To RngAC.Rows.Count, 1 To RngAC.Columns.Count)
   For L = 1 To UBound(T, 1)
      T(L, 1) = L
      N = L - 1
      For C = UBound(T, 2) To 2 Step -1
         R = N Mod NbVal
         T(L, C) = Début + Pas * R
         N = N \ NbVal: Next C, L
   ListeCombi = T
   End Function
Dans une plage de 1331 lignes et 4 colonnes, cette formule :
Code:
=ListeCombi(0;200000;11)
, validée par Ctrl+Maj+Entrée, renvoie votre tableau du poste #7
 

meamandine

XLDnaute Nouveau
merci pou ta réponse,
en fait pour le projet il consiste à calculer pour chaque combinaison un cout et u rendement pour choisir celles ayant le moindre coût
comment je fais pour avoir un tableau et le coller automatiquement dans la feuille excel au lieu de passer par la formule Ctrl+Maj+Entrée
 

Dranreb

XLDnaute Barbatruc
VB:
Sub Test()
   ListeCombi ActiveSheet.[B2].Resize(1331, 4), 0, 200000, 11
   End Sub
Sub ListeCombi(ByVal RngCible As Range, ByVal Début As Double, ByVal Pas As Double, NbVal As Long)
   Dim T(), L As Long, C As Long, N As Long, R As Long
   ReDim T(1 To RngCible.Rows.Count, 1 To RngCible.Columns.Count)
   For L = 1 To UBound(T, 1)
      T(L, 1) = L
      N = L - 1
      For C = UBound(T, 2) To 2 Step -1
         R = N Mod NbVal
         T(L, C) = Début + Pas * R
         N = N \ NbVal: Next C, L
   RngCible.Value = T
   End Sub
Mais plutôt que ce processus bestial, Il ne serait pas impossible que ça puisse se calculer avec le Solveur, voire une inversion de matrice !
 

eriiic

XLDnaute Barbatruc
Bonjour,

merci eric pour ta réponse j'ai essayée le code mais il affiche juste une ligne contenant
5 5 5 5
Oui, c'est qu'il a fini.
En regardant le code tu aurais pu voir que j'inscris toute les solutions au même endroit.
C'était juste un exemple pour te montrer l'endroit où tu dois insérer le traitement que tu veux appliquer à chacune.
J'imaginais plus que tu mettrais des calculs pour ne sortir que celles qui t'intéressent, mais si tu veux seulement inscrire chacune sur une ligne, tu modifies en conséquence.
eric
 

meamandine

XLDnaute Nouveau
@eriiiic donc je dois le modifier pour q'uil affiche chaque résultat dans une ligne c'est bien ça?
@Dranreb merci pour la solution elle marche bien, j'ai une autre question comment je peux integrer une contrainte sur chaque ligne de telle façon à avoir une somme < 2000000 pour réduire la taille du tableau parce que j'aurai à utiliser un grand nombre de colonnes, et lors de l'insertion de T dans la feuille passer à la feuille suivante si le nombre de ligne dépassent la feuille excel?
Merci
j'ai pu adapté le code à ma situation :
VB:
Sub Test()
If Range("C6").Value <> " " Then Rows("6:1048000").ClearContents

   ListeCombi 10
   End Sub
Sub ListeCombi(ByVal ncol As Double)
   Dim T(), L As Long, C As Long, N As Long, R As Long
   NbVal = (Worksheets("Feuil1").Range("B1").Value / Worksheets("Feuil1").Range("pas").Value) + 1
   nrow = NbVal ^ ncol
  
   ReDim T(1 To nrow, 1 To ncol)
   Pas = Worksheets("Feuil1").Range("pas").Value
   Début = 0
   For L = 1 To UBound(T, 1)
      T(L, 1) = L
      N = L - 1
      For C = UBound(T, 2) To 2 Step -1
         R = N Mod NbVal
         T(L, C) = Début + Pas * R
         N = N \ NbVal: Next C, L
   ActiveSheet.[C6].Resize(nrow, ncol).Value = T
   End Sub
 

meamandine

XLDnaute Nouveau
j'ai utilisé ce code pour supprimer les lignes ne vérifiant pas la condition mais il ne les supprime pas
VB:
Sub Test()
If Range("C6").Value <> " " Then Rows("6:1048000").ClearContents

   ListeCombi 5
   End Sub
Sub ListeCombi(ByVal ncol As Double)
   Dim T(), L As Long, C As Long, N As Long, R As Long
   NbVal = (Worksheets("Feuil1").Range("B1").Value / Worksheets("Feuil1").Range("pas").Value) + 1
   nrow = NbVal ^ (ncol - 1)
  
   ReDim T(1 To nrow, 1 To ncol)
   Pas = Worksheets("Feuil1").Range("pas").Value
   Début = 0
   For L = UBound(T, 1) To 1 Step -1
      T(L, 1) = L
      N = L - 1
      somme = 0
      For C = (UBound(T, 2) - 1) To 2 Step -1
         R = N Mod NbVal
         T(L, C) = Début + Pas * R
         somme = somme + T(L, C)
         N = N \ NbVal: Next C
         If somme <= Worksheets("Feuil1").Range("B1").Value Then
         T(L, ncol) = Worksheets("Feuil1").Range("B1").Value - somme
         Else: Rows(L).Delete
         End If
         Next L
 Debug.Print UBound(T, 1)
   End Sub
 

eriiic

XLDnaute Barbatruc
@eriiiic donc je dois le modifier pour q'uil affiche chaque résultat dans une ligne c'est bien ça?
oui si c'est ce que tu veux.
Le mieux c'est de faire tes calculs avant et d'ajouter ceux qui t'intéressent dans un tableau, qui sera plus rapide à écrire en une fois à la fin.
Mais tu peux continuer avec la proposition de Dranreb qui est du pareil au même.
eric
 

meamandine

XLDnaute Nouveau
Vu que j'aurai un nombre important de colonnes, je pense vaut mieux que je calcule chaque combinaison et en même temps appliquer la condition pour réduire la taille du tableau.
je sais pas si un tableau de vba peut supporter un nombre important de combinaisons (parce que j'aurai 360 colonnes )et si ce n'est pas le cas comment je peux procéder, je suis vraiment bloquée la dessus !!
Merci
 

Dranreb

XLDnaute Barbatruc
Il n'y a pas seulement une question de taille, mais aussi de temps !
360 colonnes c'est impossible. Même s'il n'y avait que deux valeurs possibles pour chacune, ça ferait encore 2,3485425827738332278894805967893e+108 combinaisons à analyser. À supposer qu'il faille 1 µs pour en calculer une, le tout prendrait une durée largement supérieure à l'âge de l'univers !
Alors qu'il serait peut être possible de calculer la solution optimale à partir d'un nombre d'exemples égal au nombre de colonnes. Ça dépend comment les scores à optimiser dépendent de ces valeurs …
 

Discussions similaires

Réponses
4
Affichages
181
Réponses
12
Affichages
328

Statistiques des forums

Discussions
312 467
Messages
2 088 680
Membres
103 918
dernier inscrit
comite des fets allonzier