Nomenclature indentée de fabrication sous VBA
Bonsoir.
Je sollicite votre aide car j'ai passé mon week-end à trouver la solution mais en vain.
De plus je suis débutant en VBA.
Je cherche à faire une macro qui met en forme la nomenclature identée de fabrication de plusieurs articles. (http://www.logistiqueconseil.org/Fiches/Gestion-des-stocks/Nomenclature-et-classification.pdf, page 2)
Par exemple pour faire l'article A, il faut (en niveau 1) 2 article B et 3 article C. Pour faire un article B, il faut (en niveau 2) 36,5 article D etc....
Pour cela , j'ai un élément de départ qui est une extraction de départ dans la feuille "Import_SYMBAD_nomenclature".
Malheureusement tout les liens entre article père et fils sont mélangés.
Mon but est à partir de l'extraction, arriver au résultat dans la feuille "Résultat Cible".
J'ai fais une macro dans le module Nomenclature_NOK, et j'arrive au résultat incomplet dans la feuille inter.
Je ne vois pas comment avoir la nomenclature en entier malgré mes multiples tentatives.
SI vous avez des questions sur la lecture de la nomenclature n'hésitez surtout pas.
Bon fin de week-end.
Merci
bonsoir,
une proposition de macros, dis-moi si le résultat te convient.
Dim lignea, wsi As Object, wsa As Object, dli
Sub structure()
' wsi feuille import
Set wsi = Worksheets("Import_SYMBAD_nomenclature")
Worksheets.Add after:=Worksheets(Worksheets.Count)
' wsa feuille résultat (arbre)
Set wsa = Worksheets(Worksheets.Count)
' dli numéro de la dernière ligne dans wsi
dli = wsi.Range("c" & Rows.Count).End(xlUp).Row
'lignea numéro de ligne dans l'arbre
lignea = 0
' produire l'arbre en commençant à la ligne 2 de wsi
Call lirearbre(2)
End Sub
Sub lirearbre(l) ' procédure recursive
niveau = wsi.Cells(l, 1)
article = wsi.Cells(l, 3)
While article = wsi.Cells(l, 3) ' on lit tous les éléments ayant le même père
If niveau = 1 Then ' on affiche le titre si le niveau est 1 et qu'il n'est pas déjà affiché pour cet article
If Not articleaffiché Then
lignea = lignea + 1
wsa.Cells(lignea, 1) = String(80, "-")
lignea = lignea + 1
wsa.Cells(lignea, 1) = "Article"
wsa.Cells(lignea, 2) = wsi.Cells(l, 3)
lignea = lignea + 2
wsa.Cells(lignea, 1) = String(80, "-")
lignea = lignea + 1
wsa.Cells(lignea, 2) = "Article" & vbCrLf & "d'exp."
wsa.Cells(lignea, 3) = "Nombre"
articleaffiché = True
lignea = lignea + 1
wsa.Cells(lignea, 1) = String(80, "-")
End If
End If
' on imprime la ligne de détail pour ce niveau
lignea = lignea + 1
wsa.Cells(lignea, 1) = String(niveau, "_") & niveau ' niveau
wsa.Cells(lignea, 2) = wsi.Cells(l, 4) & "" ' le fils
wsa.Cells(lignea, 2).NumberFormat = "0" 'le format pour le fils
wsa.Cells(lignea, 3) = wsi.Cells(l, "L") ' le nombre (?)
' on recher si le fils a des sous-composants
Set re = wsi.Range("C" & l + 1 & ":C" & dli).Find(wsi.Cells(l, 4), lookat:=xlWhole)
If Not re Is Nothing Then
' si c'est le cas, on produit l'arbre à partir de la ligne fils
Call lirearbre(re.Row)
End If
l = l + 1 ' on prend la ligne suivante
If l > dli Then Exit Sub
If niveau = 1 Then ' un traitement special si le niveau est 1
If article <> wsi.Cells(l, 3) Then ' c'est un niveau 1 mais un article différent
article = wsi.Cells(l, 3)
articleaffiché = False
End If
While wsi.Cells(l, 1) <> 1 ' on recherche la ligne suivante de niveau 1
l = l + 1
If l > dli Then Exit Sub
article = wsi.Cells(l, 3)
articleaffiché = False
Wend
End If
Wend
End SubBonjour h2so4.
Merci, je viens de voir ta réponse.
Je vais lire attentivement ta proposition et voir si ça correspond à ce que je veux.
J'ai aussi fais ma cuisine interne en parallèle mais j'arrive pas au but.
Je te confirme d'ici à ce soir.
h2so4, ta solution s'approche de ce que je veux mais je pense que ton algorithme n'est pas complet
et avec ma "cuisine interne" j'ai le même problème: un article fils peut avoir plusieurs pères
Prenons le résultat pour un article
******************Début résultat********************************
Article 338-001-906-0
--------------------------------------------------------------------------------
"Article
d'exp." Nombre
--------------------------------------------------------------------------------
_1 338-001-906-0S2 0
__2 338-001-906-0F2 1
__2 338-002-006-8 1
___3 338-002-006-8S1 0
___3 338-002-006-8S2 0
____4 338-002-006-9 1
_____5 975221521511 323
_____5 975221521511 323
____4 338-002-006-9 1
____4 975221521511 323
___3 338-002-006-8S9 0
___3 338-002-006-8S1 0
___3 338-002-006-8S2 0
____4 338-002-006-9 1
_____5 975221521511 323
_____5 975221521511 323
____4 338-002-006-9 1
____4 975221521511 323
___3 338-002-006-8S9 0
__2 338-002-703-0 1
__2 HL48-8-2 18
_1 338-001-906-0S3 0
__2 338-002-006-8 1
___3 338-002-006-8S1 0
___3 338-002-006-8S2 0
____4 338-002-006-9 1
_____5 975221521511 323
_____5 975221521511 323
____4 338-002-006-9 1
____4 975221521511 323
___3 338-002-006-8S9 0
___3 338-002-006-8S1 0
___3 338-002-006-8S2 0
____4 338-002-006-9 1
_____5 975221521511 323
_____5 975221521511 323
____4 338-002-006-9 1
____4 975221521511 323
___3 338-002-006-8S9 0
__2 338-002-703-0 1
__2 HL48-8-2 18
_1 338-001-906-0S4 0
__2 338-001-906-0F4 1
__2 338-002-006-8 1
___3 338-002-006-8S1 0
___3 338-002-006-8S2 0
____4 338-002-006-9 1
_____5 975221521511 323
_____5 975221521511 323
____4 338-002-006-9 1
____4 975221521511 323
___3 338-002-006-8S9 0
___3 338-002-006-8S1 0
___3 338-002-006-8S2 0
____4 338-002-006-9 1
_____5 975221521511 323
_____5 975221521511 323
____4 338-002-006-9 1
____4 975221521511 323
___3 338-002-006-8S9 0
__2 338-002-703-0 1
__2 HL48-8-2 18
******************Fin résultat
Sur certaines lignes le même niveau apparaît plusieurs fois. Ex: le père 338-002-006-9 (8ème ligne en partant de la fin) fait appel
deux fois à l'article 975221521511.
Et l'article 338-002-006-8 (au début) fait appel deux fois à l'article 338-002-006-9.
Donc il y a encore des modif à faire.
bonsoir,
une version adaptée, j'ai compris une erreur dans la gestion des niveaux.
Dim lignea, wsi As Object, wsa As Object, dli
Sub structure()
' wsi feuille import
Set wsi = Worksheets("Import_SYMBAD_nomenclature")
Worksheets.Add after:=Worksheets(Worksheets.Count)
' wsa feuille résultat (arbre)
Set wsa = Worksheets(Worksheets.Count)
' dli numéro de la dernière lignes dans wsi
dli = wsi.Range("c" & Rows.Count).End(xlUp).Row
'lignea numéro de ligne dans l'arbre
lignea = 0
' produire l'arbre en commençant à la ligne 2 de wsi
Call lirearbre(2)
End Sub
Sub lirearbre(l) ' procédure recursive
niveau = wsi.Cells(l, 1)
article = wsi.Cells(l, 3)
While article = wsi.Cells(l, 3) And niveau = wsi.Cells(l, 1) ' on lit tous les éléments ayant le même père
If niveau = 1 Then ' on affiche le titre si le niveau est 1 et qu'il n'est pas déjà affiché pour cet article
If Not articleaffiché Then
lignea = lignea + 1
wsa.Cells(lignea, 1) = String(80, "-")
lignea = lignea + 1
wsa.Cells(lignea, 1) = "Article"
wsa.Cells(lignea, 2) = wsi.Cells(l, 3)
lignea = lignea + 2
wsa.Cells(lignea, 1) = String(80, "-")
lignea = lignea + 1
wsa.Cells(lignea, 2) = "Article" & vbCrLf & "d'exp."
wsa.Cells(lignea, 3) = "Nombre"
articleaffiché = True
lignea = lignea + 1
wsa.Cells(lignea, 1) = String(80, "-")
End If
End If
' on imprime la ligne de détail pour ce niveau
lignea = lignea + 1
wsa.Cells(lignea, 1) = String(niveau, "_") & niveau ' niveau
wsa.Cells(lignea, 2) = wsi.Cells(l, 4) & "" ' le fils
wsa.Cells(lignea, 2).NumberFormat = "0" 'le format pour le fils
wsa.Cells(lignea, 3) = wsi.Cells(l, "L") ' le nombre (?)
' on recher si le fils a des sous-composants
Set re = wsi.Range("C" & l + 1 & ":C" & dli).Find(wsi.Cells(l, 4), lookat:=xlWhole)
If Not re Is Nothing Then
' si c'est le cas, on produit l'arbre à partir de la ligne fils
'on vérifie si le niveau de la ligne trouvée est correct
j = re.Row
While niveau + 1 <> wsi.Cells(j, 1)
j = j + 1
If j > dli Then MsgBox "sous-composant " & wsi.Cells(l, 4) & " non trouvé au niveau " & niveau + 1: Stop
Wend
Call lirearbre(j)
End If
l = l + 1 ' on prend la ligne suivante
If l > dli Then Exit Sub
If niveau = 1 Then ' un traitement special si le niveau est 1
If article <> wsi.Cells(l, 3) Then ' c'est un niveau 1 mais un article différent
article = wsi.Cells(l, 3)
articleaffiché = False
End If
While wsi.Cells(l, 1) <> 1 ' on recherche la ligne suivante de niveau 1
l = l + 1
If l > dli Then Exit Sub
article = wsi.Cells(l, 3)
articleaffiché = False
Wend
End If
Wend
End Sub