recopier des cellules un nombre de fois indiqué dans une autre cellule

fredi63

XLDnaute Nouveau
Bonjour,

Je souhaite recopier et empiler les cellules d'une colonne un certain nombre de fois, indiqué dans une autre colonne.

J'ai deux colonnes A et B.
A contient les intitulés, et B le nombre de répétitions pour chaque intitulé. Je souhaite répéter chaque cellule de A le nombre de fois indiqué dans B, par exemple dans une autre colonne de la même feuille.

Ex:
Col A Col B
Article x 2
Article y 3
Article z 5
etc.

Je souhaiterais créer une colonne (par ex. colonne C ou D, peu importe) avec ces données répétées et empilées:
Article x
Article x
Article y
Article y
Article y
Article z
Article z
Article z
Article z
Article z
etc.

Merci de votre aide, je n'ai pas trouvé la réponse dans le forum!
 

job75

XLDnaute Barbatruc
Bonjour fredi63, Pierre, le forum,

Avec des tableaux VBA c'est nettement plus rapide :
Code:
Sub recopie()
t = Range("A1:B" & Range("A" & Rows.Count).End(xlUp).Row)
ReDim rest(1 To Application.Sum([B:B]), 1 To 1)
For n = 1 To UBound(t)
   x = t(n, 1)
   For m = 1 To t(n, 2)
     ligne = ligne + 1
     rest(ligne, 1) = x
   Next
Next
[C1].Resize(ligne) = rest
End Sub
Fichier joint avec mesure des durées d'exécution.

A+
 

Pièces jointes

  • fredy(1).xlsm
    190.6 KB · Affichages: 29

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonsoir fredi63, pierrejean, job75,
(...) Avec des tableaux VBA c'est nettement plus rapide (...)
C'est ce que je pensais aussi. Mais il semble que ce ne soit pas systématique.
J'ai utilisé une macro (variante de pierrejean) sans tableau avec de multiples écritures sur la feuille. La différence avec pierrejean est que j'écris les résultats par bloc pour chaque article.
VB:
Sub copie_mapomme()
   t0 = Timer
   Range("d:d").ClearContents
   Application.ScreenUpdating = False
   Set xrg = Range("d1")
   Set Source = Range(Range("A1"), Cells(Rows.Count, "a").End(xlUp))
   For Each xcell In Source
      n = xcell.Offset(, 1)
      xrg.Resize(n) = xcell
      Set xrg = xrg.Offset(n)
   Next
   Range("j4") = Format(Timer - t0, "0.000\ sec.")
End Sub

Fichier joint avec les durées mesurées pour chacune des trois macros.

Edit: En fait cela dépend des données à traiter. Si on remplit la colonne B avec la seule valeur 3, alors la méthode de job75 est plus rapide. Si on fait la même chose avec la valeur 20, c'est la macro de ma pomme qui est plus rapide. Le basculement s'effectue autour de la valeur 8 ou 9.
Je l'avais déjà remarqué : suivant le profil des données à traiter, une macro ou une autre peut se révéler plus efficace.
 

Pièces jointes

  • fredy- ventiler- v1.xlsm
    83.7 KB · Affichages: 28
Dernière édition:

job75

XLDnaute Barbatruc
Re, bonjour mapomme,

Je continue avec les tableaux VBA.

Si le code est suffisamment rapide on peut le mettre dans une Worksheet_Change :
Code:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim t, limite&, rest(), n&, x, m, lig&
Application.EnableEvents = False
If Me.FilterMode Then Me.ShowAllData 'si la feuille est filtrée
t = Range("A1:B" & Range("A" & Rows.Count).End(xlUp).Row)
limite = Rows.Count - 1
ReDim rest(1 To limite, 1 To 1)
For n = 2 To UBound(t)
  x = t(n, 1)
  For m = 1 To Val(CStr(t(n, 2)))
    lig = lig + 1
    rest(lig, 1) = x
    If lig = limite Then MsgBox "Limite de la feuille !", 48: GoTo 1
Next m, n
1 If lig Then [D2].Resize(lig) = rest
If lig < limite Then Range("D" & lig + 2 & ":D" & Rows.Count) = ""
With Me.UsedRange: End With 'actualise si nécessaire la barre de défilement verticale
Application.EnableEvents = True
End Sub
Les valeurs en colonne B peuvent être quelconques.

Fichier joint.

A+
 

Pièces jointes

  • Recopie(1).xlsm
    183.7 KB · Affichages: 31
Dernière édition:

fredi63

XLDnaute Nouveau
Waouh, un grand merci à tous, n'en jetez plus la cour est pleine ! ;-))

C'est exactement ce qu'il me faut, merci beaucoup pour votre aide et toutes les variantes très pédagogiques, je me coucherai moins bête ce soir grâce à vous, respect!
 

Discussions similaires