Possible to group by structure and letter/number Parts List table with iLogic?

Possible to group by structure and letter/number Parts List table with iLogic?

claudio.ibarra
Advocate Advocate
1,143 Views
8 Replies
Message 1 of 9

Possible to group by structure and letter/number Parts List table with iLogic?

claudio.ibarra
Advocate
Advocate

I can mark parts as normal/inseparable/purchased/etc. in the document settings. Is it possible to take that information and use it to group/organize a parts list?

 

I'd like to push all purchased parts down to the bottom of the list, numbered numerically. I'd like everything else (i.e., anything not marked as purchased) first on the list, "numbered" with letters (bonus for skipping letters like I and O). Double extra bonus for a blank row in between.

 

Is that possible in iLogic? Hit a button or run a rule, and have the parts list separate itself by non-purchased/purchased, and then renumber itself alpha/numerically in order of their part number or description in their separate groups? 

 

I borrowed some code I found online that renumbers my Parts List with letters, but I don't know how to make it only apply to only items that are _not_ marked as Purchased in the BOM Structure.

 

Sub Main()
Dim drw As DrawingDocument
 drw = ThisApplication.ActiveDocument
Dim obom As BOM
Dim oview As BOMView
Dim orow As BOMRow
ass = ThisDrawing.ModelDocument
obom = ass.ComponentDefinition.BOM
obom.StructuredViewEnabled = False
obom.StructuredViewEnabled = True
drw.Update
Dim prtl As PartsList
 prtl = drw.ActiveSheet.PartsLists.Item(1)
 prtl.Sort("PART NUMBER", True, "DESCRIPTION", True)
Dim prow As PartsListRow
oview = obom.BOMViews.Item(2)
Dim arr() As String
ReDim arr(oview.BOMRows.Count)
For i = 1 To prtl.PartsListRows.Count
arr(i - 1)=  prtl.PartsListRows.Item(i).Item(1).Value
Next
Dim x As Integer
For i = 1 To oview.BOMRows.Count
                j = CLng(arr(i-1))
                orow = oview.BOMRows.Item(j)
      x= Floor((i) / 25)
      If x= 0 Then
      orow.ItemNumber = Get_Number(i)
      End If
      If x > 0 Then
      orow.ItemNumber = Get_Number(Floor((i) / 24)) & Get_Number((i)- 24* Floor(i/24))   
End If

Next
drw.Update
End Sub

Function Get_Number(Number) As String
 Select Case Number
    Case 1: Get_Number = "A"
    Case 2: Get_Number = "B"
    Case 3: Get_Number = "C"
    Case 4: Get_Number = "D"
    Case 5: Get_Number = "E"
    Case 6: Get_Number = "F"
    Case 7: Get_Number = "G"
    Case 8: Get_Number = "H"
    Case 9: Get_Number = "J"
    Case 10: Get_Number = "K"
    Case 11: Get_Number = "L"
    Case 12: Get_Number = "M"
    Case 13: Get_Number = "N"
    Case 14: Get_Number = "P"
    Case 15: Get_Number = "Q"
    Case 16: Get_Number = "R"
    Case 17: Get_Number = "S"
    Case 18: Get_Number = "T"
    Case 19: Get_Number = "U"
    Case 20: Get_Number = "V"
    Case 21: Get_Number = "W"
    Case 22: Get_Number = "X"
    Case 23: Get_Number = "Y"
    Case 24: Get_Number = "Z"
  End Select

End Function

 

0 Likes
Accepted solutions (1)
1,144 Views
8 Replies
Replies (8)
Message 2 of 9

JamieVJohnson2
Collaborator
Collaborator

I don't know how to make it only apply to only items that are _not_ marked as Purchased in the BOM Structure.

dim oBomRow as BOMRow = BomRows.Item(xxx)

if oBomRow.BomStructure = BOMStructureEnum.kPurchasedBOMStructure then

   'Do something for purchased parts

else

   'Do something for standard parts

end if

 

Personally I would change the Item field then just sort it when finished.  However, in our office we generate separate tables, with half the rows in each turned off.

Jamie Johnson : Owner / Sisu Lissom, LLC https://sisulissom.com/
0 Likes
Message 3 of 9

Anonymous
Not applicable

Claudio,

If I understand what you are looking to do, you want all the purchased components to be at the bottom. If so, you can try the code below. That should help or it will point you in the right direction. Hope that helps.

 

Dim oDrawDoc As DrawingDocument = ThisDoc.Document

Dim oPartList As PartsList
oPartsList = oDrawDoc.ActiveSheet.PartsLists.Item(1)

oPartsList.Sort("PART NUMBER", True)

Dim oItemCell As PartsListCell
Dim intNonPurchItemCounter As Integer = 1
Dim intPurchItemCounter As Integer = 1

