Re,
Tu compliquais un peu les choses, en voulant une base filtrée et réorganisée ! Ça va réduire l'écart en taille de code avec la solution que proposera ThauTheme...
Pour faciliter les manipulations, 4 plages nommées :
- BaseCode : la 1re colonne (Code) de la base, en-tête de champ incluse, en dynamique
- LstCode : un filtrage avancé sans doublon de la plage précédente en Z1 (colonne masquée), nommée en dynamique à partir de Z2 (inclut une cellule vide, voir ci-dessous), destinée à alimentée liste déroulante placée en C2
- Crit : c'est la zone de critères pour le filtrage, en C1:C2, C2 sous liste déroulante ; c'est le choix dans la liste qui déclenchera le filtrage ; en cas de choix de la position "vide" (ou effacement de C2), le filtrage n'aura pas lieu, mais le filtrage antérieur sera effacé
- BaseFilt : la 1re colonne de la zone de résultats du filtrage (feuille 2), en-tête incluse, en dynamique ; lors de l'effacement, on n'efface pas l'en-tête, de cette façon la plage existe toujours et ne déclenchera pas d'erreur si on l'effaçait par exemple deux fois de suite.
Le dispositif est simple : évènementielle au changement de sélection dans la liste déroulante en C2 ;
on procède au filtrage avancé : résultat (temporaire sur la feuille 2 en AA9:AM9 ;
on mesure l'extension par la dernière cellule occupée en AA, ligne qui en retranchant 9 donne le nombre de ligne de données filtrées (variable n) ;
compte tenu du découpage des résultats, on transfère les valeurs de la 11e col. filtrée en 1re col. résultats, les 6e à 10e col. filtrées en 2e à 6e col. résultats, les 12e et 13e col. filtrées en 7e et 8e col. résultats, en trois fois donc ;
on efface le filtrage (temporaire, Clear pour effacer toutes traces du filtrage) ;
on affiche la feuille.
Petite particularité : on accède à la feuille 2 à partir de la plage nommée (propriété Worksheet), d'où indépendance par rapport au nom de feuille. L'évènementielle étant liée à la feuille 1, son nom n'est également pas utilisé...
Si un changement intervient dans la colonne Code de la base, la même évènementielle intervient mais là se contente de filtrer la liste alimentant la liste déroulante.
Le code :
Private Sub Worksheet_Change(ByVal Target As Range)
Dim n%
If Target.Address = "$C$2" Then
[BaseFilt].Offset(1).Resize(, 8).ClearContents
If Target <> "" Then
[BaseCode].Resize(, 13).AdvancedFilter xlFilterCopy, [Crit], _
[BaseFilt].Worksheet.Range("AA9:AM9"), False
With [BaseFilt]
n = .Worksheet.Range("AA" & Rows.Count).End(xlUp).Row - 9
.Cells(2, 1).Resize(n).Value = .Worksheet.Range("AK10").Resize(n).Value
.Cells(2, 2).Resize(n, 5).Value = .Worksheet.Range("AF10").Resize(n, 5).Value
.Cells(2, 7).Resize(n, 2).Value = .Worksheet.Range("AL10").Resize(n, 2).Value
.Worksheet.Range("AA9").Resize(n + 1, 13).Clear
.Worksheet.Activate
End With
End If
ElseIf Not Intersect(Target, [BaseCode]) Is Nothing Then
[BaseCode].AdvancedFilter xlFilterCopy, , Me.Range("Z1"), True
End If
End Sub
Cordialement.