Tri spécifique sur deuxième feuille avec macro/formule ou Power Q
Bonjour a tous!
J'aimerais pouvoir trier mes emplacements sur ma feuille ABCD différemment, afin d'obtenir exactement ce qui est sur ma feuille résultat. Les couleurs sont juste la pour mettre en évidence l'attendu. Ex ici pour l'allée A, bay 01. A noter que parfois, certaines bay n'iront pas jusqu'au niveau 60 et pourront avoir que 2 ou 3 positions (A,B ou A,B,C)
Merci pour votre support!
Bonjour,
Alors juste parce que je l'ai écrite, une solution "via formule", mais honnetement je déconseille car votre Excel va rester bloquer pendant quelques secondes (10-20 ?). Mais ça fonctionne si vous le laissez finir le calcul [EDIT : voir dernier message ici] :
=LET( _baseTbl; LET(t; EXCLURE(ABCD!A:.E; 1); TRIERPAR(t; PRENDRE(t; ; 1))); _letters; UNIQUE(DROITE(CHOISIRCOLS(_baseTbl; 1))); _colsM; MAX(MAP(_letters; LAMBDA(l; SOMME(1 * (DROITE(CHOISIRCOLS(_baseTbl; 1)) = l))))); _res; MAKEARRAY( LIGNES(_letters); _colsM; LAMBDA(r; c; INDEX(FILTRE(CHOISIRCOLS(_baseTbl; 1); DROITE(CHOISIRCOLS(_baseTbl; 1)) = INDEX(_letters; r)); c) ) ); SIERREUR(_res; ""))
Il y a peut-être une optimisation à faire sur le filtre. Mais PQ me semble plus adapté vu le volume de données (> 1500 colonnes !).
Hello,
Une proposition PQ, quasi instantanée, me semble que ça donne le bon résultat, si tu peux me confirmer. Quoique, j'ai trié dans un sens différent mais au vu de la proposition de saboh je ne suis plus trop sûr ^^
= Table.Sort(Source,{
{"allée", Order.Ascending},
{"bay", Order.Ascending},
each List.PositionOf({"A","B","C","D"},Text.End([emplacement],1)),
each Text.End([emplacement],3)
})@+
Ah j'ai probablement mal compris. J'ai lu "je veux exactement ce résultat" et j'ai cherché à le retrouver… mais c'est vrai que ce n'est pas très exploitable. Le tri que tu proposes est sans doute celui voulu
PS : Une petite révision de la formule en gardant en mémoire le filtre et les paramètres réutilisés (=> grande réduction du temps de calcul).
=LET(
λTHUNK; LAMBDA(x; LAMBDA(x));
_baseTbl; LET(t; EXCLURE(ABCD!A:.E; 1); TRIERPAR(t; PRENDRE(t; ; 1)));
_col1; CHOISIRCOLS(_baseTbl; 1);
_rCol1; DROITE(_col1);
_letters; UNIQUE(_rCol1);
_colsM; MAX(MAP(_letters; LAMBDA(l; SOMME(1 * (_rCol1 = l)))));
_thunks; MAP(_letters; LAMBDA(l; λTHUNK(FILTRE(_col1; _rCol1 = l))));
_res; MAKEARRAY(LIGNES(_letters); _colsM; LAMBDA(r; c; INDEX(INDEX(_thunks; r; 1)(); c)));
SIERREUR(_res; "")
)Hello,
Une autre proposition en fonction de la compréhension, cette fois j'empile toutes les lignes. @saboh, il y a ça aussi comme interprétation je pense
@+
Et enfin,
La version au même format que saboh avec prise en compte des valeurs null si il y en a
Normalement dans mes trois propositions tu devrais trouver ton bonheur
@+
Bonjour Baroute78,
La dernière proposition en PQ est absolument parfaite!! Merci!!
@saboh--> la formule fonctionne mais le résultat est affiché sur les 4 premières lignes en allant de gauche a droite jusque la colonne BET !
est possible d'avoir exactement le meme resultat que le PQ de baroute? Soit 1193 lignes
Ah donc la bonne proposition c'est celle où j'empile les différents tableaux
Merci pour ton retour
@saboh--> la formule fonctionne mais le résultat est affiché sur les 4 premières lignes en allant de gauche a droite jusque la colonne BET !
est possible d'avoir exactement le meme resultat que le PQ de baroute? Soit 1193 lignes
Merci pour votre retour, oui effectivement dans la formule vu qu'on regroupe par la lettre finale de la colonne emplacement (A,B,C ou D), on a >1500 colonnes.
Vous parlez du tableau de @Baroute en G:M ? Ca doit être possible via formule mais si PQ fonctionne… avec autant de données la formule risque d'être (bien) plus lente.
Bonjour à tous
A l'ancienne, une version vba avec ce que j'en ai compris... Cliquer sur le bouton Hop!
Le code est dans Module1. Il est un peu commenté.
Sub Reorganiser()
Dim derlig&, plage As Range, tinit, t, dercol&, i&, ref$, refcurr$, ncol&, necrit&
ReDim ligne(1 To 1, 1 To Columns.Count)
Worksheets("RESULTAT").Select
Worksheets("RESULTAT").Range("a1").CurrentRegion.Offset(1).Clear ' effacement des précédent résultats
Application.ScreenUpdating = False ' bloquer actualisation de l'affichage
With Worksheets("ABCD")
If .FilterMode Then .ShowAllData ' si filtre, afficher tout
derlig = .Cells(Rows.Count, "a").End(xlUp).Row ' dernière ligne des données
If derlig = 1 Then Exit Sub ' si que les titres, on quitte
Set plage = .Range("a1").Resize(derlig, 5) ' la plage des données sources
tinit = plage ' le tableau des valeurs sources initiales
.Sort.SortFields.Clear ' tri selon l'allée, la baie, la position, le niveau
.Sort.SortFields.Add2 Key:=plage.Columns(2), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Sort.SortFields.Add2 Key:=plage.Columns(3), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortTextAsNumbers
.Sort.SortFields.Add2 Key:=plage.Columns(5), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Sort.SortFields.Add2 Key:=plage.Columns(4), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortTextAsNumbers
With .Sort
.SetRange plage: .Header = xlYes: .MatchCase = False: .Orientation = xlTopToBottom: .SortMethod = xlPinYin
.Apply
End With ' FIN du tri
t = plage.Resize(plage.Rows.Count + 1) ' le tableau des valeurs triées (+ 1 ligne vide pour la boucle suivante)
plage = tinit: Erase tinit ' on réaffiche les données sources (avant le tri)
End With
With Worksheets("RESULTAT")
i = 2 ' la première des données est la ligne 2 (on saute la ligne des en-têtes)
ref = Join(Array(t(i, 2), t(i, 3), t(i, 5)), ";") ' ref est la référence qu'on traite
ncol = 1: necrit = 1 ' ncol est le nombre de colonnes déjà remplies de la ligne (pour la référence ref)
ligne(1, ncol) = t(i, 1) ' le premier élément de la ligne est mis dans le tableau ligne
For i = 3 To UBound(t) ' boucle de lecture de la donnée source suivante
refcurr = Join(Array(t(i, 2), t(i, 3), t(i, 5)), ";") ' la référence de l'élément i
If refcurr = ref Then ' si la référence de l'élém. i est égal à ref
ncol = ncol + 1 ' on incrémente le nombre d'éléments du tableau ligne
ligne(1, ncol) = t(i, 1) ' on insère la référence de la localisation dans ligne
Else ' la référence de l'élem. i est différente de l'ancienne
necrit = necrit + 1 ' on incrémente la ligne d'écriture du résultat
.Cells(necrit, 1).Resize(, ncol) = ligne ' on écrit le résultat
' on change la référence qu'on traite, on remet le nombre d'éléments de ligne à 1 et
' on insère le premier élément correspondant à la nouvelle référence
ref = refcurr: ncol = 1: ligne(1, ncol) = t(i, 1)
End If
Next i
Application.Goto .[a1], True ' on va à la cellule A1
End With
End SubMerci Mafraise c’est très bien aussi avec le code !
@sabohà c’est noté si la formule n’est pas pratique
Merci a tous pour le support !!!
Pour finir, ci-joint la formule demandée. J'ai des petits soucis pour créer une formule unique (intersections implicites sur FRACTIONNER.TEXTE...) donc j'ai pris 3 colonnes d'aide dans la feuille RESULTAT (colonnes masquées A,B,C). Au final c'est rapide.
En reprenant le groupement proposé par mafraise (si j'ai bien compris chaque ligne correspond aux 5 premiers caractères de la colonne "A" de ABCD), je crois que je retrouve son résultat.