I found a rule on the forums a while back that kind of does that. The caveat is that it does not count CC parts as they are read only and the rule writes back a project iproperty with a quantity to all components.
'01/03/2017
'Reg Hasell.
'This iLogic rule will run though all the items in an assembly and add a QTY field to it.
'The QTY field is based on a programmable project number. (project_QTY)
'Any Content Center items are ignored. (Read Only)
'There is an option to set the project number.
'
'Some of this code has originated from the forum, but I cannot
'remember where I got it from, so I am unable To give credit To the original author.
Sub Main ()
'Check to see if this document is an assembly.
oDoc = ThisApplication.ActiveDocument
If oDoc.DocumentType <> kAssemblyDocumentObject Then
MessageBox.Show("This rule can only be run in an Assembly file - exiting rule...", "GDI iLogic")
Return
End If
If iProperties.Value("Project", "Project")=""
oProj = InputBox("Change Project Name", "Project Name", iProperties.Value("Project", "Project"))
iProperties.Value("Project", "Project")=oProj
End If
'get the project number of this assembly and use it to build the name of a custom property, i.e. "4100_QTY"
customPropertyName = CStr(iProperties.Value("Project", "Project")) & "_QTY"
oQ=MessageBox.Show(customPropertyName, "Project Number",MessageBoxButtons.YesNoCancel,MessageBoxIcon.Question)
If oQ=vbYes
oDone()
ElseIf oQ=vbNo
Call oProject
ElseIf oQ=vbCancel
MessageBox.Show("Cancelled", "GDI iLogic", MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1)
Return
End If
End Sub
Sub oDone
oCompDef = ThisDoc.Document.ComponentDefinition
openDoc = ThisDoc.Document
customPropertyName = CStr(iProperties.Value("Project", "Project")) & "_QTY"
'Open the document that inventor has in focus right now
For Each docFile In openDoc.AllReferencedDocuments
'FNamePos is getting the number of spaces that it takes to get to the
'very last back slash in the full file name of our document.
FNamePos = InStrRev(docFile.FullFileName, "\", -1)
'We can then take that number (position) and use it to cut off all of the
'file path that we don't need. In this case, it's the front of the path
'that we're getting rid of, leaving us with just the file name.
docFName = Mid(docFile.FullFileName, FNamePos + 1, Len(docFile.FullFileName) - FNamePos)
'Let's make sure that we can even change this part. If we can, then we'll continue.
If docFile.IsModifiable = True Then
'Because you can only grab the occurrences from an assembly document
'we need to fill up that empty AssemblyDocument container with an object
'that we know is definitely an assembly document. Because that was one
'of the first checks we made up there on this open document, we can safely
'declare that assemblyDoc (Which is an AssemblyDocument) is equal to
' openDoc (Which is just a regular old Document)
assemblyDoc = openDoc
'While we're at it, let's go on and define the empty ComponentDefinition container
'(we named ours assemblyDef) with some sort of content.
assemblyDef = assemblyDoc.ComponentDefinition
'Now we need to collect every instance of the document against
'our open assembly and put them all inside of partQty.
partQty = assemblyDef.Occurrences.AllReferencedOccurrences(docFile)
'Now that we have our collection of instances, we need to populate
'our target iproperty with the total amount.
'Instead of just throwing that amount in there, let's make sure that
'the value inside of the target iProperty isn't already equal to our count.
'If it is equal, then we don't have to change anything (which saves us time!),
'but if it isn't equal then we will need to change it.
'The Try statement is here because of the next if statement ---
'If we just compare the two values, there is a small chance that our target
'iProperty is already set to something that is NOT a number, which would create
'an error (as you can't compare numbers against things that aren't numbers).
'So, we TRY to complete that if statement, and if there is an error (The CATCH)
'we just force that target to equal our part qty total.
Try
If partQty.Count <> iProperties.Value(docFName, "Custom", customPropertyName) Then
iProperties.Value(docFName, "Custom", customPropertyName) = partQty.Count
End If
Catch
iProperties.Value(docFName, "Custom", customPropertyName) = partQty.Count
End Try
End If
Next
'29/01/2016
'I added the following to create the value for the GA
'Some code automation in the Detailing environment was
'failing because it could not find a valid entry.
'This is a dummy field, and does not contribute to the rest of the inteligence of the rule.
Try
oASSYParam= iProperties.Value("Custom",customPropertyName)
Catch
iProperties.Value("Custom",customPropertyName) = "1"
End Try
iLogicVb.UpdateWhenDone = True
MessageBox.Show("Completed" & vbNewLine & ":-)", "Completed", MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1)
End Sub
Sub oProject
oProj = InputBox("Change Project Name", "Project Name", iProperties.Value("Project", "Project"))
iProperties.Value("Project", "Project")=oProj
Main ()
End Sub