Différencier les niveaux des sous-niveaux dans une liste

9exemple.xlsx (8.67 Ko)

Bonjour à tous !

Je travaille sur une liste de produits à plusieurs niveaux, soit fabriqués soit achetés. Je souhaite connaître uniquement les niveaux de tête achetés.

Pour cela je dispose d'une colonne pré-renseignée qui m'indique si le produit, quel que soit le niveau, est acheté ou non.

Or, cette colonne ne différencie pas les niveaux achetés, exemple : si j'achète une "chemise", les sous-niveaux "bouton", "col", "manche" vont aussi être indiqués achetés.

Pour être plus parlant, j'attache un fichier exemple avec le résultat voulu en colonne D.

Ma liste de produits est profonde sur 9 niveaux et compte plusieurs milliers de lignes.

Existe-t-il une solution simple et efficiente (de préférence sans VBA) pour arriver à mes fins ?

Merci par avance pour toute aide !

Bonjour

A tester en D2 à étirer

=SI(B2="Fab";B2;SI(ET(A2>=A1;B1="Achat");"Achat nv sup";"Achat"))

Bonjour Chris,

Merci pour votre retour, malheureusement ne marche pas dans tous les cas de figure. En effet, il y a à mon avis un cas où il est sans doute nécessaire de regarder plus haut dans la liste, pas uniquement le niveau du dessus. Il faudrait conserver l'"héritage" du niveau de tête acheté et pouvoir l'appliquer sur tous ses sous-niveaux...mais je ne vois pas bien comment !

capture

Bonsoir 78chris, Griftr,

Vraiment pas très clair ton exemple parlant

Manuellement, je procéderais comme ceci.

J'insèrerais une colonne pour indexer les lignes pour rétablir leur position initiale à la fin du traitement qui va suivre.

J'insèrerais une ligne vide avant chaque occurrence "Fab" en colonne B pour délimiter chaque zone.

J'appliquerais un tri ascendant sur chaque zone en m"appuyant sur la colonne A.

A parti de là, on définirait les différents niveaux d,"achat de chaque zone en s'appuyant sur la formule de 78chris.

Une fois défini, processus inverse on supprimerait les lignes vides et on rétablirait la position initiale des lignes de ton tableau via la colonne index.

Voilà ma réponse aussi tarabiscotée que la problématique exposée.

Édit : fais le manuellement sur quelques zones et dis-nous si tu obtiens le résultat souhaité.

klin89

Bonjour Klin89, merci pour ta réponse et désolé pour l'exemple un peu obscur...

J'ai quand même essayé de rendre l'exemple plus parlant en le simplifiant et en prenant une image culinaire pour bien saisir la liste de constituants, qui peuvent être achetés à différents niveaux. J'espère que cela peut clarifier

J'ai gardé la formule de Chris pour montrer qu'il y a des cas où je n'obtiens pas le résultat escompté (en rouge).

Ta proposition ne résout pas le problème de la formule, qui ne se définit qu'en fonction de la ligne du dessus. En effet, pour définir une ligne on a besoin de connaitre la caractéristique du "père". Or, le "père" n'est pas toujours la ligne du dessus, et trier ne va pas aider.

Edit: sincèrement je ne sais pas si une résolution est possible sans code. Si ce n'est pas le cas, je suis preneur d'un bout de code...

capture
3exemple-2.xlsx (9.93 Ko)

Bonjour

J'avais testé une autre formule mais on avait toujours 2 écarts, ailleurs

Sauf si tu arrives à définir l’algorithme je ne pense pas que cela soit possible en l'état que ce soit par formule ou code...

Bonjour Chris

En termes d'algorithme je verrais bien la solution avec une boucle while.

Trouver le type d'appro du père : tant que le niveau de la ligne i-1 est supérieur ou égal à la la ligne i, on décrémente i, puis on renvoie le type d'appro de la ligne i

Trouver le type d'appro de la ligne : ça revient à ta formule de double test selon 3 cas :

Si type d'appro de la ligne

- Fab alors Fab

- Achat alors si type d'appro du père :

- Fab alors Achat

- Sinon Achat niveau sup

Re à tous,

As-tu essayé la méthode ColumnDifferences de l'objet Range ?

Tu peux ainsi parcourir toutes les plages de la colonne B contenant le mot "Achat" et comparer chaque cellule de la colonne A avec la valeur de la cellule se trouvant en 1ère position de chaque plage.

klin89

Merci Klin pour ta piste en VBA, je ne connais pas mais ça doit fonctionner.

Pour votre info j'ai trouvé la solution sans VBA. Je le mets en PJ.

Il s'agit de créer autant de colonnes que de sous niveaux et de recréer l'arbre généalogique de chaque ligne.

A partir de là un simple test sur chaine de caractères permet de faire la distinction.

Merci en tout cas pour votre aide, ça m'a bien aidé à structurer ma pensée !

capture
4exemple-2.xlsx (10.45 Ko)

Re Griftr,

Comme dit précédemment, avec la méthode ColumnDifferences.

Essaie ceci sur le premier fichier :

Option Explicit
Sub test()
Dim rng As Areas, r As Range, i As Long
With Sheets("Feuil1")
    With .Range("B2", .Cells(Rows.Count, 2).End(xlUp))
        Set rng = .ColumnDifferences(.Cells(1)).Areas
    End With
    For Each r In rng
        For i = 1 To r.Count
            If r(i).Offset(, -1) = r(1).Offset(, -1) Then
                r(i).Offset(, 1) = "Achat"
            Else
                r(i).Offset(, 1) = "Achat nv sup"
            End If
        Next
    Next
    On Error Resume Next
    With .Range("B2", .Cells(Rows.Count, 2).End(xlUp))
        .Offset(, 1).SpecialCells(4) = "Fab"
    End With
    On Error GoTo 0
End With
Set rng = Nothing
End Sub

klin89

Rechercher des sujets similaires à "differencier niveaux liste"