I'm trying to write some code for a spreadsheet to calculate if items within a Bill of Materials (BoM) are a child of a purchased assembly or not. I'll try and explain in more detail.
Basically my spreadsheet has many columns, but only 2 are needed to calculate from. For simplicity I'll just say these are Columns A & B and the output from the VBA is put in Column C.
Column A contains the BoM level - This always starts at Level 0 and children of this level are level 1, and children of level 1 are level 2 and so on. Currently from all the BoMs I have created, level 10 has been 'deepest' it goes, but it isn't impossible that this could increase.
Column B contains the Assembly status - The only value I'm interested in this column is "P" for purchased.
Due to the various headings in my spreadsheet the data starts at Row 12 and as this is the Top Level I can always mark this as "TL" in Column C.
Now the bit I am struggling with. For each row from 13 onwards (this could easily extend to 100,000 rows and beyond!) I need to look at Column A (BoM level) and then look upwards to find the level below until I either find a level that is purchased ("P" in Column B) or reach BoM level 0.
Hopefully this table will help
| Column A | Column B | Column c |
|---|---|---|
| 0 | IH | TL |
| 1 | IH | FALSE |
| 2 | FALSE | |
| 2 | FALSE | |
| 1 | P | FALSE |
| 2 | P | TRUE |
| 3 | TRUE | |
| 3 | TRUE |
Whilst thinking of how to automate this issue, I thought I could use a For loop with a nested Select Case followed by a nested For loop (with Step -1).
The first For loop start at the top and look down to the last row, at each row it looks at the BoM Level and based on the this value a Select Case is used to run a For loop (Step -1) to start looking back up the rows.
The problem I can see is I would need to have a Case for each possible BoM level (the maximum total levels possible is 99)
Extract of code so far (only going to Case 3):
Sub Purch_Child_Formula() 'ADD CHILD OF PURCHASED ASSY FORMULA
Dim AssyStatus As Double
Dim ChildPurchStatus As Double
Dim CurrentBomLevel As Integer
Dim X As Long
Last_Row = ActiveSheet.Range("A" & rows.Count).End(xlUp).Row
For ChildPurchStatus = 13 To Last_Row
CurrentBomLevel = Cells(ChildPurchStatus, 1).Value
Select Case CurrentBomLevel
Case 1
For X = ChildPurchStatus To 13 Step -1
If Cells(X - 1, 1).Value = CurrentBomLevel Then
Exit For
ElseIf Cells(X - 1, 1).Value = (CurrentBomLevel - 1) And Cells(X - 1, 2).Value = "P" Then
Cells(X, 3).Value = "TRUE"
Else
Cells(X, 3).Value = "FALSE"
End If
Next X
Case 2
For X = ChildPurchStatus To 13 Step -1
If Cells(X - 1, 1).Value = CurrentBomLevel Then
Exit For
ElseIf Cells(X - 1, 1).Value = (CurrentBomLevel - 1) And Cells(X - 1, 2).Value = "P" Then
Cells(X, 3).Value = "TRUE"
ElseIf Cells(X - 1, 1).Value = (CurrentBomLevel - 2) And Cells(X - 1, 2).Value = "P" Then
Cells(X, 3).Value = "TRUE"
Else
Cells(X, 3).Value = "FALSE"
End If
Next X
Case 3
For X = ChildPurchStatus To 13 Step -1
If Cells(X - 1, 1).Value = CurrentBomLevel Then
Exit For
ElseIf Cells(X - 1, 1).Value = (CurrentBomLevel - 1) And Cells(X - 1, 2).Value = "P" Then
Cells(X, 3).Value = "TRUE"
ElseIf Cells(X - 1, 1).Value = (CurrentBomLevel - 2) And Cells(X - 1, 2).Value = "P" Then
Cells(X, 3).Value = "TRUE"
ElseIf Cells(X - 1, 1).Value = (CurrentBomLevel - 3) And Cells(X - 1, 2).Value = "P" Then
Cells(X, 3).Value = "TRUE"
Else
Cells(X, 3).Value = "FALSE"
End If
Next X
Case 4
Case 5
Case 6
Case 7
Case 8
Case 9
Case 10
End Select
Next ChildPurchStatus
End Sub
This starts to work, but does go wrong before reaching a BoM Level of 4.
So now I'm thinking that perhaps I should use an initial for loop to down the rows, followed but another for loop looking back up the data, but this for loop should continue until it finds the criteria "P" in Column 2 - and we've arrived at an Until loop. Is this possible? (It may be evident that coding is not part of my normal job!)
Sorry for the very wordy post, but my scenario seems to unique as some searching online hasn't helped so far.
Hopefully there is enough information in this post. I will add any other details requested.


Dictionaryobject to store the status of upper BoM.