For j = 1 To oPartsList.PartsListRows.Count
	Dim oPartsListRow As PartsListRow = oPartsList.PartsListRows.Item(j)
	oItemCell = oPartsListRow.Item("ITEM")
	'MessageBox.Show(oPartsListRow.Item("PART NUMBER").Value)
	Dim oDrawingBOMRow As DrawingBOMRow = oPartsListRow.ReferencedRows.Item(1)
	Dim oBOMRow As BOMRow = oDrawingBOMRow.BOMRow
	
	If Not oBOMRow Is Nothing Then
		Dim oCompDef As ComponentDefinition = oBOMRow.ComponentDefinitions.Item(1)	
		Dim oBomStructure As BOMStructureEnum = oCompDef.BOMStructure
		
		If oBomStructure = BOMStructureEnum.kPurchasedBOMStructure Then
			oItemCell.Value = "P" & intPurchItemCounter
			intPurchItemCounter += 1
		Else
			oItemCell.Value = intNonPurchItemCounter
			intNonPurchItemCounter += 1
		End If
	End If
Next
oPartsList.Sort("ITEM", True)
oPartsList.Renumber()

 

DanV

Message 4 of 9

claudio.ibarra
Advocate
Advocate

It might be easier to generate separate tables, and just hide/show based on filtering. 

 

In my experience, I can't get one to snap to the end of the other. Is that something you've accomplished?

 

Is it possible to have iLogic code only target to the non-purchased parts list table and have them "numbered" with letters?

 

Is there an advantage to changing the item number field and then sorting compared to sorting and then changing the item number? 

0 Likes
Message 5 of 9

JamieVJohnson2
Collaborator
Collaborator

