Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Quantity om drawing based on total number of parts. iLogic

35 REPLIES 35
SOLVED
Reply
Message 1 of 36
Anonymous
4904 Views, 35 Replies

Quantity om drawing based on total number of parts. iLogic

Hello Autodesk community!

 

does anyone know how to get the total number of a part from a top assembly down to a drawing?

 

I already have  a solution to the question. BUT, i cannot force inventor to count sub-assemblies. any help would be amazing.

 

With kind regards, Mikael Nanke

 

Here is my code:

 

SyntaxEditor Code Snippet

doc = ThisDoc.Document
Dim oAssyDef As AssemblyComponentDefinition = doc.ComponentDefinition
oAssyDef.RepresentationsManager.LevelOfDetailRepresentations("Master").Activate
Dim oBOM As BOM = oAssyDef.BOM

oBOM.PartsOnlyViewEnabled = True

Dim oBOMView As BOMView = oBOM.BOMViews.Item("Parts Only")

Dim oBOMRow As BOMRow

For Each oBOMRow In oBOMView.BOMRows
    'Set a reference to the primary ComponentDefinition of the row
    Dim oCompDef As ComponentDefinition
    oCompDef = oBOMRow.ComponentDefinitions.Item(1)
    
    Dim CompFullDocumentName As String = oCompDef.Document.FullDocumentName
    Dim CompFileNameOnly As String
    Dim index As Integer = CompFullDocumentName.lastindexof("\")
    
    CompFileNameOnly = CompFullDocumentName.substring(index+1)
    'MessageBox.Show(CompFileNameOnly)
    
     Dim Qty As String
     
    Try    
           Qty = oBOMRow.ItemQuantity
    Catch
        MessageBox.Show("Kunne ikke til f�je Part antal til CompFileNameOnly", "Title")
    End Try
    
    iProperties.Value(CompFileNameOnly, "Custom", "PartQty") = Qty
Next

 

35 REPLIES 35
Message 21 of 36
P_Korgaonkar
in reply to: Anonymous

Thank you for your quick reply.

I can share a project folder directly with you if you don't mind.

I hesitate to share it on the forum as you may understnd.

Do you mind sharing an email where I can send a wetransfer link?

You can email me if you wish, parag@contechengineering.com

 

Thank you once again.

Regards

Parag

Message 22 of 36
P_Korgaonkar
in reply to: A.Acheson

Thank you for your quick reply A.Acheson.

 

I can send you the project via wetransfer if you don't mind sharing an email address.

You can share your email here or you can email me at parag@contechengineering.com

 

Thank you once again.

Regards

Parag

Message 23 of 36
A.Acheson
in reply to: P_Korgaonkar

As you are using Inv 2021 I am not sure if the read only checking function will work the same way so I have commented the reference to the function and just put the part qty in a try and catch statement. Please test and see if this works. 

Sub Main
'Get current document
doc = ThisDoc.Document
Dim oAssyDef As AssemblyComponentDefinition = doc.ComponentDefinition
'Get the BOM object
Dim oBOM As BOM = oAssyDef.BOM
'enable the Parts Only View
oBOM.PartsOnlyViewEnabled = True
'Get the Parts Only view of the BOM
Dim oBOMViewPO As BOMView = oBOM.BOMViews.Item("Parts Only")
'declare variable for each BOM row.
Dim oBOMRowPO As BOMRow

'For each row in the Parts Only BOM, do the following
For Each oBOMRowPO In oBOMViewPO.BOMRows
    'Set a reference to the primary ComponentDefinition of the row
    Dim oCompDef As ComponentDefinition = oBOMRowPO.ComponentDefinitions.Item(1)
    
    'get the full filename associated to the component in the row. ex: c:\temp\part1.ipt
    Dim CompFullDocumentName As String = oCompDef.Document.FullDocumentName
    Dim CompFileNameOnly As String
    'get the location of the last backslash
    Dim index As Integer = CompFullDocumentName.LastIndexOf("\")
    'get the filename only from the full filename
    CompFileNameOnly = CompFullDocumentName.Substring(index+1)
    
    'MessageBox.Show(CompFileNameOnly)
    
    'get the Qty value in the current row
    Dim Qty As String = oBOMRowPO.TotalQuantity
	
   		
		
    'check to see if the component is a library part, cc part or read only.
   ' Dim IsLibCCReadonly As Boolean = LibCCReadonlyChecker(CompFullDocumentName)
    
    'if the file is NOT a library part, cc part or read only.
   ' If IsLibCCReadonly = False Then
        'set following custom iproperty to equal the QTY from the row
		 Try
			iProperties.Value(CompFileNameOnly, "Custom", "PartQty") = Qty
         Catch
			Logger.Info(CompFileNameOnly, "Error in PartQty Main Sub")
		End Try
    'End If
Next

'at this time, the qty value for all parts have been copied to the custom property.'next, the following code will cycle through only the subassemblies.

'if the Structured BOM view is enabled then...
If oBOM.StructuredViewEnabled Then
    'If show First Level is set then turn it off. This will set it to All Levels
    If oBOM.StructuredViewFirstLevelOnly Then
        oBOM.StructuredViewFirstLevelOnly = False
    End If
Else
    'enable the Structured BOM view
    oBOM.StructuredViewEnabled = True
    'set the FirstLevelOnly to false therefore make it All Levels
    oBOM.StructuredViewFirstLevelOnly = False
End If

'Get the Structured view of the BOM
Dim oBOMViewStruc As BOMView = oBOM.BOMViews.Item("Structured")
'declare variable for each BOM row.
Dim oBOMRowStruc As BOMRow
'Create a blank array(list). This will be used to store a list of all subassemblies for comparing if the subassembly already exist.
Dim arrSubAssemblyList As New ArrayList

'call a subroutine to cycle through the structured BOM. It will need the collection of rows, the subassembly list, and 1 is the initial parentqty.
Call QueryBOMRowProperties(oBOMViewStruc.BOMRows, arrSubAssemblyList, 1)

End Sub

Private Sub QueryBOMRowProperties(oBOMRows As BOMRowsEnumerator, arrSubAssembly As ArrayList, oParentQty As Integer)

'declare a incrementer variable
Dim i As Long
'for each row in the structured BOM
For i = 1 To oBOMRows.count
    'get the row based on the incrementer
    Dim oBOMRowStruc As BOMRow = oBOMRows.item(i)
    'get the component definition assocated with the row
    Dim oCompDef As ComponentDefinition = oBOMRowStruc.ComponentDefinitions.Item(1)
    Dim oQty As Integer
    
    'If the component is an assembly and it's bom structure is Normal then do the following. else do nothing
    If TypeOf oCompDef Is AssemblyComponentDefinition And oCompDef.BOMStructure = BOMStructureEnum.kNormalBOMStructure Then
            'get the full filename associated to the component in the row. ex: c:\temp\subassembly.iam
            Dim CompFullDocumentName As String = oCompDef.Document.FullDocumentName
            Dim CompFileNameOnly As String
            'get the location of the last backslash
            Dim index As Integer = CompFullDocumentName.LastIndexOf("\")
            'get the filename only from the full filename
            CompFileNameOnly = CompFullDocumentName.Substring(index+1)
            'MessageBox.Show(CompFileNameOnly)
            
            'get the qty of the row and multiply by the parent qty.
            oQty = oBOMRowStruc.ItemQuantity * oParentQty
            
            'create a variable that will be used to get the qty of the subassembly if it was used elsewhere
            Dim additionalQty As Integer = 0
            'if the subassembly list is not empty then...
            If arrSubAssembly.Count <> 0 Then
                'create a counter. this will be used to determine which item in the subassembly array (list) when it finds a match.
                'this counter will be used to edit that item with the new qty.
                Dim counter As Integer = 0
                'for each item in the subassembly array (list) starting at 0 (first item) to last item
                For j As Integer = 0 To arrSubAssembly.Count-1
                    'get the location of the colon
                    Dim commaindex As Integer = arrSubAssembly(j).indexof(":")
                    'get just the file name
                    Dim CompName As String = arrSubAssembly(j).substring(0,commaindex)
                    
                    'if the file name of the current row matches the current item in the subassembly array (list) then...
                    If CompName = CompFileNameOnly Then
                        'set the additional qty to the qty found in the subassembly array (list)
                        additionalQty = arrSubAssembly(j).substring(commaindex+1)
                        'set the counter equal to the item in the subassembly array (list)
                        counter = j
                        'since a match is found, we need to exit the for loop so that counter no longer increments.
                        'so Set j To the number of items in the subassembly array. this will exit out the for loop.
                        j = arrSubAssembly.Count
                    Else
                        'increase the counter
                        counter += 1
                    End If
                Next
                
                'if additional qty was not changed then there was no match. It will be a new item in the subassembly array (list)
                If additionalQty = 0 Then
                    'add the subassambly to the subassembly array (list)
                    arrSubAssembly.add(CompFileNameOnly & ":" & oQty)
                Else
                    'if it did find a match, then update the qty for that item in the subassembly array (list)
                    arrSubAssembly(counter) = CompFileNameOnly & ":" & oQty + additionalQty
                End If
            Else
                'add the first subassembly to the list. It will add the filename and the qty separated by a colon. ex. subassembly.iam:2
                arrSubAssembly.add(CompFileNameOnly & ":" & oQty)
            End If
            
            'check to see if the component is a library part, cc part or read only.
            'Dim IsLibCCReadonly As Boolean = LibCCReadonlyChecker(CompFullDocumentName)
            
            'if the file is NOT a library part, cc part or read only.
           ' If IsLibCCReadonly = False Then
                'set following custom iproperty to equal the QTY from the row plus the additional qty value
               
			   Try
			   		iProperties.Value(CompFileNameOnly, "Custom", "PartQty") = oQty + additionalQty
            	Catch
					Logger.Info(CompFileNameOnly, "Error in PartQty sub QueryBOMRowProperties")
				End Try
                'Recursively iterate child rows if present.
                If Not oBOMRowStruc.ChildRows Is Nothing Then
                    'recall the subroutine, push the childrows of the sub, sub assembly array (list), and the qty of the subassembly
                    Call QueryBOMRowProperties(oBOMRowStruc.ChildRows, arrSubAssembly, oQty)
                End If
            'End If
        End If
    Next
End Sub

Private Function LibCCReadonlyChecker(filename As String) As Boolean
' Get the active project
Dim oProject As DesignProject = ThisApplication.DesignProjectManager.ActiveDesignProject
' Get all the library paths
Dim oLibraryPaths As ProjectPaths = oProject.LibraryPaths
Dim oLibraryPath As ProjectPath

'for each library path in the list of all library paths
For Each oLibraryPath In oLibraryPaths
    'get the library path
    Dim oLibs As String = oLibraryPath.Path
    'if the file is in a library path then Return True
    If filename.Contains(oLibs) = True Then
        Return True
    End If
Next

'if the file is in the CC location then Return True
If filename.Contains(oProject.ContentCenterPath) = True Then
    Return True
End If

'get read only status
Dim File_Attr As Long = System.IO.File.GetAttributes(filename)
'if the file is readonly or readonly and archieve then Return True
If File_Attr = 1 Or File_Attr = 33 Then
    Return True
End If

'return False if it's not a library, CC or a Readonly part.
Return False

End Function

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
Message 24 of 36
P_Korgaonkar
in reply to: A.Acheson

Thank you, A.Acheson

 

Yes, this new rule works like charm.

No errors and all parts and assemblies get a PartQty custom property with the correct total quantity.

 

Thank you very much, really appreciate it.

 

I was wondering, if we do not check for library and read-only files and just tried to write to each and every file what will happen?

When I use design assistant and copy I properties, they get copied to all parts including the library parts, so there is no reason for Ilogic code not to write to library parts, am I correct in saying this? or am I missing something?

 

Thank you once again, May God Bless you!

Regards

Parag

Message 25 of 36
A.Acheson
in reply to: P_Korgaonkar

Ok so I am assuming the function is not working and indicating which files are read only and to be skipped and which ones are writeable to accept the property value.  The function or the filtering it does is the correct way to check the status of the files. The try catch statement is inefficient. Perhaps a good analogy is a bunch of keys :key: :key: :key: (try catch) instead of selecting the correct labeled key by excluding the wrong keys (excluding read only status) :locked_with_key: :label: .

If your looking to write to your library parts like this I think the folder structure you are using is different than intended. My library on the desktop is read only so acts like the CC so as the files can be reused.

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
Message 26 of 36
P_Korgaonkar
in reply to: Anonymous

Thank you for the quick reply.

Sorry if I confused you. The code is working fine for this purpose and I am very happy with it. What you have done is correct and there is no doubt or question about your code or your abilities or your intentions.

I was curious to know what will happen just in case if we try to write to library parts.

My library is also on my desktop, and I can not edit parts while working on a project, as Inventor does not allow me to edit parts from Library. Saying that when I use the design assistant to change/copy I properties, it does change library parts as well. This makes me think that it is possible to edit I properties using the I logic. Maybe I am wrong. I don't have in-depth knowledge of this, so just asking the questions out of curiosity.

Old days, at the time of install Inventor, did ask a question if I want to edit library parts and use to say "NO" I am not sure if this option still exists, and I also wonder if I allow editing of library parts will this code work as it is. All questions out of curiosity!

 

Thank you once again.

 

Regards

Parag

Message 27 of 36
cgchad
in reply to: Anonymous

This doesn't seem to work in 2023.  Maybe I am doing something wrong since I am new to iLogic.

Does this go in the assembly itself?  If so it definitely doesn't work.

 

Where would this get applied?  iam? ipt? idw?

Message 28 of 36
Moverano
in reply to: Anonymous

@Anonymous @A.Acheson @GosponZ 

I probe in v2015 but it generated an error, atach imagen. 

 

Any idea which the problem?

 

Thanks

Message 29 of 36
A.Acheson
in reply to: Moverano

Can you post the more info tab information and translate to English? Also post the code your using or refer to which message you copied the code from.

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
Message 30 of 36
Moverano
in reply to: A.Acheson

Thanks @A.Acheson 

 

This is the code:

 

Sub Main
'Get current document
doc = ThisDoc.Document
Dim oAssyDef As AssemblyComponentDefinition = doc.ComponentDefinition
'Get the BOM object
Dim oBOM As BOM = oAssyDef.BOM
'enable the Parts Only View
oBOM.PartsOnlyViewEnabled = True
'Get the Parts Only view of the BOM
Dim oBOMViewPO As BOMView = oBOM.BOMViews.Item("Parts Only")
'declare variable for each BOM row.
Dim oBOMRowPO As BOMRow

'For each row in the Parts Only BOM, do the following
For Each oBOMRowPO In oBOMViewPO.BOMRows
    'Set a reference to the primary ComponentDefinition of the row
    Dim oCompDef As ComponentDefinition = oBOMRowPO.ComponentDefinitions.Item(1)
    
    'get the full filename associated to the component in the row. ex: c:\temp\part1.ipt
    Dim CompFullDocumentName As String = oCompDef.Document.FullDocumentName
    Dim CompFileNameOnly As String
    'get the location of the last backslash
    Dim index As Integer = CompFullDocumentName.lastindexof("\")
    'get the filename only from the full filename
    CompFileNameOnly = CompFullDocumentName.substring(index+1)
    
    'MessageBox.Show(CompFileNameOnly)
    
    'get the Qty value in the current row
    Dim Qty As String = oBOMRowPO.ItemQuantity
    
    'check to see if the component is a library part, cc part or read only.
    Dim IsLibCCReadonly As Boolean = LibCCReadonlyChecker(CompFullDocumentName)
    
    'if the file is NOT a library part, cc part or read only.
    If IsLibCCReadonly = False Then
        'set following custom iproperty to equal the QTY from the row (cQty IN ORIGINAL RULE)
        iProperties.Value(CompFileNameOnly, "Custom", "UDS_T") = Qty
    End If
Next

'at this time, the qty value for all parts have been copied to the custom property.'next, the following code will cycle through only the subassemblies.

'if the Structured BOM view is enabled then...
If oBOM.StructuredViewEnabled Then
    'If show First Level is set then turn it off. This will set it to All Levels
    If oBOM.StructuredViewFirstLevelOnly Then
        oBOM.StructuredViewFirstLevelOnly = False
    End If
Else
    'enable the Structured BOM view
    oBOM.StructuredViewEnabled = True
    'set the FirstLevelOnly to false therefore make it All Levels
    oBOM.StructuredViewFirstLevelOnly = False
End If

'Get the Structured view of the BOM
Dim oBOMViewStruc As BOMView = oBOM.BOMViews.Item("Structured")
'declare variable for each BOM row.
Dim oBOMRowStruc As BOMRow
'Create a blank array(list). This will be used to store a list of all subassemblies for comparing if the subassembly already exist.
Dim arrSubAssemblyList As New ArrayList

'call a subroutine to cycle through the structured BOM. It will need the collection of rows, the subassembly list, and 1 is the initial parentqty.
Call QueryBOMRowProperties(oBOMViewStruc.BOMRows, arrSubAssemblyList, 1)
Dim openDoc As Document
openDoc = ThisDoc.Document
Dim docFile As Document
If openDoc.DocumentType = 12291 Then
    For Each docFile In openDoc.AllReferencedDocuments
        Dim FNamePos As Long
        Dim docFName As String
        FNamePos = InStrRev(docFile.FullFileName, "\", - 1)
        docFName = Mid(docFile.FullFileName, FNamePos + 1, Len(docFile.FullFileName) - FNamePos)

        If docFile.IsModifiable = True Then
            Dim assemblyDoc As AssemblyDocument
            Dim assemblyDef As AssemblyComponentDefinition
            Dim partQty As ComponentOccurrencesEnumerator

            assemblyDoc = openDoc
            assemblyDef = assemblyDoc.ComponentDefinition
            partQty = assemblyDef.Occurrences.AllReferencedOccurrences(docFile)
            If IsNumeric(partQty.Count) = True Then
                Try
                    If IsNumeric(iProperties.Value(docFName, "Custom", "UDS_P")) = False Then
                        iProperties.Value(docFName, "Custom", "UDS_P") = 0
                    End If
                Catch
                    iProperties.Value(docFName, "Custom", "UDS_P") = partQty.Count
                End Try
                If partQty.Count <> iProperties.Value(docFName, "Custom", "UDS_P") Then
                    iProperties.Value(docFName, "Custom", "UDS_P") = partQty.Count
                End If
            End If
        End If
    Next
End If
End Sub


Private Sub QueryBOMRowProperties(oBOMRows As BOMRowsEnumerator, arrSubAssembly As ArrayList, oParentQty As Integer)

'declare a incrementer variable
Dim i As Long
'for each row in the structured BOM
For i = 1 To oBOMRows.count
    'get the row based on the incrementer
    Dim oBOMRowStruc As BOMRow = oBOMRows.item(i)
    'get the component definition assocated with the row
    Dim oCompDef As ComponentDefinition = oBOMRowStruc.ComponentDefinitions.item(1)
    Dim oQty As Integer
    
    'If the component is an assembly and it's bom structure is Normal then do the following. else do nothing
    If TypeOf oCompDef Is AssemblyComponentDefinition And oCompDef.BOMStructure = BOMStructureEnum.kNormalBOMStructure Then
            'get the full filename associated to the component in the row. ex: c:\temp\subassembly.iam
            Dim CompFullDocumentName As String = oCompDef.Document.FullDocumentName
            Dim CompFileNameOnly As String
            'get the location of the last backslash
            Dim index As Integer = CompFullDocumentName.lastindexof("\")
            'get the filename only from the full filename
            CompFileNameOnly = CompFullDocumentName.substring(index+1)
            'MessageBox.Show(CompFileNameOnly)
            
            'get the qty of the row and multiply by the parent qty.
            oQty = oBOMRowStruc.ItemQuantity * oParentQty
            
            'create a variable that will be used to get the qty of the subassembly if it was used elsewhere
            Dim additionalQty As Integer = 0
            'if the subassembly list is not empty then...
            If arrSubAssembly.Count <> 0 Then
                'create a counter. this will be used to determine which item in the subassembly array (list) when it finds a match.
                'this counter will be used to edit that item with the new qty.
                Dim counter As Integer = 0
                'for each item in the subassembly array (list) starting at 0 (first item) to last item
                For j As Integer = 0 To arrSubAssembly.Count-1
                    'get the location of the colon
                    Dim commaindex As Integer = arrSubAssembly(j).indexof(":")
                    'get just the file name
                    Dim CompName As String = arrSubAssembly(j).substring(0,commaindex)
                    
                    'if the file name of the current row matches the current item in the subassembly array (list) then...
                    If CompName = CompFileNameOnly Then
                        'set the additional qty to the qty found in the subassembly array (list)
                        additionalQty = arrSubAssembly(j).substring(commaindex+1)
                        'set the counter equal to the item in the subassembly array (list)
                        counter = j
                        'since a match is found, we need to exit the for loop so that counter no longer increments.
                        'so Set j To the number of items in the subassembly array. this will exit out the for loop.
                        j = arrSubAssembly.Count
                    Else
                        'increase the counter
                        counter += 1
                    End If
                Next
                
                'if additional qty was not changed then there was no match. It will be a new item in the subassembly array (list)
                If additionalQty = 0 Then
                    'add the subassambly to the subassembly array (list)
                    arrSubAssembly.add(CompFileNameOnly & ":" & oQty)
                Else
                    'if it did find a match, then update the qty for that item in the subassembly array (list)
                    arrSubAssembly(counter) = CompFileNameOnly & ":" & oQty + additionalQty
                End If
            Else
                'add the first subassembly to the list. It will add the filename and the qty separated by a colon. ex. subassembly.iam:2
                arrSubAssembly.add(CompFileNameOnly & ":" & oQty)
            End If
            
            'check to see if the component is a library part, cc part or read only.
            Dim IsLibCCReadonly As Boolean = LibCCReadonlyChecker(CompFullDocumentName)
            
            'if the file is NOT a library part, cc part or read only.
            If IsLibCCReadonly = False Then
                'set following custom iproperty to equal the QTY from the row plus the additional qty value
                iProperties.Value(CompFileNameOnly, "Custom", "UDS_T") = oQty + additionalQty
            
                'Recursively iterate child rows if present.
                If Not oBOMRowStruc.ChildRows Is Nothing Then
                    'recall the subroutine, push the childrows of the sub, sub assembly array (list), and the qty of the subassembly
                    Call QueryBOMRowProperties(oBOMRowStruc.ChildRows, arrSubAssembly, oQty)
                End If
            End If
        End If
    Next
End Sub

Private Function LibCCReadonlyChecker(filename As String) As Boolean
' Get the active project
Dim oProject As DesignProject = ThisApplication.DesignProjectManager.ActiveDesignProject
' Get all the library paths
Dim oLibraryPaths As ProjectPaths = oProject.LibraryPaths
Dim oLibraryPath As ProjectPath

'for each library path in the list of all library paths
For Each oLibraryPath In oLibraryPaths
    'get the library path
    Dim oLibs As String = oLibraryPath.Path
    'if the file is in a library path then Return True
    If filename.Contains(oLibs) = True Then
        Return True
    End If
Next

'if the file is in the CC location then Return True
If filename.Contains(oProject.ContentCenterPath) = True Then
    Return True
End If

'get read only status
Dim File_Attr As Long = System.IO.File.GetAttributes(filename)
'if the file is readonly or readonly and archieve then Return True
If File_Attr = 1 Or File_Attr = 33 Then
    Return True
End If

'return False if it's not a library, CC or a Readonly part.
Return False

Try
            iProperties.Value(CompFileNameOnly, "Custom", "UDS_T") = Qty
    Catch 'Is Not a writeable file
        End Try

End Function
 

 

 

Message 31 of 36
A.Acheson
in reply to: Moverano

Hi @Moverano 

I haven't been able to test the code but I see one potential issue. In the second block in for loop of referenced documents all referenced documents are set to be an assembly document which wouldn't always be correct. It will be a mixture of part and assembly documents.

assemblyDoc = openDoc
assemblyDef = assemblyDoc.ComponentDefinition
         

 In addition because the error message isn't too descriptive just saying there is a string error can you step through the code with a logger.info line or message box? Keep moving it down and running the code. Whichever line the errror message shows and the written message fails to be displayed this is your trouble area. 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
Message 32 of 36
P_Korgaonkar
in reply to: Anonymous

Hello A.Acheson and Moverano.

 

I have used this code since my last discussion on this thread, and it works fine with Inventor 2021.

I always use it on Assembly. I run this code and then Use a parts list in IDW with the "PartQty" column in the parts list.

 

I am unsure who wrote this code; I found it on this forum. And thanks to the writer, it has saved me hours and hours of work. On average, I use it a minimum of three times a week.

 

Regards

Parag

Message 33 of 36
GosponZ
in reply to: Moverano

In ipt template make custom properties  TTL and TotalUnits.  Make global form  and make like this

GosponZ_0-1704305630755.png Run this rule in assembly by pressing  update quantities

 
Sub Main
On Error Resume Next
Dim openDoc As Document
openDoc = ThisDoc.Document
Dim docFile As Document
 
Dim oCustomPropertySet = ThisDoc.Document.PropertySets.Item("Inventor User Defined Properties")
If iProperties.Value("Custom", "TotalUnits") = 0 Then
iProperties.Value("Custom", "TotalUnits") = 1
End If
Dim Total_Units = iProperties.Value("Custom", "TotalUnits")
 
 
 
If openDoc.DocumentType = 12291 Then
For Each docFile In openDoc.AllReferencedDocuments
 
Dim propertyName As String = "TTL"
Dim propertyValue As Integer = 1
customPropertySet = docFile.PropertySets.Item("Inventor User Defined Properties")
' Try
' prop = customPropertySet.Item("TTL")
' Catch
' ' Assume error means not found
' customPropertySet.Add(1, "TTL")
' End Try
Dim FNamePos As Long
Dim docFName As String
FNamePos = InStrRev(docFile.FullFileName, "\", -1)
docFName = Mid(docFile.FullFileName, FNamePos + 1, Len(docFile.FullFileName) -FNamePos)
 
If docFile.IsModifiable = True Then
Dim assemblyDoc As AssemblyDocument
Dim assemblyDef As AssemblyComponentDefinition
Dim partQty As ComponentOccurrencesEnumerator
assemblyDoc = openDoc
assemblyDef = assemblyDoc.ComponentDefinition
partQty = assemblyDef.Occurrences.AllReferencedOccurrences(docFile)
 
If IsNumeric(partQty.Count) = True Then
iProperties.Value(docFName, "Custom", "TTL") = partQty.Count * Total_Units
 
'**** FOR TESTING PURPOSES - place a ' in front of the next 3 lines to skip it
' MessageBox.Show(docFName _
' & vbLf & " Part Qty = " & partQty.Count _
' & vbLf & " TTL = " & iProperties.Value(docFName, "Custom", "TTL"), "iLogic")
 
End If
End If
Next
Else
MessageBox.Show("You must have a valid Assembly document open before using this code!", "File Type Mismatch!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
End Sub.
 
In form editor
GosponZ_2-1704305811888.png

 

All parts will be counted except CC and Library parts.

 

Hope will work for you. This rule is short but does great job. 

Message 34 of 36
P_Korgaonkar
in reply to: Anonymous

Thank you GosponZ

 

I use a lot of old models, and it's not possible to add custom properties to each part manually. The current rule I use does not need this manual step. It will create a custom Iproperty if there is not one. and it will update the quantity if there is an I-property already available.

I am not smart enough to write a code, but in your code, if you can add a code to write a custom property to each Assembly or IPT file, then it would be a better solution.

 

Regards

Parag

 

Regards

Parag

Message 35 of 36
GosponZ
in reply to: Anonymous

Ok, just in assembly level(for old models) make that custom TTL and TotalUnits iprop.  For your new parts and assembly make this 2 parameters in assembly template  not in part as i mention above. Make form as above and run update qty.

Message 36 of 36
Moverano
in reply to: GosponZ

Thanks for your help @GosponZ  I copy the code but it generates the following error

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report