Calculer le nmbre d'assemlblage possible
Bonjour,
Je sollicite votre support pour trouver une solution a mon probleme.
Je souhaiterai calculer le nombre d'assemblage possible pour les articles parent en tenant en compte la quantité nécessaire et le stock disponible des articles composants (childe).
l'objectif est pouvoir introduire la référence de l'article parent et d'avoir le nombre d'assemblage possible directement.
En pj vous trouverez un fichier avec les données stock et bill of material.
Merci infinement en avance pour vos réponse.
Kmab
Bonjour,
une proposition (introduire la ref de la pièce en B3)
bonjour,
voici les macros
1ere macro à ajouter dans un nouveau module
Option Explicit
Function nap(mat)
Dim wsb As Worksheet
Dim wss As Worksheet
Dim re As Range
Dim plageb As Range
Dim pile(1000, 2)
Dim dicts As Object
Dim dictp As Object
Dim dls&, dlb&, i&, npile&, maxpile&, m$, q&, mqp&, k&, cle, fa$, qp&
Set wsb = Sheets("bill of material")
Set wss = Sheets("stock")
dlb = wsb.Cells(Rows.Count, 1).End(xlUp).Row 'dernière ligne de wsb
Set plageb = wsb.Range("A1").Resize(dlb, 1) 'plage de ref de material
dls = wss.Cells(Rows.Count, 1).End(xlUp).Row 'dernière ligne du stock
Set dicts = CreateObject("scripting.dictionary") 'dictionnaire des pièces en stock cle=reference, item=quantité en stock
Set dictp = CreateObject("scripting.dictionary") 'dictionnaire des pièces raw pour ce produit cle=référence raw, item=quantité nécessaire
'chargement dictionnaire stock
For i = 2 To dls
dicts(wss.Cells(i, 1).Value) = wss.Cells(i, 3)
Next i
npile = 1 ' pointeur de reférence à traiter
maxpile = 0 ' nombre max de références traitées
pile(npile, 1) = mat '1 er élément à traiter est la référence du produit initial
pile(npile, 2) = 0
Do While npile > 0 'tant qu'il y a des références à traiter
m = pile(npile, 1) ' référence
q = pile(npile, 2) ' quantité nécessaire
If npile > maxpile Then maxpile = npile
npile = npile - 1 ' cet élément de la pile est traité
' recherche de la référence dans bill
Set re = plageb.Find(m, lookat:=xlWhole, LookIn:=xlValues)
If re Is Nothing Then 'référence non trouvée dans bill
If maxpile = 1 Then nap = "pièce " & m & " non trouvée": Exit Function 'si première référence
dictp(m) = dictp(m) + q 'sinon on ajoute la piece raw (et quantité) au dictionnaire des pièces nécessaires
Else
'sinon on traite toutes les lignes de bill avec cette référence
fa = re.Address
Do
npile = npile + 1 'on ajoute les composants à la pile
pile(npile, 1) = re.Offset(, 1) 'référence
pile(npile, 2) = re.Offset(, 2) 'quantité
Set re = plageb.FindNext(re)
Loop Until re.Address = fa
End If
DoEvents
Loop
'le dictionnaire des pièces raw nécessaires et leur quantité pour une pièce finale est constitué
'on vérifie combien de pièces finales on peut faire
mqp = 100000
k = 5
For Each cle In dictp.keys
k = k + 1
Cells(k, 1) = cle
Cells(k, 2) = dicts(cle)
Cells(k, 3) = dictp(cle)
qp = Int(dicts(cle) / dictp(cle))
Cells(k, 4) = qp
If qp < mqp Then mqp = qp
Cells(k, 5) = mqp
Next
nap = mqp
End Function2ème macro (événementielle) à ajouter dans le module de la feuille nbr assembly possible
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$B$3" Then
Rows("6:1000").Clear
Range("B4") = nap(Target.Value)
End If
End Sub
Bonjour,
la version précédente contient un bug. voici une correction
version avec gestion de pile
Option Explicit
Function nap(mat)
Dim wsb As Worksheet
Dim wss As Worksheet
Dim re As Range
Dim plageb As Range
Dim pile(1000, 2)
Dim dicts As Object
Dim dictp As Object
Dim dls&, dlb&, i&, npile&, maxpile&, m$, q&, mqp&, k&, cle, fa$, qp&
Set wsb = Sheets("bill of material")
Set wss = Sheets("stock")
dlb = wsb.Cells(Rows.Count, 1).End(xlUp).Row 'dernière ligne de wsb
Set plageb = wsb.Range("A1").Resize(dlb, 1) 'plage de ref de material
dls = wss.Cells(Rows.Count, 1).End(xlUp).Row 'dernière ligne du stock
Set dicts = CreateObject("scripting.dictionary") 'dictionnaire des pièces en stock cle=reference, item=quantité en stock
Set dictp = CreateObject("scripting.dictionary") 'dictionnaire des pièces raw pour ce produit cle=référence raw, item=quantité nécessaire
'chargement dictionnaire stock
For i = 2 To dls
dicts(wss.Cells(i, 1).Value) = wss.Cells(i, 3)
Next i
npile = 1 ' pointeur de reférence à traiter
maxpile = 0 ' nombre max de références traitées
pile(npile, 1) = mat '1 er élément à traiter est la référence du produit initial
pile(npile, 2) = 0
Do While npile > 0 'tant qu'il y a des références à traiter
m = pile(npile, 1) ' référence
q = pile(npile, 2) ' quantité nécessaire
If npile > maxpile Then maxpile = npile
npile = npile - 1 ' cet élément de la pile est traité
' recherche de la référence dans bill
Set re = plageb.Find(m, lookat:=xlWhole, LookIn:=xlValues)
If re Is Nothing Then 'référence non trouvée dans bill
If maxpile = 1 Then nap = "pièce " & m & " non trouvée": Exit Function 'si première référence
dictp(m) = dictp(m) + q 'sinon on ajoute la piece raw (et quantité) au dictionnaire des pièces nécessaires
Else
'sinon on traite toutes les lignes de bill avec cette référence
fa = re.Address
Do
npile = npile + 1 'on ajoute les composants à la pile
pile(npile, 1) = re.Offset(, 1) 'référence
pile(npile, 2) = re.Offset(, 2) * q 'quantité
Set re = plageb.FindNext(re)
Loop Until re.Address = fa
End If
DoEvents
Loop
'le dictionnaire des pièces raw nécessaires et leur quantité pour une pièce finale est constitué
'on vérifie combien de pièces finales on peut faire
mqp = 100000
k = 5
For Each cle In dictp.keys
k = k + 1
Cells(k, 1) = cle
Cells(k, 2) = dicts(cle)
Cells(k, 3) = dictp(cle)
qp = Int(dicts(cle) / dictp(cle))
Cells(k, 4) = qp
If qp < mqp Then mqp = qp
Cells(k, 5) = mqp
Next
nap = mqp
End Functionversion avec procédure récursive
Option Explicit
Dim dict_stock As Object
Dim dict_pieces As Object
Function nap(mat)
Dim wsb As Worksheet
Dim wss As Worksheet
Dim re As Range
Dim plageb As Range
Dim dls&, dlb&, i&, m$, q&, mqp&, k&, cle, fa$, qp&, niveau&
Set wsb = Sheets("bill of material")
Set wss = Sheets("stock")
dlb = wsb.Cells(Rows.Count, 1).End(xlUp).Row 'dernière ligne de wsb
Set plageb = wsb.Range("A1").Resize(dlb, 1) 'plage de ref de material
dls = wss.Cells(Rows.Count, 1).End(xlUp).Row 'dernière ligne du stock
Set dict_stock = CreateObject("scripting.dictionary") 'dictionnaire des pièces en stock cle=reference, item=quantité en stock
Set dict_pieces = CreateObject("scripting.dictionary") 'dictionnaire des pièces raw pour ce produit cle=référence raw, item=quantité nécessaire
' si la pièce demandée existe
If Not plageb.Find(mat, lookat:=xlWhole) Is Nothing Then
'chargement dictionnaire stock
For i = 2 To dls
dict_stock(wss.Cells(i, 1).Value) = wss.Cells(i, 3)
Next i
compterpiece mat, plageb, dict_pieces, dict_stock
'le dictionnaire des pièces raw nécessaires et leur quantité pour une pièce finale est constitué
'on vérifie combien de pièces finales on peut faire
mqp = 100000
k = 5
For Each cle In dict_pieces.keys
k = k + 1
Cells(k, 1) = cle
Cells(k, 2) = dict_stock(cle)
Cells(k, 3) = dict_pieces(cle)
qp = Int(dict_stock(cle) / dict_pieces(cle))
Cells(k, 4) = qp
If qp < mqp Then mqp = qp
Cells(k, 5) = mqp
Next
nap = mqp
Else
nap = "pièce non trouvée"
End If
End Function
Sub compterpiece(mat, plage As Range, dict_pieces As Object, dict_stock As Object, Optional facteur_multiplicatif = 1)
Dim piece As Range, composant$, nombrecomposant#
For Each piece In plage
If piece.Value = mat Then
composant = piece.Offset(, 1).Value
nombrecomposant = piece.Offset(, 2).Value
If Left(composant, 3) = "RAW" Then
dict_pieces(composant) = dict_pieces(composant) + facteur_multiplicatif * nombrecomposant
Else
compterpiece composant, plage, dict_pieces, dict_stock, facteur_multiplicatif * nombrecomposant
End If
End If
Next piece
End Submerci, de rien
Bonjour H2so4,
Un grand merci pour ton aide.