Sorry for the long post, but here is EVERYTHING!!!, because I'm lazy!  Enjoy!

  Friend Sub UserRenumberPurchasedParts()
        Dim strPrefix As String = InputBox("Enter Item prefix:", "Renumber Purchased Parts", "P")
        GetInventorApplication()
        If invApp.ActiveDocument IsNot Nothing Then
            If TypeOf invApp.ActiveDocument Is Inventor.DrawingDocument Then
                Dim drawDoc As DrawingDocument = invApp.ActiveDocument
                Dim sheet As Sheet = drawDoc.ActiveSheet
                If sheet IsNot Nothing Then
                    Dim plPurchasedParts As PartsList = Nothing
                    For Each item As Object In drawDoc.SelectSet
                        If TypeOf item Is Inventor.PartsList Then
                            plPurchasedParts = item
                            Exit For
                        End If
                    Next
                    If plPurchasedParts Is Nothing Then
                        For Each pl As PartsList In sheet.PartsLists
                            If pl.Style.Name = "Purchased Parts" Then
                                plPurchasedParts = pl
                                Exit For
                            End If
                        Next
                    End If
                    Dim nextItem As Integer = 1
                    For j As Integer = 1 To plPurchasedParts.PartsListRows.Count
                        Dim plRow As PartsListRow = plPurchasedParts.PartsListRows.Item(j)
                        'renumber the purchased parts items using the P numbers
                        If plRow.Visible = True Then
                            For i As Integer = 1 To plRow.Count
                                Dim plCell As PartsListCell = plRow(i)
                                Dim plColumn As PartsListColumn = plCell.Parent.PartsListColumns(i)
                                If plColumn.Title.ToUpper = "ITEM" Then
                                    plCell.Value = strPrefix & nextItem
                                    nextItem += 1
                                    Exit For
                                End If
                            Next
                        End If
                    Next
                    Exit Sub
                End If
            End If
        End If
    End Sub

    Public Sub UserAddPartsLists()
        GetInventorApplication()
        If invApp.ActiveDocument IsNot Nothing Then
            If TypeOf invApp.ActiveDocument Is Inventor.DrawingDocument Then
                Dim drawDoc As DrawingDocument = invApp.ActiveDocument
                Dim sheet1 As Sheet = drawDoc.ActiveSheet
                If sheet1 IsNot Nothing Then
                    Dim drView As DrawingView = Nothing
                    For Each item As Object In drawDoc.SelectSet
                        If TypeOf item Is Inventor.DrawingView Then
                            drView = item
                            Exit For
                        End If
                    Next
                    Dim modelDoc As Inventor.Document = Nothing
                    If drView Is Nothing Then
                        For Each view As DrawingView In sheet1.DrawingViews
                            If view.ReferencedDocumentDescriptor IsNot Nothing Then
                                modelDoc = view.ReferencedDocumentDescriptor.ReferencedDocument
                                Exit For
                            End If
                        Next
                    Else
                        If drView.ReferencedDocumentDescriptor IsNot Nothing Then
                            modelDoc = drView.ReferencedDocumentDescriptor.ReferencedDocument
                        End If
                    End If
                    If modelDoc IsNot Nothing Then
                        'turn on parts list
                        Dim pntPartsList As Point2d = invApp.TransientGeometry.CreatePoint2d(sheet1.Width - (0.25 * 2.54), 2.95 * 2.54)
                        Dim plBOM As PartsList = sheet1.PartsLists.Add(modelDoc, pntPartsList, PartsListLevelEnum.kStructuredAllLevels)
                        Dim plStyle As PartsListStyle = drawDoc.StylesManager.PartsListStyles.Item("BOM LIST")
                        plBOM.Style = plStyle
                        plBOM.Sort2("PART NUMBER", True,,,,, True, False)
                        Dim booAddPurchasedPartsList As Boolean = False
                        For Each plRow As PartsListRow In plBOM.PartsListRows
                            If PlaceInListOfParts(plRow) = False Then
                                plRow.Visible = False
                                booAddPurchasedPartsList = True
                            End If
                        Next
                        SortListOfPartsByDocumentType(plBOM)
                        Dim pMin As Point2d = plBOM.RangeBox.MinPoint
                        Dim pMax As Point2d = plBOM.RangeBox.MaxPoint
                        pntPartsList.X += 0
                        pntPartsList.Y += (pMax.Y - pMin.Y)
                        plBOM.Position = pntPartsList
                        'turn on purchased parts list
                        If booAddPurchasedPartsList Then
                            pntPartsList = invApp.TransientGeometry.CreatePoint2d(plBOM.Position.X, plBOM.Position.Y)
                            Dim plPurchasedParts As PartsList = sheet1.PartsLists.Add(modelDoc, pntPartsList, PartsListLevelEnum.kStructuredAllLevels)
                            plStyle = drawDoc.StylesManager.PartsListStyles.Item("Purchased Parts")
                            plPurchasedParts.Style = plStyle
                            plPurchasedParts.Sort2("TITLE", True,,,,, True, False)
                            Dim nextItem As Integer = 1
                            For Each plRow As PartsListRow In plPurchasedParts.PartsListRows
                                Dim strPartNumber As String = String.Empty
                                'look for part number to see if it is an engineered part, if not turn it off
                                If PlaceInListOfParts(plRow) = True Then
                                    plRow.Visible = False
                                Else
                                    'strPartNumber = GetPartNumberFromPartsListRow(plRow)
                                    For i As Integer = 1 To plRow.Count
                                        Dim plCell As PartsListCell = plRow(i)
                                        Dim plColumn As PartsListColumn = plCell.Parent.PartsListColumns(i)
                                        If plColumn.Title.ToUpper = "PART NUMBER" Then
                                            strPartNumber = plCell.Value
                                            If strPartNumber.Contains("ANSI") Then 'if it is not an engineered part , check for ANSI and remove it from this cell
                                                plCell.Value = ""
                                            End If
                                        End If
                                        Exit For
                                    Next
                                End If
                                'look for title, and use the previously found part number to see if it has ANSI in the name, if so, move the value from the part number to the title
                                If strPartNumber.Contains("ANSI") Then
                                    For i As Integer = 1 To plRow.Count
                                        Dim plCell As PartsListCell = plRow(i)
                                        Dim plColumn As PartsListColumn = plCell.Parent.PartsListColumns(i)
                                        If plColumn.Title.ToUpper = "TITLE" Then
                                            If String.IsNullOrWhiteSpace(plCell.Value) Then plCell.Value = strPartNumber
                                        End If
                                    Next
                                End If
                                'renumber the purchased parts items using the P numbers
                                If plRow.Visible = True Then
                                    For i As Integer = 1 To plRow.Count
                                        Dim plCell As PartsListCell = plRow(i)
                                        Dim plColumn As PartsListColumn = plCell.Parent.PartsListColumns(i)
                                        If plColumn.Title.ToUpper = "ITEM" Then
                                            plCell.Value = "P" & nextItem
                                            nextItem += 1
                                        End If
                                    Next
                                End If
                            Next
                            pMin = plPurchasedParts.RangeBox.MinPoint
                            pMax = plPurchasedParts.RangeBox.MaxPoint
                            pntPartsList.X += 0
                            pntPartsList.Y += (pMax.Y - pMin.Y)
                            plPurchasedParts.Position = pntPartsList
                        End If
                    Else
                        MsgBox("Can not find model for parts list.")
                    End If
                End If
            End If
        End If
    End Sub

    Private Sub SortListOfPartsByDocumentType(plBOM As PartsList)
        Dim i As Integer = 0
        Do
            i += 1
            Dim booRestart As Boolean = False
            Dim pn1 As PartNumber = New PartNumber(GetPartNumberFromPartsListRow(plBOM.PartsListRows(i)))
            SetSortOverridesForPartsListRow(plBOM.PartsListRows(i), pn1)
            Dim pn2 As PartNumber = New PartNumber(GetPartNumberFromPartsListRow(plBOM.PartsListRows(i + 1)))
            SetSortOverridesForPartsListRow(plBOM.PartsListRows(i + 1), pn2)
            Dim comp As Integer = pn1.CompareTo(pn2)
            If comp = 1 Then
                plBOM.PartsListRows(i + 1).Reposition(i)
                i = 0
                booRestart = True
            End If
        Loop Until i = plBOM.PartsListRows.Count - 1
    End Sub

    Private Sub SetSortOverridesForPartsListRow(plRow As PartsListRow, pn As PartNumber)
        If plRow.ReferencedFiles.Count > 0 Then
            'car file
            If plRow.ReferencedFiles.Item(1).FullFileName.Contains("\Libraries\Cars\") Then
                pn.SortOverride = -2
            End If
            'load file
            Dim invDoc As Inventor.Document = plRow.ReferencedFiles.Item(1).ReferencedDocument
            If GetiPropertyValue(Tools.UserDefinedPropertySetID, "Specification", invDoc) IsNot Nothing Then
                pn.SortOverride = -1
            End If
        End If
    End Sub
Jamie Johnson : Owner / Sisu Lissom, LLC https://sisulissom.com/
Message 6 of 9

claudio.ibarra
Advocate
Advocate

Please forgive my ignorance -- how do I use this code? 

 

Am I supposed to copy that into a rule with other syntax around it? I get this with the code in a rule by itself.

Capture01.PNG

 

Should I append it to the code I already borrowed? I feel like that might not be the right way to go... many more errors.

Capture02.PNG

 

How do I best make use of what you've written out here? Also, what's a car file?

 

 

0 Likes
Message 7 of 9

claudio.ibarra
Advocate
Advocate

Yes, that puts purchased at the bottom! And it leaves me with intPurchItemCounter and intNonPurchItemCounter, each at +1 more than the actual parts list count at the end. 

 

Would it be possible to use those counters to selectively renumber the parts list in a half-alpha half-numeric fashion?

0 Likes
Message 8 of 9

Anonymous
Not applicable
Accepted solution

Claudio,

Here you go. This will renumber the non-purchased components as alphabetic characters and purchased as numeric. The only thing is that when you sort it, Inventor will place numeric items before alphabetic items. So your purchased components will be before the non-purchased. That's what this code here will do.

 

If you want the purchased components at the bottom, what you can probably do is append "ZZ" before the numeric for purchased components so that it is at the bottom. Then go through the parts list again and look for the "ZZ" and remove it.

 

Hope that helps.

 

DanV

 

Dim oDrawDoc As DrawingDocument = ThisDoc.Document

Dim oPartList As PartsList
oPartsList = oDrawDoc.ActiveSheet.PartsLists.Item(1)

oPartsList.Sort("PART NUMBER", True)

Dim oItemCell As PartsListCell
Dim strNonPurchItem As String = "A"
Dim intPurchItemCounter As Integer = 1

For j = 1 To oPartsList.PartsListRows.Count
	Dim oPartsListRow As PartsListRow = oPartsList.PartsListRows.Item(j)
	oItemCell = oPartsListRow.Item("ITEM")
	'MessageBox.Show(oPartsListRow.Item("PART NUMBER").Value)
	Dim oDrawingBOMRow As DrawingBOMRow = oPartsListRow.ReferencedRows.Item(1)
	Dim oBOMRow As BOMRow = oDrawingBOMRow.BOMRow
	
	If Not oBOMRow Is Nothing Then
		Dim oCompDef As ComponentDefinition = oBOMRow.ComponentDefinitions.Item(1)	
		Dim oBomStructure As BOMStructureEnum = oCompDef.BOMStructure
		
		If oBomStructure = BOMStructureEnum.kPurchasedBOMStructure Then
			oItemCell.Value = intPurchItemCounter
			intPurchItemCounter += 1
		Else
			oItemCell.Value = strNonPurchItem
			strNonPurchItem = Chr(Asc(strNonPurchItem) + 1)
			'skip I and O
			If strNonPurchItem = "I" Or strNonPurchItem = "O" Then
				strNonPurchItem = Chr(Asc(strNonPurchItem) + 1)
			End If
		End If
	End If
	
Next
oPartsList.Sort("ITEM", True)

 

0 Likes
Message 9 of 9

claudio.ibarra
Advocate
Advocate

That definitely works! I will figure out how to apply that ZZ reorder. Thank you!

0 Likes