Jim Dettman
jimdettman at earthlink.net
Tue Jul 15 11:35:52 CDT 2003
Sorry I missed this thread. I've got a couple of sample MDB's for nested tree logic. Two are pure SQL solutions, one from Joe and the other from a fellow expert on Expert's Exchange. Then I have one from a VBA standpoint, which is my own logic that I've used for the past 20 years. I've paste the code below if anyone is interested. If anyone wants copies, let me know off-list. Note that I'm on vacation next week. Jim Dettman jimdettman at earthlink.net Public Function ExplodeBOM(strPartID As String, dblQuantity As Double) As Integer Dim dbCur As Database Dim rstParts As Recordset Dim rstBOM As Recordset Dim rstExploded As Recordset Dim lngDisplayOrder As Long Dim intCurLevel As Integer Dim strParts(255) As String Dim lngCurLine(255) As Long Dim dblQPA(255) As Double Dim dblQtyRequired As Double Dim dblHoldQPA As Double Dim intJ As Integer Set dbCur = CurrentDb() Set rstParts = dbCur.OpenRecordset("tblPartMaster", dbOpenTable) rstParts.Index = "PrimaryKey" Set rstBOM = dbCur.OpenRecordset("tblBOM", dbOpenTable) rstBOM.Index = "PrimaryKey" Set rstExploded = dbCur.OpenRecordset("tblBOMExploded") ExplodeBOM = False ' First clear BOM explosion table. On Error GoTo ExplodeBOM_ErrDelete dbCur.Execute "DELETE * FROM tblBOMExploded", dbFailOnError On Error GoTo 0 ' Find part in part master rstParts.Seek "=", strPartID If rstParts.NoMatch Then MsgBox "Part: " & strPartID & " cannot be found. " GoTo ExplodeBOM_Leave End If ' Find top level assembly, first line rstBOM.Seek "=", strPartID, 1 If rstBOM.NoMatch Then MsgBox "Part: " & strPartID & " is not an assembly. " GoTo ExplodeBOM_Leave End If ' Initialize for top level intCurLevel = 1 Erase strParts() Erase lngCurLine() Erase dblQPA() lngDisplayOrder = 0 strParts(intCurLevel) = strPartID lngCurLine(intCurLevel) = 0 dblQPA(intCurLevel) = dblQuantity ' Level loop ' Get next line from BOM. ExplodeBOM_GetNextLine: lngCurLine(intCurLevel) = lngCurLine(intCurLevel) + 1 rstBOM.Seek "=", strParts(intCurLevel), lngCurLine(intCurLevel) If rstBOM.NoMatch Then ' Go up one level If intCurLevel = 1 Then ExplodeBOM = True GoTo ExplodeBOM_Leave Else intCurLevel = intCurLevel - 1 GoTo ExplodeBOM_GetNextLine End If Else ' Have another line. Is there a BOM for it? GoSub ExplodeBOM_WriteLine dblHoldQPA = rstBOM![QPA] rstBOM.Seek "=", rstBOM![PartID], 1 If rstBOM.NoMatch Then ' Raw material or purchased componet GoTo ExplodeBOM_GetNextLine Else ' Have another assembly. Drop a Level intCurLevel = intCurLevel + 1 If intCurLevel > 20 Then MsgBox "Explosion greater then 20 levels - Circular reference" GoTo ExplodeBOM_Leave Else strParts(intCurLevel) = rstBOM![AssemblyID] lngCurLine(intCurLevel) = 0 dblQPA(intCurLevel) = dblHoldQPA GoTo ExplodeBOM_GetNextLine End If End If End If ExplodeBOM_Leave: If Not rstExploded Is Nothing Then rstExploded.Close Set rstExploded = Nothing End If If Not rstParts Is Nothing Then rstParts.Close Set rstParts = Nothing End If If Not rstBOM Is Nothing Then rstBOM.Close Set rstBOM = Nothing End If If Not dbCur Is Nothing Then Set dbCur = Nothing End If Exit Function ExplodeBOM_CalQTYReq: dblQtyRequired = 1 For intJ = 1 To intCurLevel: dblQtyRequired = dblQtyRequired * dblQPA(intJ): Next intJ dblQtyRequired = dblQtyRequired * rstBOM![QPA] Return ExplodeBOM_WriteLine: GoSub ExplodeBOM_CalQTYReq lngDisplayOrder = lngDisplayOrder + 1 rstExploded.AddNew rstExploded![DisplayOrder] = lngDisplayOrder rstExploded![Level] = intCurLevel rstExploded![Sequence] = lngCurLine(intCurLevel) rstExploded![PartID] = rstBOM![PartID] rstExploded![QtyRequired] = dblQtyRequired rstExploded.Update Return ExplodeBOM_ErrDelete: MsgBox "Could not clear BOM Exploded table" Resume ExplodeBOM_Leave End Function -----Original Message----- From: accessd-bounces at databaseadvisors.com [mailto:accessd-bounces at databaseadvisors.com]On Behalf Of Gustav Brock Sent: Tuesday, July 15, 2003 10:45 AM To: Access Developers discussion and problem solving Subject: Re: [AccessD] Tree shaped reports: Joe Celco BOM Hi Bruce <<snip>>