<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Quantity in assembly in Inventor Programming Forum</title>
    <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10723742#M44078</link>
    <description>&lt;P&gt;OK, so you have a drawing of a part, and you want to show on that drawing how many of this part are within these three other assembly's, right?&amp;nbsp; There are likely many ways to do this, but likely none of them are going to be as convenient as you would like, because its complicated to do manually, so that complication level is going to multiply when code gets is involved.&amp;nbsp; And code 'might' be the best automation tool here.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;First we have to get those quantities.&amp;nbsp; There are so many variables involved in this task, especially when the task is remote, it's hard to ask about them all.&amp;nbsp; In this code, I would need to uniquely identify these 3 assemblies we are going to search through, one way or another.&amp;nbsp; I'm just thinking in the most basic terms here and going to suggest manually entering (or cut/paste) those full file names into the start of the code.&amp;nbsp; Next we need to know what we are searching for within each of them.&amp;nbsp; There are many ways of identifying a component or part document within an assembly.&amp;nbsp; I'll just choose to use the full file name of the Part in my example below.&lt;/P&gt;
&lt;P&gt;This doesn't even try to use the BOM, or avoid content center stuff, it simply opens each listed assembly file, then searches through it for components that represent the Part file name specified, then adds 1 to the quantity for each one it finds.&lt;/P&gt;
&lt;LI-CODE lang="general"&gt;Sub Main
	Dim oAssemblyFiles As New List(Of String)
	oAssemblyFiles.Add("C:\Temp\Machine 1.iam")
	oAssemblyFiles.Add("C:\Temp\Machine 2.iam")
	oAssemblyFiles.Add("C:\Temp\Machine 3.iam")

	oPartFile = "C:\Temp\Part 5.ipt"

	'create a variable to hold the quantity
	Dim oQuantity As New List(Of Integer)

	For Each oName In oAssemblys
		Dim oAsmQuantity As Integer = 0
		Dim oADoc As AssemblyDocument
		If System.IO.File.Exists(oName) Then
			oADoc = ThisApplication.Documents.Open(oName, False)
		Else
			MsgBox("Could not find that file.  Skipping to next file name.", vbExclamation, "iLogic")
			Continue For
		End If
		If IsNothing(oADoc) Then Exit Sub
		oAllOccs = oADoc.ComponentDefinition.Occurrences
		
		'run our custom Sub routine below
		StepDown(oAllOccs, oPartFile, oAsmQuantity)
		
		oQuantity.Add(oAsmQuantity)
'		MsgBox("In this assembly:" &amp;amp; vbCrLf &amp;amp; oName &amp;amp; vbCrLf &amp;amp; _
'		"we found " &amp;amp; oAsmQuantity &amp;amp; " of the specified Part.", vbInformation, "iLogic")
	Next
	
	'now our oQuantity list should contain the quantities of the specified Part in each listed assembly
	For n As Integer = 1 To oAssemblyFiles.Count
		For q As Integer = 1 To oQuantity.Count
			MsgBox("In the assembly:" &amp;amp; vbCrLf &amp;amp; oAssemblyFiles.Item(n) &amp;amp; vbCrLf &amp;amp; _
			"we found " &amp;amp; oQuantity.Item(q) &amp;amp; " of the specified Part.", vbInformation, "iLogic")
		Next
	Next
End Sub

Sub StepDown(oComps As ComponentOccurrences, oPartName As String, ByRef oAsmQuantity As Integer)
	For Each oComp As ComponentOccurrence In oComps
		Try
			If oComp.Definition.Document.FullFileName = oPartName Then
				oAsmQuantity = oAsmQuantity + 1
			End If
		Catch
		End Try
		If TypeOf oComp.Definition Is AssemblyComponentDefinition Then
			StepDown(oComp.Definition.Occurrences, oPartName, oAsmQuantity)
		End If
	Next
End Sub&lt;/LI-CODE&gt;
&lt;P&gt;A more efficient process might have been to use something like the following:&lt;/P&gt;
&lt;LI-CODE lang="general"&gt;oComp = ComponentOccurrences.ItemByName("occurrenceName1:1")
oCount = ComponentOccurrences.AllLeafOccurrences(oComp).Count&lt;/LI-CODE&gt;
&lt;P&gt;, but that needs you to specify a component name, which is often undesirable since they are usually auto-renamed.&lt;/P&gt;
&lt;P&gt;You could have found the first component in the assembly of that Part, then used that component in that line, but that also involves a process which usually includes loops.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If this solved your problem, or answered your question, please click &lt;SPAN style="background-color: green; color: white;"&gt;&lt;STRONG&gt;ACCEPT SOLUTION&lt;/STRONG&gt;&lt;/SPAN&gt;.&lt;BR /&gt;Or, if this helped you, please click (LIKE or KUDOS) &lt;span class="lia-unicode-emoji" title=":thumbs_up:"&gt;👍&lt;/span&gt;.&lt;/P&gt;
&lt;P&gt;If you want and have time, I would appreciate your Vote(s) for &lt;A href="https://forums.autodesk.com/t5/forums/recentpostspage/post-type/message/interaction-style/idea/user-id/7812054/" target="_blank"&gt;My IDEAS &lt;/A&gt; &lt;span class="lia-unicode-emoji" title=":light_bulb:"&gt;💡&lt;/span&gt; or you can Explore &lt;A href="https://knowledge.autodesk.com/profile/LTSUSR7HXMSAE/articles" target="_blank"&gt;My CONTRIBUTIONS &lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 29 Oct 2021 18:53:52 GMT</pubDate>
    <dc:creator>WCrihfield</dc:creator>
    <dc:date>2021-10-29T18:53:52Z</dc:date>
    <item>
      <title>Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10722255#M44073</link>
      <description>&lt;P&gt;Hi !&lt;/P&gt;&lt;P&gt;I make 3 machines in Inventor.&lt;/P&gt;&lt;P&gt;The 3 machines have some pieces in common.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The file tree is like this :&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;- MACHINE1.iam&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- Subassembly1.iam (Common)&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- Part1.ipt&amp;nbsp; (Common)&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- Part2.ipt&amp;nbsp; (Common)&lt;/P&gt;&lt;P&gt;Part3.ipt&lt;/P&gt;&lt;P&gt;Part4.ipt&lt;/P&gt;&lt;P&gt;Part5.ipt&lt;/P&gt;&lt;P&gt;........&lt;/P&gt;&lt;P&gt;- MACHINE2.iam&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- Subassembly1.iam (Common)&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- Part1.ipt&amp;nbsp; (Common)&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- Part2.ipt&amp;nbsp; (Common)&lt;/P&gt;&lt;P&gt;Part4.ipt&lt;/P&gt;&lt;P&gt;Part5.ipt&lt;/P&gt;&lt;P&gt;Part6.ipt&lt;/P&gt;&lt;P&gt;........&lt;/P&gt;&lt;P&gt;- MACHINE3.iam&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- Subassembly1.iam (Common)&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- Part1.ipt&amp;nbsp; (Common)&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- Part2.ipt&amp;nbsp; (Common)&lt;/P&gt;&lt;P&gt;Part7.ipt&lt;/P&gt;&lt;P&gt;Part8.ipt&lt;/P&gt;&lt;P&gt;Part9.ipt&lt;/P&gt;&lt;P&gt;........&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;In the drawing of common parts i need to get the TOTAL (in the 3 machines) quantity of parts. Like this table for example :&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Machine 1 : 10x&lt;/P&gt;&lt;P&gt;Machine 2 : 0x&lt;/P&gt;&lt;P&gt;Machine 3 : 5x&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The goal : When the manufacturer have to build bart, they get the by machine, and the TOTAL quantity.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;How to manage this ?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thank you very much,&lt;/P&gt;&lt;P&gt;Best regards.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 29 Oct 2021 07:18:20 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10722255#M44073</guid>
      <dc:creator>inventor4578</dc:creator>
      <dc:date>2021-10-29T07:18:20Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10722525#M44074</link>
      <description>&lt;P&gt;You can use The "parts only" bom view from your top assembly. This will give you the total of component from all Assemblies and there sub assemblies. By setting the rigth BOM structure for each part or assembly you will get a correct component list.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here is some reference:&amp;nbsp;&lt;A href="https://knowledge.autodesk.com/support/inventor/learn-explore/caas/CloudHelp/cloudhelp/2022/ENU/Inventor-Help/files/GUID-A0A95805-CBF6-4524-8314-4AC8B53C19CF-htm.html" target="_blank"&gt;About the BOM Structure | Inventor 2022 | Autodesk Knowledge Network&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 29 Oct 2021 09:31:50 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10722525#M44074</guid>
      <dc:creator>theo.bot</dc:creator>
      <dc:date>2021-10-29T09:31:50Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10722561#M44075</link>
      <description>&lt;P&gt;Hi, thanks for reply.&lt;/P&gt;&lt;P&gt;Yes it can work, but i would like to have only the quantity of the part of the drawing (i have 1 drawing by 1 part).&lt;/P&gt;&lt;P&gt;And the quantity have to be attribute to each machine.&lt;/P&gt;</description>
      <pubDate>Fri, 29 Oct 2021 09:49:04 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10722561#M44075</guid>
      <dc:creator>inventor4578</dc:creator>
      <dc:date>2021-10-29T09:49:04Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10722615#M44076</link>
      <description>&lt;P&gt;I see, There is no direct way to get that info. So you simply need to store that machine and QTY info from the BOM view into a property or external source. On the drawing you can display that info into a table or any other text object. I would avoid this info on a drawing and store such info in PDM / ERP systems. To keep the data up to date on each drawing will be very hard.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 29 Oct 2021 10:21:19 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10722615#M44076</guid>
      <dc:creator>theo.bot</dc:creator>
      <dc:date>2021-10-29T10:21:19Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10723248#M44077</link>
      <description>&lt;P&gt;We do use total qty, but not very smart way.&amp;nbsp; Try this one, but remember Library parts can't be count as total qty.&lt;/P&gt;&lt;PRE&gt;&lt;SPAN&gt;Sub&lt;/SPAN&gt; &lt;SPAN&gt;Main&lt;/SPAN&gt;
&lt;SPAN&gt;'Get current document&lt;/SPAN&gt;
&lt;SPAN&gt;doc&lt;/SPAN&gt; = &lt;SPAN&gt;ThisDoc&lt;/SPAN&gt;.&lt;SPAN&gt;Document&lt;/SPAN&gt;
&lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;oAssyDef&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;AssemblyComponentDefinition&lt;/SPAN&gt; = &lt;SPAN&gt;doc&lt;/SPAN&gt;.&lt;SPAN&gt;ComponentDefinition&lt;/SPAN&gt;
&lt;SPAN&gt;'Get the BOM object&lt;/SPAN&gt;
&lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;oBOM&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;BOM&lt;/SPAN&gt; = &lt;SPAN&gt;oAssyDef&lt;/SPAN&gt;.&lt;SPAN&gt;BOM&lt;/SPAN&gt;
&lt;SPAN&gt;'enable the Parts Only View&lt;/SPAN&gt;
&lt;SPAN&gt;oBOM&lt;/SPAN&gt;.&lt;SPAN&gt;PartsOnlyViewEnabled&lt;/SPAN&gt; = &lt;SPAN&gt;True&lt;/SPAN&gt;
&lt;SPAN&gt;'Get the Parts Only view of the BOM&lt;/SPAN&gt;
&lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;oBOMViewPO&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;BOMView&lt;/SPAN&gt; = &lt;SPAN&gt;oBOM&lt;/SPAN&gt;.&lt;SPAN&gt;BOMViews&lt;/SPAN&gt;.&lt;SPAN&gt;Item&lt;/SPAN&gt;(&lt;SPAN&gt;"Parts Only"&lt;/SPAN&gt;)
&lt;SPAN&gt;'declare variable for each BOM row.&lt;/SPAN&gt;
&lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;oBOMRowPO&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;BOMRow&lt;/SPAN&gt;

&lt;SPAN&gt;'For each row in the Parts Only BOM, do the following&lt;/SPAN&gt;
&lt;SPAN&gt;For&lt;/SPAN&gt; &lt;SPAN&gt;Each&lt;/SPAN&gt; &lt;SPAN&gt;oBOMRowPO&lt;/SPAN&gt; &lt;SPAN&gt;In&lt;/SPAN&gt; &lt;SPAN&gt;oBOMViewPO&lt;/SPAN&gt;.&lt;SPAN&gt;BOMRows&lt;/SPAN&gt;
    &lt;SPAN&gt;'Set a reference to the primary ComponentDefinition of the row&lt;/SPAN&gt;
    &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;oCompDef&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;ComponentDefinition&lt;/SPAN&gt; = &lt;SPAN&gt;oBOMRowPO&lt;/SPAN&gt;.&lt;SPAN&gt;ComponentDefinitions&lt;/SPAN&gt;.&lt;SPAN&gt;Item&lt;/SPAN&gt;(1)
    
    &lt;SPAN&gt;'get the full filename associated to the component in the row. ex: c:\temp\part1.ipt&lt;/SPAN&gt;
    &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;CompFullDocumentName&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;String&lt;/SPAN&gt; = &lt;SPAN&gt;oCompDef&lt;/SPAN&gt;.&lt;SPAN&gt;Document&lt;/SPAN&gt;.&lt;SPAN&gt;FullDocumentName&lt;/SPAN&gt;
    &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;CompFileNameOnly&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;String&lt;/SPAN&gt;
    &lt;SPAN&gt;'get the location of the last backslash&lt;/SPAN&gt;
    &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;index&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;Integer&lt;/SPAN&gt; = &lt;SPAN&gt;CompFullDocumentName&lt;/SPAN&gt;.&lt;SPAN&gt;LastIndexOf&lt;/SPAN&gt;(&lt;SPAN&gt;"\"&lt;/SPAN&gt;)
    &lt;SPAN&gt;'get the filename only from the full filename&lt;/SPAN&gt;
    &lt;SPAN&gt;CompFileNameOnly&lt;/SPAN&gt; = &lt;SPAN&gt;CompFullDocumentName&lt;/SPAN&gt;.&lt;SPAN&gt;Substring&lt;/SPAN&gt;(&lt;SPAN&gt;index&lt;/SPAN&gt;+1)
    
    &lt;SPAN&gt;'MessageBox.Show(CompFileNameOnly)&lt;/SPAN&gt;
    
    &lt;SPAN&gt;'get the Qty value in the current row&lt;/SPAN&gt;
    &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;Qty&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;String&lt;/SPAN&gt; = &lt;SPAN&gt;oBOMRowPO&lt;/SPAN&gt;.&lt;SPAN&gt;TotalQuantity&lt;/SPAN&gt;
    
    &lt;SPAN&gt;'check to see if the component is a library part, cc part or read only.&lt;/SPAN&gt;
    &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;IsLibCCReadonly&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;Boolean&lt;/SPAN&gt; = &lt;SPAN&gt;LibCCReadonlyChecker&lt;/SPAN&gt;(&lt;SPAN&gt;CompFullDocumentName&lt;/SPAN&gt;)
    
    &lt;SPAN&gt;'if the file is NOT a library part, cc part or read only.&lt;/SPAN&gt;
    &lt;SPAN&gt;If&lt;/SPAN&gt; &lt;SPAN&gt;IsLibCCReadonly&lt;/SPAN&gt; = &lt;SPAN&gt;False&lt;/SPAN&gt; &lt;SPAN&gt;Then&lt;/SPAN&gt;
        &lt;SPAN&gt;'set following custom iproperty to equal the QTY from the row&lt;/SPAN&gt;
        &lt;SPAN&gt;iProperties&lt;/SPAN&gt;.&lt;SPAN&gt;Value&lt;/SPAN&gt;(&lt;SPAN&gt;CompFileNameOnly&lt;/SPAN&gt;, &lt;SPAN&gt;"Custom"&lt;/SPAN&gt;, &lt;SPAN&gt;"PartQty"&lt;/SPAN&gt;) = &lt;SPAN&gt;Qty&lt;/SPAN&gt;
    &lt;SPAN&gt;End&lt;/SPAN&gt; &lt;SPAN&gt;If&lt;/SPAN&gt;
&lt;SPAN&gt;Next&lt;/SPAN&gt;

&lt;SPAN&gt;'at this time, the qty value for all parts have been copied to the custom property.&lt;/SPAN&gt;
&lt;SPAN&gt;'next, the following code will cycle through only the subassemblies.&lt;/SPAN&gt;

&lt;SPAN&gt;'if the Structured BOM view is enabled then...&lt;/SPAN&gt;
&lt;SPAN&gt;If&lt;/SPAN&gt; &lt;SPAN&gt;oBOM&lt;/SPAN&gt;.&lt;SPAN&gt;StructuredViewEnabled&lt;/SPAN&gt; &lt;SPAN&gt;Then&lt;/SPAN&gt;
    &lt;SPAN&gt;'If show First Level is set then turn it off. This will set it to All Levels&lt;/SPAN&gt;
    &lt;SPAN&gt;If&lt;/SPAN&gt; &lt;SPAN&gt;oBOM&lt;/SPAN&gt;.&lt;SPAN&gt;StructuredViewFirstLevelOnly&lt;/SPAN&gt; &lt;SPAN&gt;Then&lt;/SPAN&gt;
        &lt;SPAN&gt;oBOM&lt;/SPAN&gt;.&lt;SPAN&gt;StructuredViewFirstLevelOnly&lt;/SPAN&gt; = &lt;SPAN&gt;False&lt;/SPAN&gt;
    &lt;SPAN&gt;End&lt;/SPAN&gt; &lt;SPAN&gt;If&lt;/SPAN&gt;
&lt;SPAN&gt;Else&lt;/SPAN&gt;
    &lt;SPAN&gt;'enable the Structured BOM view&lt;/SPAN&gt;
    &lt;SPAN&gt;oBOM&lt;/SPAN&gt;.&lt;SPAN&gt;StructuredViewEnabled&lt;/SPAN&gt; = &lt;SPAN&gt;True&lt;/SPAN&gt;
    &lt;SPAN&gt;'set the FirstLevelOnly to false therefore make it All Levels&lt;/SPAN&gt;
    &lt;SPAN&gt;oBOM&lt;/SPAN&gt;.&lt;SPAN&gt;StructuredViewFirstLevelOnly&lt;/SPAN&gt; = &lt;SPAN&gt;False&lt;/SPAN&gt;
&lt;SPAN&gt;End&lt;/SPAN&gt; &lt;SPAN&gt;If&lt;/SPAN&gt;

&lt;SPAN&gt;'Get the Structured view of the BOM&lt;/SPAN&gt;
&lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;oBOMViewStruc&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;BOMView&lt;/SPAN&gt; = &lt;SPAN&gt;oBOM&lt;/SPAN&gt;.&lt;SPAN&gt;BOMViews&lt;/SPAN&gt;.&lt;SPAN&gt;Item&lt;/SPAN&gt;(&lt;SPAN&gt;"Structured"&lt;/SPAN&gt;)
&lt;SPAN&gt;'declare variable for each BOM row.&lt;/SPAN&gt;
&lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;oBOMRowStruc&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;BOMRow&lt;/SPAN&gt;
&lt;SPAN&gt;'Create a blank array(list). This will be used to store a list of all subassemblies for comparing if the subassembly already exist.&lt;/SPAN&gt;
&lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;arrSubAssemblyList&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;New&lt;/SPAN&gt; &lt;SPAN&gt;ArrayList&lt;/SPAN&gt;

&lt;SPAN&gt;'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.&lt;/SPAN&gt;
&lt;SPAN&gt;Call&lt;/SPAN&gt; &lt;SPAN&gt;QueryBOMRowProperties&lt;/SPAN&gt;(&lt;SPAN&gt;oBOMViewStruc&lt;/SPAN&gt;.&lt;SPAN&gt;BOMRows&lt;/SPAN&gt;, &lt;SPAN&gt;arrSubAssemblyList&lt;/SPAN&gt;, 1)

&lt;SPAN&gt;End&lt;/SPAN&gt; &lt;SPAN&gt;Sub&lt;/SPAN&gt;

&lt;SPAN&gt;Private&lt;/SPAN&gt; &lt;SPAN&gt;Sub&lt;/SPAN&gt; &lt;SPAN&gt;QueryBOMRowProperties&lt;/SPAN&gt;(&lt;SPAN&gt;oBOMRows&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;BOMRowsEnumerator&lt;/SPAN&gt;, &lt;SPAN&gt;arrSubAssembly&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;ArrayList&lt;/SPAN&gt;, &lt;SPAN&gt;oParentQty&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;Integer&lt;/SPAN&gt;)

&lt;SPAN&gt;'declare a incrementer variable&lt;/SPAN&gt;
&lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;i&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;Long&lt;/SPAN&gt;
&lt;SPAN&gt;'for each row in the structured BOM&lt;/SPAN&gt;
&lt;SPAN&gt;For&lt;/SPAN&gt; &lt;SPAN&gt;i&lt;/SPAN&gt; = 1 &lt;SPAN&gt;To&lt;/SPAN&gt; &lt;SPAN&gt;oBOMRows&lt;/SPAN&gt;.&lt;SPAN&gt;Count&lt;/SPAN&gt;
    &lt;SPAN&gt;'get the row based on the incrementer&lt;/SPAN&gt;
    &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;oBOMRowStruc&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;BOMRow&lt;/SPAN&gt; = &lt;SPAN&gt;oBOMRows&lt;/SPAN&gt;.&lt;SPAN&gt;Item&lt;/SPAN&gt;(&lt;SPAN&gt;i&lt;/SPAN&gt;)
    &lt;SPAN&gt;'get the component definition assocated with the row&lt;/SPAN&gt;
    &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;oCompDef&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;ComponentDefinition&lt;/SPAN&gt; = &lt;SPAN&gt;oBOMRowStruc&lt;/SPAN&gt;.&lt;SPAN&gt;ComponentDefinitions&lt;/SPAN&gt;.&lt;SPAN&gt;Item&lt;/SPAN&gt;(1)
    &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;oQty&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;Integer&lt;/SPAN&gt;
    
    &lt;SPAN&gt;'If the component is an assembly and it's bom structure is Normal then do the following. else do nothing&lt;/SPAN&gt;
    &lt;SPAN&gt;If&lt;/SPAN&gt; &lt;SPAN&gt;TypeOf&lt;/SPAN&gt; &lt;SPAN&gt;oCompDef&lt;/SPAN&gt; &lt;SPAN&gt;Is&lt;/SPAN&gt; &lt;SPAN&gt;AssemblyComponentDefinition&lt;/SPAN&gt; &lt;SPAN&gt;And&lt;/SPAN&gt; &lt;SPAN&gt;oCompDef&lt;/SPAN&gt;.&lt;SPAN&gt;BOMStructure&lt;/SPAN&gt; = &lt;SPAN&gt;BOMStructureEnum&lt;/SPAN&gt;.&lt;SPAN&gt;kNormalBOMStructure&lt;/SPAN&gt; &lt;SPAN&gt;Then&lt;/SPAN&gt;
            &lt;SPAN&gt;'get the full filename associated to the component in the row. ex: c:\temp\subassembly.iam&lt;/SPAN&gt;
            &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;CompFullDocumentName&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;String&lt;/SPAN&gt; = &lt;SPAN&gt;oCompDef&lt;/SPAN&gt;.&lt;SPAN&gt;Document&lt;/SPAN&gt;.&lt;SPAN&gt;FullDocumentName&lt;/SPAN&gt;
            &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;CompFileNameOnly&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;String&lt;/SPAN&gt;
            &lt;SPAN&gt;'get the location of the last backslash&lt;/SPAN&gt;
            &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;index&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;Integer&lt;/SPAN&gt; = &lt;SPAN&gt;CompFullDocumentName&lt;/SPAN&gt;.&lt;SPAN&gt;LastIndexOf&lt;/SPAN&gt;(&lt;SPAN&gt;"\"&lt;/SPAN&gt;)
            &lt;SPAN&gt;'get the filename only from the full filename&lt;/SPAN&gt;
            &lt;SPAN&gt;CompFileNameOnly&lt;/SPAN&gt; = &lt;SPAN&gt;CompFullDocumentName&lt;/SPAN&gt;.&lt;SPAN&gt;Substring&lt;/SPAN&gt;(&lt;SPAN&gt;index&lt;/SPAN&gt;+1)
            &lt;SPAN&gt;'MessageBox.Show(CompFileNameOnly)&lt;/SPAN&gt;
            
            &lt;SPAN&gt;'get the qty of the row and multiply by the parent qty.&lt;/SPAN&gt;
            &lt;SPAN&gt;oQty&lt;/SPAN&gt; = &lt;SPAN&gt;oBOMRowStruc&lt;/SPAN&gt;.&lt;SPAN&gt;ItemQuantity&lt;/SPAN&gt; * &lt;SPAN&gt;oParentQty&lt;/SPAN&gt;
            
            &lt;SPAN&gt;'create a variable that will be used to get the qty of the subassembly if it was used elsewhere&lt;/SPAN&gt;
            &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;additionalQty&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;Integer&lt;/SPAN&gt; = 0
            &lt;SPAN&gt;'if the subassembly list is not empty then...&lt;/SPAN&gt;
            &lt;SPAN&gt;If&lt;/SPAN&gt; &lt;SPAN&gt;arrSubAssembly&lt;/SPAN&gt;.&lt;SPAN&gt;Count&lt;/SPAN&gt; &amp;lt;&amp;gt; 0 &lt;SPAN&gt;Then&lt;/SPAN&gt;
                &lt;SPAN&gt;'create a counter. this will be used to determine which item in the subassembly array (list) when it finds a match.&lt;/SPAN&gt;
                &lt;SPAN&gt;'this counter will be used to edit that item with the new qty.&lt;/SPAN&gt;
                &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;counter&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;Integer&lt;/SPAN&gt; = 0
                &lt;SPAN&gt;'for each item in the subassembly array (list) starting at 0 (first item) to last item&lt;/SPAN&gt;
                &lt;SPAN&gt;For&lt;/SPAN&gt; &lt;SPAN&gt;j&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;Integer&lt;/SPAN&gt; = 0 &lt;SPAN&gt;To&lt;/SPAN&gt; &lt;SPAN&gt;arrSubAssembly&lt;/SPAN&gt;.&lt;SPAN&gt;Count&lt;/SPAN&gt;-1
                    &lt;SPAN&gt;'get the location of the colon&lt;/SPAN&gt;
                    &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;commaindex&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;Integer&lt;/SPAN&gt; = &lt;SPAN&gt;arrSubAssembly&lt;/SPAN&gt;(&lt;SPAN&gt;j&lt;/SPAN&gt;).&lt;SPAN&gt;indexof&lt;/SPAN&gt;(&lt;SPAN&gt;":"&lt;/SPAN&gt;)
                    &lt;SPAN&gt;'get just the file name&lt;/SPAN&gt;
                    &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;CompName&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;String&lt;/SPAN&gt; = &lt;SPAN&gt;arrSubAssembly&lt;/SPAN&gt;(&lt;SPAN&gt;j&lt;/SPAN&gt;).&lt;SPAN&gt;substring&lt;/SPAN&gt;(0,&lt;SPAN&gt;commaindex&lt;/SPAN&gt;)
                    
                    &lt;SPAN&gt;'if the file name of the current row matches the current item in the subassembly array (list) then...&lt;/SPAN&gt;
                    &lt;SPAN&gt;If&lt;/SPAN&gt; &lt;SPAN&gt;CompName&lt;/SPAN&gt; = &lt;SPAN&gt;CompFileNameOnly&lt;/SPAN&gt; &lt;SPAN&gt;Then&lt;/SPAN&gt;
                        &lt;SPAN&gt;'set the additional qty to the qty found in the subassembly array (list)&lt;/SPAN&gt;
                        &lt;SPAN&gt;additionalQty&lt;/SPAN&gt; = &lt;SPAN&gt;arrSubAssembly&lt;/SPAN&gt;(&lt;SPAN&gt;j&lt;/SPAN&gt;).&lt;SPAN&gt;substring&lt;/SPAN&gt;(&lt;SPAN&gt;commaindex&lt;/SPAN&gt;+1)
                        &lt;SPAN&gt;'set the counter equal to the item in the subassembly array (list)&lt;/SPAN&gt;
                        &lt;SPAN&gt;counter&lt;/SPAN&gt; = &lt;SPAN&gt;j&lt;/SPAN&gt;
                        &lt;SPAN&gt;'since a match is found, we need to exit the for loop so that counter no longer increments.&lt;/SPAN&gt;
                        &lt;SPAN&gt;'so Set j To the number of items in the subassembly array. this will exit out the for loop.&lt;/SPAN&gt;
                        &lt;SPAN&gt;j&lt;/SPAN&gt; = &lt;SPAN&gt;arrSubAssembly&lt;/SPAN&gt;.&lt;SPAN&gt;Count&lt;/SPAN&gt;
                    &lt;SPAN&gt;Else&lt;/SPAN&gt;
                        &lt;SPAN&gt;'increase the counter&lt;/SPAN&gt;
                        &lt;SPAN&gt;counter&lt;/SPAN&gt; += 1
                    &lt;SPAN&gt;End&lt;/SPAN&gt; &lt;SPAN&gt;If&lt;/SPAN&gt;
                &lt;SPAN&gt;Next&lt;/SPAN&gt;
                
                &lt;SPAN&gt;'if additional qty was not changed then there was no match. It will be a new item in the subassembly array (list)&lt;/SPAN&gt;
                &lt;SPAN&gt;If&lt;/SPAN&gt; &lt;SPAN&gt;additionalQty&lt;/SPAN&gt; = 0 &lt;SPAN&gt;Then&lt;/SPAN&gt;
                    &lt;SPAN&gt;'add the subassambly to the subassembly array (list)&lt;/SPAN&gt;
                    &lt;SPAN&gt;arrSubAssembly&lt;/SPAN&gt;.&lt;SPAN&gt;Add&lt;/SPAN&gt;(&lt;SPAN&gt;CompFileNameOnly&lt;/SPAN&gt; &amp;amp; &lt;SPAN&gt;":"&lt;/SPAN&gt; &amp;amp; &lt;SPAN&gt;oQty&lt;/SPAN&gt;)
                &lt;SPAN&gt;Else&lt;/SPAN&gt;
                    &lt;SPAN&gt;'if it did find a match, then update the qty for that item in the subassembly array (list)&lt;/SPAN&gt;
                    &lt;SPAN&gt;arrSubAssembly&lt;/SPAN&gt;(&lt;SPAN&gt;counter&lt;/SPAN&gt;) = &lt;SPAN&gt;CompFileNameOnly&lt;/SPAN&gt; &amp;amp; &lt;SPAN&gt;":"&lt;/SPAN&gt; &amp;amp; &lt;SPAN&gt;oQty&lt;/SPAN&gt; + &lt;SPAN&gt;additionalQty&lt;/SPAN&gt;
                &lt;SPAN&gt;End&lt;/SPAN&gt; &lt;SPAN&gt;If&lt;/SPAN&gt;
            &lt;SPAN&gt;Else&lt;/SPAN&gt;
                &lt;SPAN&gt;'add the first subassembly to the list. It will add the filename and the qty separated by a colon. ex. subassembly.iam:2&lt;/SPAN&gt;
                &lt;SPAN&gt;arrSubAssembly&lt;/SPAN&gt;.&lt;SPAN&gt;Add&lt;/SPAN&gt;(&lt;SPAN&gt;CompFileNameOnly&lt;/SPAN&gt; &amp;amp; &lt;SPAN&gt;":"&lt;/SPAN&gt; &amp;amp; &lt;SPAN&gt;oQty&lt;/SPAN&gt;)
            &lt;SPAN&gt;End&lt;/SPAN&gt; &lt;SPAN&gt;If&lt;/SPAN&gt;
            
            &lt;SPAN&gt;'check to see if the component is a library part, cc part or read only.&lt;/SPAN&gt;
            &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;IsLibCCReadonly&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;Boolean&lt;/SPAN&gt; = &lt;SPAN&gt;LibCCReadonlyChecker&lt;/SPAN&gt;(&lt;SPAN&gt;CompFullDocumentName&lt;/SPAN&gt;)
            
            &lt;SPAN&gt;'if the file is NOT a library part, cc part or read only.&lt;/SPAN&gt;
            &lt;SPAN&gt;If&lt;/SPAN&gt; &lt;SPAN&gt;IsLibCCReadonly&lt;/SPAN&gt; = &lt;SPAN&gt;False&lt;/SPAN&gt; &lt;SPAN&gt;Then&lt;/SPAN&gt;
                &lt;SPAN&gt;'set following custom iproperty to equal the QTY from the row plus the additional qty value&lt;/SPAN&gt;
                &lt;SPAN&gt;iProperties&lt;/SPAN&gt;.&lt;SPAN&gt;Value&lt;/SPAN&gt;(&lt;SPAN&gt;CompFileNameOnly&lt;/SPAN&gt;, &lt;SPAN&gt;"Custom"&lt;/SPAN&gt;, &lt;SPAN&gt;"PartQty"&lt;/SPAN&gt;) = &lt;SPAN&gt;oQty&lt;/SPAN&gt; + &lt;SPAN&gt;additionalQty&lt;/SPAN&gt;
            
                &lt;SPAN&gt;'Recursively iterate child rows if present.&lt;/SPAN&gt;
                &lt;SPAN&gt;If&lt;/SPAN&gt; &lt;SPAN&gt;Not&lt;/SPAN&gt; &lt;SPAN&gt;oBOMRowStruc&lt;/SPAN&gt;.&lt;SPAN&gt;ChildRows&lt;/SPAN&gt; &lt;SPAN&gt;Is&lt;/SPAN&gt; &lt;SPAN&gt;Nothing&lt;/SPAN&gt; &lt;SPAN&gt;Then&lt;/SPAN&gt;
                    &lt;SPAN&gt;'recall the subroutine, push the childrows of the sub, sub assembly array (list), and the qty of the subassembly&lt;/SPAN&gt;
                    &lt;SPAN&gt;Call&lt;/SPAN&gt; &lt;SPAN&gt;QueryBOMRowProperties&lt;/SPAN&gt;(&lt;SPAN&gt;oBOMRowStruc&lt;/SPAN&gt;.&lt;SPAN&gt;ChildRows&lt;/SPAN&gt;, &lt;SPAN&gt;arrSubAssembly&lt;/SPAN&gt;, &lt;SPAN&gt;oQty&lt;/SPAN&gt;)
                &lt;SPAN&gt;End&lt;/SPAN&gt; &lt;SPAN&gt;If&lt;/SPAN&gt;
            &lt;SPAN&gt;End&lt;/SPAN&gt; &lt;SPAN&gt;If&lt;/SPAN&gt;
        &lt;SPAN&gt;End&lt;/SPAN&gt; &lt;SPAN&gt;If&lt;/SPAN&gt;
    &lt;SPAN&gt;Next&lt;/SPAN&gt;
&lt;SPAN&gt;End&lt;/SPAN&gt; &lt;SPAN&gt;Sub&lt;/SPAN&gt;

&lt;SPAN&gt;Private&lt;/SPAN&gt; &lt;SPAN&gt;Function&lt;/SPAN&gt; &lt;SPAN&gt;LibCCReadonlyChecker&lt;/SPAN&gt;(&lt;SPAN&gt;filename&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;String&lt;/SPAN&gt;) &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;Boolean&lt;/SPAN&gt;
&lt;SPAN&gt;' Get the active project&lt;/SPAN&gt;
&lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;oProject&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;DesignProject&lt;/SPAN&gt; = &lt;SPAN&gt;ThisApplication&lt;/SPAN&gt;.&lt;SPAN&gt;DesignProjectManager&lt;/SPAN&gt;.&lt;SPAN&gt;ActiveDesignProject&lt;/SPAN&gt;
&lt;SPAN&gt;' Get all the library paths&lt;/SPAN&gt;
&lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;oLibraryPaths&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;ProjectPaths&lt;/SPAN&gt; = &lt;SPAN&gt;oProject&lt;/SPAN&gt;.&lt;SPAN&gt;LibraryPaths&lt;/SPAN&gt;
&lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;oLibraryPath&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;ProjectPath&lt;/SPAN&gt;

&lt;SPAN&gt;'for each library path in the list of all library paths&lt;/SPAN&gt;
&lt;SPAN&gt;For&lt;/SPAN&gt; &lt;SPAN&gt;Each&lt;/SPAN&gt; &lt;SPAN&gt;oLibraryPath&lt;/SPAN&gt; &lt;SPAN&gt;In&lt;/SPAN&gt; &lt;SPAN&gt;oLibraryPaths&lt;/SPAN&gt;
    &lt;SPAN&gt;'get the library path&lt;/SPAN&gt;
    &lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;oLibs&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;String&lt;/SPAN&gt; = &lt;SPAN&gt;oLibraryPath&lt;/SPAN&gt;.&lt;SPAN&gt;Path&lt;/SPAN&gt;
    &lt;SPAN&gt;'if the file is in a library path then Return True&lt;/SPAN&gt;
    &lt;SPAN&gt;If&lt;/SPAN&gt; &lt;SPAN&gt;filename&lt;/SPAN&gt;.&lt;SPAN&gt;Contains&lt;/SPAN&gt;(&lt;SPAN&gt;oLibs&lt;/SPAN&gt;) = &lt;SPAN&gt;True&lt;/SPAN&gt; &lt;SPAN&gt;Then&lt;/SPAN&gt;
        &lt;SPAN&gt;Return&lt;/SPAN&gt; &lt;SPAN&gt;True&lt;/SPAN&gt;
    &lt;SPAN&gt;End&lt;/SPAN&gt; &lt;SPAN&gt;If&lt;/SPAN&gt;
&lt;SPAN&gt;Next&lt;/SPAN&gt;

&lt;SPAN&gt;'if the file is in the CC location then Return True&lt;/SPAN&gt;
&lt;SPAN&gt;If&lt;/SPAN&gt; &lt;SPAN&gt;filename&lt;/SPAN&gt;.&lt;SPAN&gt;Contains&lt;/SPAN&gt;(&lt;SPAN&gt;oProject&lt;/SPAN&gt;.&lt;SPAN&gt;ContentCenterPath&lt;/SPAN&gt;) = &lt;SPAN&gt;True&lt;/SPAN&gt; &lt;SPAN&gt;Then&lt;/SPAN&gt;
    &lt;SPAN&gt;Return&lt;/SPAN&gt; &lt;SPAN&gt;True&lt;/SPAN&gt;
&lt;SPAN&gt;End&lt;/SPAN&gt; &lt;SPAN&gt;If&lt;/SPAN&gt;

&lt;SPAN&gt;'get read only status&lt;/SPAN&gt;
&lt;SPAN&gt;Dim&lt;/SPAN&gt; &lt;SPAN&gt;File_Attr&lt;/SPAN&gt; &lt;SPAN&gt;As&lt;/SPAN&gt; &lt;SPAN&gt;Long&lt;/SPAN&gt; = &lt;SPAN&gt;System&lt;/SPAN&gt;.&lt;SPAN&gt;IO&lt;/SPAN&gt;.&lt;SPAN&gt;File&lt;/SPAN&gt;.&lt;SPAN&gt;GetAttributes&lt;/SPAN&gt;(&lt;SPAN&gt;filename&lt;/SPAN&gt;)
&lt;SPAN&gt;'if the file is readonly or readonly and archieve then Return True&lt;/SPAN&gt;
&lt;SPAN&gt;If&lt;/SPAN&gt; &lt;SPAN&gt;File_Attr&lt;/SPAN&gt; = 1 &lt;SPAN&gt;Or&lt;/SPAN&gt; &lt;SPAN&gt;File_Attr&lt;/SPAN&gt; = 33 &lt;SPAN&gt;Then&lt;/SPAN&gt;
    &lt;SPAN&gt;Return&lt;/SPAN&gt; &lt;SPAN&gt;True&lt;/SPAN&gt;
&lt;SPAN&gt;End&lt;/SPAN&gt; &lt;SPAN&gt;If&lt;/SPAN&gt;

&lt;SPAN&gt;'return False if it's not a library, CC or a Readonly part.&lt;/SPAN&gt;
&lt;SPAN&gt;Return&lt;/SPAN&gt; &lt;SPAN&gt;False&lt;/SPAN&gt;

&lt;SPAN&gt;End&lt;/SPAN&gt; &lt;SPAN&gt;Function&lt;/SPAN&gt;

&lt;/PRE&gt;</description>
      <pubDate>Fri, 29 Oct 2021 15:01:28 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10723248#M44077</guid>
      <dc:creator>GosponZ</dc:creator>
      <dc:date>2021-10-29T15:01:28Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10723742#M44078</link>
      <description>&lt;P&gt;OK, so you have a drawing of a part, and you want to show on that drawing how many of this part are within these three other assembly's, right?&amp;nbsp; There are likely many ways to do this, but likely none of them are going to be as convenient as you would like, because its complicated to do manually, so that complication level is going to multiply when code gets is involved.&amp;nbsp; And code 'might' be the best automation tool here.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;First we have to get those quantities.&amp;nbsp; There are so many variables involved in this task, especially when the task is remote, it's hard to ask about them all.&amp;nbsp; In this code, I would need to uniquely identify these 3 assemblies we are going to search through, one way or another.&amp;nbsp; I'm just thinking in the most basic terms here and going to suggest manually entering (or cut/paste) those full file names into the start of the code.&amp;nbsp; Next we need to know what we are searching for within each of them.&amp;nbsp; There are many ways of identifying a component or part document within an assembly.&amp;nbsp; I'll just choose to use the full file name of the Part in my example below.&lt;/P&gt;
&lt;P&gt;This doesn't even try to use the BOM, or avoid content center stuff, it simply opens each listed assembly file, then searches through it for components that represent the Part file name specified, then adds 1 to the quantity for each one it finds.&lt;/P&gt;
&lt;LI-CODE lang="general"&gt;Sub Main
	Dim oAssemblyFiles As New List(Of String)
	oAssemblyFiles.Add("C:\Temp\Machine 1.iam")
	oAssemblyFiles.Add("C:\Temp\Machine 2.iam")
	oAssemblyFiles.Add("C:\Temp\Machine 3.iam")

	oPartFile = "C:\Temp\Part 5.ipt"

	'create a variable to hold the quantity
	Dim oQuantity As New List(Of Integer)

	For Each oName In oAssemblys
		Dim oAsmQuantity As Integer = 0
		Dim oADoc As AssemblyDocument
		If System.IO.File.Exists(oName) Then
			oADoc = ThisApplication.Documents.Open(oName, False)
		Else
			MsgBox("Could not find that file.  Skipping to next file name.", vbExclamation, "iLogic")
			Continue For
		End If
		If IsNothing(oADoc) Then Exit Sub
		oAllOccs = oADoc.ComponentDefinition.Occurrences
		
		'run our custom Sub routine below
		StepDown(oAllOccs, oPartFile, oAsmQuantity)
		
		oQuantity.Add(oAsmQuantity)
'		MsgBox("In this assembly:" &amp;amp; vbCrLf &amp;amp; oName &amp;amp; vbCrLf &amp;amp; _
'		"we found " &amp;amp; oAsmQuantity &amp;amp; " of the specified Part.", vbInformation, "iLogic")
	Next
	
	'now our oQuantity list should contain the quantities of the specified Part in each listed assembly
	For n As Integer = 1 To oAssemblyFiles.Count
		For q As Integer = 1 To oQuantity.Count
			MsgBox("In the assembly:" &amp;amp; vbCrLf &amp;amp; oAssemblyFiles.Item(n) &amp;amp; vbCrLf &amp;amp; _
			"we found " &amp;amp; oQuantity.Item(q) &amp;amp; " of the specified Part.", vbInformation, "iLogic")
		Next
	Next
End Sub

Sub StepDown(oComps As ComponentOccurrences, oPartName As String, ByRef oAsmQuantity As Integer)
	For Each oComp As ComponentOccurrence In oComps
		Try
			If oComp.Definition.Document.FullFileName = oPartName Then
				oAsmQuantity = oAsmQuantity + 1
			End If
		Catch
		End Try
		If TypeOf oComp.Definition Is AssemblyComponentDefinition Then
			StepDown(oComp.Definition.Occurrences, oPartName, oAsmQuantity)
		End If
	Next
End Sub&lt;/LI-CODE&gt;
&lt;P&gt;A more efficient process might have been to use something like the following:&lt;/P&gt;
&lt;LI-CODE lang="general"&gt;oComp = ComponentOccurrences.ItemByName("occurrenceName1:1")
oCount = ComponentOccurrences.AllLeafOccurrences(oComp).Count&lt;/LI-CODE&gt;
&lt;P&gt;, but that needs you to specify a component name, which is often undesirable since they are usually auto-renamed.&lt;/P&gt;
&lt;P&gt;You could have found the first component in the assembly of that Part, then used that component in that line, but that also involves a process which usually includes loops.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If this solved your problem, or answered your question, please click &lt;SPAN style="background-color: green; color: white;"&gt;&lt;STRONG&gt;ACCEPT SOLUTION&lt;/STRONG&gt;&lt;/SPAN&gt;.&lt;BR /&gt;Or, if this helped you, please click (LIKE or KUDOS) &lt;span class="lia-unicode-emoji" title=":thumbs_up:"&gt;👍&lt;/span&gt;.&lt;/P&gt;
&lt;P&gt;If you want and have time, I would appreciate your Vote(s) for &lt;A href="https://forums.autodesk.com/t5/forums/recentpostspage/post-type/message/interaction-style/idea/user-id/7812054/" target="_blank"&gt;My IDEAS &lt;/A&gt; &lt;span class="lia-unicode-emoji" title=":light_bulb:"&gt;💡&lt;/span&gt; or you can Explore &lt;A href="https://knowledge.autodesk.com/profile/LTSUSR7HXMSAE/articles" target="_blank"&gt;My CONTRIBUTIONS &lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 29 Oct 2021 18:53:52 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10723742#M44078</guid>
      <dc:creator>WCrihfield</dc:creator>
      <dc:date>2021-10-29T18:53:52Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10723772#M44079</link>
      <description>&lt;P&gt;Guys,&lt;/P&gt;&lt;P&gt;Can I hijack this thread for a second?&lt;BR /&gt;Can you show me the code that finds the BOM 'total quantity' of FrameGenerator parts?&lt;/P&gt;&lt;P&gt;I've tried to do that but can't figure out how to get my rule to see that iProperty from the top-level assembly.&lt;/P&gt;&lt;P&gt;It can see custom parts, but not ContentCenter parts.&lt;/P&gt;&lt;P&gt;Thanx...&lt;/P&gt;</description>
      <pubDate>Fri, 29 Oct 2021 19:04:33 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10723772#M44079</guid>
      <dc:creator>cadman777</dc:creator>
      <dc:date>2021-10-29T19:04:33Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10725425#M44080</link>
      <description>&lt;P&gt;&lt;A href="https://forums.autodesk.com/t5/inventor-ilogic-api-vba-forum/ilogic-to-identify-if-component-was-created-by-frame-generator/td-p/9448636" target="_blank" rel="noopener"&gt;Here&lt;/A&gt; is a post in how to identify a &lt;SPAN&gt;document is referenced to&amp;nbsp;&lt;/SPAN&gt;frame generator addin. It uses the has interest method. If you look in the API help you will see other add ins reference there also. I would suggest starting a new thread as it would be different to this threads objective.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sat, 30 Oct 2021 22:05:50 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10725425#M44080</guid>
      <dc:creator>A.Acheson</dc:creator>
      <dc:date>2021-10-30T22:05:50Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10725509#M44081</link>
      <description>&lt;P&gt;Thanx Alan, appreciate it. That looks like it may make life easier for this rule. Also, Joel has a rule that changes the BaseUnit in FG parts, which is something I've been wanting to do. So I got 2 solutions in 1 from that forum thread!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I also figured out that the way my rule is presently written, it looks at the DisplayName instead of the 'Part Number'.&amp;nbsp; So I'm going to change that and see how the rule runs. Maybe that'll fix it.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Little by little I'm learning how to do this.&lt;/P&gt;&lt;P&gt;It's noway as easy to do as Grasshopper's&amp;nbsp;VisualMacro system, but at least I'm getting the hang of it.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Cheers...&lt;/P&gt;</description>
      <pubDate>Sun, 31 Oct 2021 00:04:06 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10725509#M44081</guid>
      <dc:creator>cadman777</dc:creator>
      <dc:date>2021-10-31T00:04:06Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10727550#M44082</link>
      <description>I've got this error :&lt;BR /&gt;&lt;BR /&gt;Error in rule: count, in document: ASSY1.iam&lt;BR /&gt;Object reference not set to an instance of an object.</description>
      <pubDate>Mon, 01 Nov 2021 10:59:40 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10727550#M44082</guid>
      <dc:creator>inventor4578</dc:creator>
      <dc:date>2021-11-01T10:59:40Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10727796#M44083</link>
      <description>&lt;P&gt;I think I see the problem.&amp;nbsp; I changed the name of the variable at the start of the code, for the list of assembly names, from "oAssemblys" to "oAssemblyFiles", then forgot to copy that changed variable name down to the line of code where it is being used to start the main loop.&amp;nbsp; This line of code, near the top:&lt;/P&gt;
&lt;LI-CODE lang="general"&gt;For Each oName In oAssemblys&lt;/LI-CODE&gt;
&lt;P&gt;needed to be updated/changed to this:&lt;/P&gt;
&lt;LI-CODE lang="general"&gt;For Each oName In oAssemblyFiles&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;But, apparently I did remember to copy it down into 2 places within the final report messages loop, after the main loop.&lt;/P&gt;
&lt;P&gt;See if that fixes the rule for you.&lt;/P&gt;
&lt;P&gt;Also, if you would rather find &amp;amp;/or identify these assemblies &amp;amp; parts differently, just be as detailed as possible about the specific needs/requirements/wants of the task, because code generally needs to be very specific to work.&lt;/P&gt;</description>
      <pubDate>Mon, 01 Nov 2021 12:57:14 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10727796#M44083</guid>
      <dc:creator>WCrihfield</dc:creator>
      <dc:date>2021-11-01T12:57:14Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10727855#M44084</link>
      <description>Hi !&lt;BR /&gt;It run now !&lt;BR /&gt;The result : It count only 2 of the 3 assembly.&lt;BR /&gt;The resultat of the 2 have mistake, because it show always "In the assembly ASSY.iam" for all counting (Always it show the same assembly path but the count is good). It is just a presentation error in text i think.&lt;BR /&gt;&lt;BR /&gt;The error for the last assembly :&lt;BR /&gt;&lt;BR /&gt;"Error in rule: count, in document: ASSY2.iam&lt;BR /&gt;&lt;BR /&gt;Index was out of range. Must be non-negative and less than the size of the collection.&lt;BR /&gt;Parameter name: index"&lt;BR /&gt;</description>
      <pubDate>Mon, 01 Nov 2021 13:22:16 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10727855#M44084</guid>
      <dc:creator>inventor4578</dc:creator>
      <dc:date>2021-11-01T13:22:16Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10728158#M44085</link>
      <description>&lt;P&gt;OK.&amp;nbsp; The 2 tiered loop at the end, just for reporting the results, apparently wasn't counting up each time, because I forgot to add 1 to the counter after each loop.&amp;nbsp; I also did not include any feedback in the Catch part of the Try...Catch block where it is trying to check the Component.Definition.Document.FullFileName against the specified part file name, so if it was failing, it was just continuing without adding any quantity and without any explanation.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I changed the regular List object at the beginning to a Dictionary object, so that each item within can hold 2 things, instead of just one, and each pair will be linked together.&amp;nbsp; (Might have been able to use a NameValueMap here instead, but they can be odd to work with.)&amp;nbsp; The 'Key' of each entry/pair in the dictionary is the full file name of an assembly to be searched.&amp;nbsp; The Value of each entry/pair will represent the quantity of the part we find in that assembly.&amp;nbsp; The Value is initially set to 0 (zero).&amp;nbsp; Then I use a single loop at the end to report the individual resulting quantity for each assembly, with that assembly's name in the message.&amp;nbsp; Instead of this loop showing a message 3 times, we could also write all 3 results to a single String message, then show that one message at the end, if that would work better for you.&amp;nbsp; Then within that custom Sub routine, I got rid of the Try...Catch block, and just used a couple more logical steps with If...Then statements to handle the count/quantity task.&amp;nbsp; I also added some extra comment lines in there, since I changed the code, to help you follow what's going on.&amp;nbsp; I hope these changes fix the problems you were having.&lt;/P&gt;
&lt;P&gt;Here's the new code:&lt;/P&gt;
&lt;LI-CODE lang="general"&gt;Sub Main
	'specify full file name (path, file name, &amp;amp; file extension)
	'of the Part file to find within these assemblies
	oPartFile = "C:\Temp\Part 5.ipt"
	
	'list of name - value pairs
	'name = assembly full file name (path, name, &amp;amp; file extension)
	'value = 0 (zero) to start, will be filled in by quantity of the part found within
	Dim oPairs As New Dictionary(Of String, Integer)
	oPairs.Add("C:\Temp\Machine 1.iam", 0)
	oPairs.Add("C:\Temp\Machine 2.iam", 0)
	oPairs.Add("C:\Temp\Machine 3.iam", 0)
	
	For Each oPair As KeyValuePair(Of String, Integer) In oPairs
		'create a variable to represent this AssemblyDocument
		Dim oADoc As AssemblyDocument
		
		'make sure this file can be found
		If System.IO.File.Exists(oPair.Key) Then
			'it was found, so try to open it invisibly (in the background)
			oADoc = ThisApplication.Documents.Open(oPair.Key, False)
		Else
			'it was not found, so notify user then skip to next assembly file name
			MsgBox("Could not find that file.  Skipping to next file name.", vbExclamation, "iLogic")
			Continue For 'this skips to next item in loop
		End If
		'double check that we have now assigned a value to this variable
		If IsNothing(oADoc) Then Exit Sub
			
		'get this assembly's ComponentOccurrences so we can loop through them
		oAllOccs = oADoc.ComponentDefinition.Occurrences
		
		'create a quantity variable to pass to our custom Sub routine
		Dim oQty As Integer = 0
		
		'run our custom Sub routine below
		StepDown(oAllOccs, oPartFile, oQty)
		
		'set the returned quantity to our oPair's Value
		'oPair.Value = oQty 'won't work, because Value is ReadOnly
		oPairs.Item(oPair.Key) = oQty 'this will work, not read only
		
'		MsgBox("In this assembly:" &amp;amp; vbCrLf &amp;amp; oPair.Key &amp;amp; vbCrLf &amp;amp; _
'		"we found " &amp;amp; oPair.Value &amp;amp; " of the specified Part.", vbInformation, "iLogic")
	Next
	
	'now our oQuantity list should contain the quantities of the specified Part in each listed assembly
	For Each oPair As KeyValuePair(Of String, Integer) In oPairs
		MsgBox("The following assembly file:" &amp;amp; vbCrLf &amp;amp; _
		oPair.Key &amp;amp; vbCrLf &amp;amp; _
		"Contained the following quantity of components representing the specified part:" &amp;amp; vbCrLf &amp;amp; _
		oPair.Value, vbInformation, "iLogic")
	Next
End Sub

Sub StepDown(oComps As ComponentOccurrences, oPartName As String, ByRef oQty As Integer)
	For Each oComp As ComponentOccurrence In oComps
		If oComp.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then
			Dim oPDoc As PartDocument = oComp.Definition.Document
			If oPDoc.FullFileName = oPartName Then
				oQty = oQty + 1
			End If
		End If
		If TypeOf oComp.Definition Is AssemblyComponentDefinition Then
			StepDown(oComp.Definition.Occurrences, oPartName, oQty)
		End If
	Next
End Sub&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 01 Nov 2021 15:25:31 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10728158#M44085</guid>
      <dc:creator>WCrihfield</dc:creator>
      <dc:date>2021-11-01T15:25:31Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10729539#M44086</link>
      <description>&lt;P&gt;Hi, and thank you for reply!&lt;BR /&gt;Now i've got this error :&lt;BR /&gt;&lt;BR /&gt;Error Message :&lt;BR /&gt;&lt;EM&gt;"Error in rule: count, in document: PART_TEST.ipt&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;Collection was modified; enumeration operation may not execute."&lt;/EM&gt;&lt;BR /&gt;&lt;BR /&gt;More info:&lt;BR /&gt;&lt;EM&gt;System.InvalidOperationException: Collection was modified; enumeration operation may not execute.&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;at System.Collections.Generic.Dictionary`2.Enumerator.MoveNext()&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;at LmiRuleScript.Main()&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;at Autodesk.iLogic.Exec.AppDomExec.ExecRuleInAssembly(Assembly assem)&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;at iLogic.RuleEvalContainer.ExecRuleEval(String execRule)&lt;/EM&gt;&lt;/P&gt;</description>
      <pubDate>Tue, 02 Nov 2021 06:44:06 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10729539#M44086</guid>
      <dc:creator>inventor4578</dc:creator>
      <dc:date>2021-11-02T06:44:06Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10730174#M44087</link>
      <description>&lt;P&gt;Since I don't have any use for this code myself, and didn't have a file set to test it on, so I haven't been testing the codes locally, which often leads to unforeseen errors.&amp;nbsp; So...this time I created a folder, created three new assembly files with varying quantities of a certain test part file in them, and recorded the full file names of the part and all three assemblies to use in a local test scenario.&amp;nbsp; The previous code did not like the one line where I changed the value of the key/value pair while looping through the dictionary.&amp;nbsp; This behavior seemed to restrictive, so I switched to using a NameValueMap instead, to store the names and quantities, which then worked in my tests without any errors.&amp;nbsp; However, to simplify I then switched back to using a regular List again, then decided to record a 'Report' String as I loop through the three assemblies to keep a running tab on the findings as it progresses, instead of using another loop at the end to re-assemble the data, and this works out much smoother and simpler.&amp;nbsp; I also included a couple of important lines of code, that I couldn't believe I left out before...lines to dismiss those assembly documents after opening and inspecting them.&amp;nbsp; I also switched my custom reference routine from a Sub to a Function, because that better matches what we are using it for (to Return data).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here is the new version of the code that was working flawlessly for me in my tests.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="general"&gt;Sub Main
	'specify full file name (path, file name, &amp;amp; file extension)
	'of the Part file to find within these assemblies
	oPartFile = "C:\Temp\Part 5.ipt"
	
	'list of assembly full file names (path, name, &amp;amp; file extension)
	Dim oAsmFiles As New List(Of String)
	oAsmFiles.Add("C:\Temp\Machine 1.iam")
	oAsmFiles.Add("C:\Temp\Machine 2.iam")
	oAsmFiles.Add("C:\Temp\Machine 3.iam")
	
	Dim oReport As String
	Dim oTotalQty As Integer = 0
	For Each oAsmFile In oAsmFiles
		Dim oADoc As AssemblyDocument
		If System.IO.File.Exists(oAsmFile) Then
			oADoc = ThisApplication.Documents.Open(oAsmFile, False)
		Else
			MsgBox("Could not find that file.  Skipping to next file name.", vbExclamation, "iLogic")
			Continue For 'skips to next oAsmFile
		End If
		If IsNothing(oADoc) Then Exit Sub
		oAllOccs = oADoc.ComponentDefinition.Occurrences
		Dim oQty As Integer = StepDown(oAllOccs, oPartFile)
		oTotalQty = oTotalQty + oQty
		oReport = oReport &amp;amp; "Assembly:  " &amp;amp; oAsmFile &amp;amp; vbCrLf &amp;amp; "Quantity:  " &amp;amp; oQty &amp;amp; vbCrLf &amp;amp; vbCrLf
		'releases the reference to those invisibly opened documents so they can be cleaned up
		oADoc.ReleaseReference
		'oADoc.Close(True)
	Next
	ThisApplication.Documents.CloseAll(True) 'True = only close unreferenced documents
	oReport = oReport &amp;amp; "Total Quantity:  " &amp;amp; oTotalQty
	MsgBox(oReport, vbInformation, "iLogic")
End Sub

Function StepDown(oComps As ComponentOccurrences, oPartName As String) As Integer
	Dim oQuantity As Integer = 0
	For Each oComp As ComponentOccurrence In oComps
		If oComp.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then
			Dim oPDoc As PartDocument = oComp.Definition.Document
			If oPDoc.FullFileName = oPartName Then
				oQuantity = oQuantity + 1
			End If
		End If
		If TypeOf oComp.Definition Is AssemblyComponentDefinition Then
			oQuantity = oQuantity + StepDown(oComp.Definition.Occurrences, oPartName)
		End If
	Next
	Return oQuantity
End Function&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 02 Nov 2021 12:48:46 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10730174#M44087</guid>
      <dc:creator>WCrihfield</dc:creator>
      <dc:date>2021-11-02T12:48:46Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10730208#M44088</link>
      <description>&lt;P&gt;It's working great ! Amazing.&lt;/P&gt;&lt;P&gt;Is it possible to add factor for counting ?&lt;/P&gt;&lt;P&gt;If i have 5 machine 1 / 7 machine 2 and 3 machine 3 for example ?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thank you very much again!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 02 Nov 2021 12:58:44 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10730208#M44088</guid>
      <dc:creator>inventor4578</dc:creator>
      <dc:date>2021-11-02T12:58:44Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10730718#M44089</link>
      <description>&lt;P&gt;The short answer most likely, yes.&amp;nbsp; How difficult/complicated making those changes to the code will be depends on how &amp;amp; when you want to specify/supply those multiplication factors, and how you want the end result to be presented.&amp;nbsp; The multiplication factor will need to be somehow kept together with the assembly it was meant for from beginning to end, so it will likely mean using more multi-value type variables to hold the related bits of data together.&lt;/P&gt;
&lt;P&gt;So far this code doesn't seem very user friendly to me yet, because it is not usually a good situation when you have to manually edit the rule before every time you want to run it.&amp;nbsp; If needed, we may incorporate better user interaction tools to help avoid the need to edit the code each time.&amp;nbsp; Things like a file dialog to select the part or assembly files, and/or getting the part from an active drawing of the part and/or using some InputBox or InputListBox type routines, or using an Excel sheet, etc.&lt;/P&gt;</description>
      <pubDate>Tue, 02 Nov 2021 16:45:18 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10730718#M44089</guid>
      <dc:creator>WCrihfield</dc:creator>
      <dc:date>2021-11-02T16:45:18Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10734628#M44090</link>
      <description>&lt;P&gt;Ok thank you very much.&lt;/P&gt;&lt;P&gt;Can be great in the code, like this :&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;EM&gt;Dim oAsmFiles As New List(Of String)&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;oAsmFiles.Add("MACHINE1.iam") * 10&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;oAsmFiles.Add("MACHINE2.iam") * 5&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;oAsmFiles.Add("MACHINE3.iam") * 3 &lt;/EM&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 04 Nov 2021 07:17:28 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10734628#M44090</guid>
      <dc:creator>inventor4578</dc:creator>
      <dc:date>2021-11-04T07:17:28Z</dc:date>
    </item>
    <item>
      <title>Re: Quantity in assembly</title>
      <link>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10735619#M44091</link>
      <description>&lt;P&gt;OK.&amp;nbsp; I think I have something that will work that way for you that way.&amp;nbsp; I chose to use a NameValueMap this time, so I could store the order quantity multiplier with the assembly it is meant for.&amp;nbsp; Then I also incorporated a few InputBox functions to make the data entry/edit changes quicker &amp;amp; easier, without having to directly edit the rule code itself.&amp;nbsp; It uses a Do...Loop type of loop, that will exit the loop when you enter an empty assembly name and/or an empty order quantity.&amp;nbsp; This allows you to enter as many assemblies and order quantities as you want.&amp;nbsp; I tested this on my sample files and it worked as expected, so I hope it also work for you.&lt;/P&gt;
&lt;P&gt;Here is the updated code:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="general"&gt;Sub Main
	'get Part file name from user
	oPartFile = InputBox("Enter the 'Full File Name' (path, name, &amp;amp; file extension)" &amp;amp; vbCrLf &amp;amp; _
	"of the Part file you want to find the quantity of within multiple assemblies.", "Part File To Find", "")
	If String.IsNullOrEmpty(oPartFile) Then Exit Sub 'nothing was entered, so exit rule 
	
	'NameValueMap to hold Name/Value pairs (Assembly file name, order quantity)
	Dim oAsmFiles As NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap
	
	Dim oEmpty As Boolean = False
	Do Until oEmpty = True
		'get assembly file name from user
		oFileName = InputBox("Enter the 'Full File Name' (path, name, &amp;amp; file extension)" &amp;amp; vbCrLf &amp;amp; _
		"of an Assembly file you want to search for the part within.", "Assembly File To Search Within", "")
		'get order quantity from user
		oNum = InputBox("Enter 'Order Quantity' for that Assembly.", "Order Quantity", "1")
		'check returned values, to make sure not empty
		If String.IsNullOrEmpty(oFileName) Or String.IsNullOrEmpty(oNum) Then
			oEmpty = True
		Else
			oAsmFiles.Add(oFileName, CInt(oNum))
		End If
	Loop
	
	Dim oReport As String
	Dim oTotalQty As Integer = 0
	Dim i As Integer = 1 'for looping through NameValueMap
	For Each oItem In oAsmFiles 'oItem Type should not be defined, simply a placeholder here
		oAsmFile = oAsmFiles.Name(i)
		Dim oOrderQuantity As Integer = oAsmFiles.Value(oAsmFiles.Name(i))
		Dim oADoc As AssemblyDocument
		If System.IO.File.Exists(oAsmFile) Then
			oADoc = ThisApplication.Documents.Open(oAsmFile, False)
		Else
			MsgBox("Could not find that file.  Skipping to next file name.", vbExclamation, "iLogic")
			Continue For 'skips to next oAsmFile
		End If
		If IsNothing(oADoc) Then Exit Sub
		oAllOccs = oADoc.ComponentDefinition.Occurrences
		Dim oQty As Integer = (StepDown(oAllOccs, oPartFile) * oOrderQuantity)
		oTotalQty = oTotalQty + oQty
		oReport = oReport &amp;amp; "Assembly:  " &amp;amp; oAsmFile &amp;amp; vbCrLf &amp;amp; "Quantity:  " &amp;amp; oQty &amp;amp; vbCrLf &amp;amp; vbCrLf
		'releases the reference to those invisibly opened documents so they can be cleaned up
		oADoc.ReleaseReference
		'oADoc.Close(True)
		i = i + 1
	Next
	ThisApplication.Documents.CloseAll(True) 'True = only close unreferenced documents
	oReport = oReport &amp;amp; "Total Quantity:  " &amp;amp; oTotalQty
	MsgBox(oReport, vbInformation, "iLogic")
End Sub

Function StepDown(oComps As ComponentOccurrences, oPartName As String) As Integer
	Dim oQuantity As Integer = 0
	For Each oComp As ComponentOccurrence In oComps
		If oComp.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then
			Dim oPDoc As PartDocument = oComp.Definition.Document
			If oPDoc.FullFileName = oPartName Then
				oQuantity = oQuantity + 1
			End If
		End If
		If TypeOf oComp.Definition Is AssemblyComponentDefinition Then
			oQuantity = oQuantity + StepDown(oComp.Definition.Occurrences, oPartName)
		End If
	Next
	Return oQuantity
End Function&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If this solved your problem, or answered your question, please click &lt;SPAN style="background-color: green; color: white;"&gt;&lt;STRONG&gt;ACCEPT SOLUTION&lt;/STRONG&gt;&lt;/SPAN&gt;.&lt;BR /&gt;Or, if this helped you, please click (LIKE or KUDOS) &lt;span class="lia-unicode-emoji" title=":thumbs_up:"&gt;👍&lt;/span&gt;.&lt;/P&gt;
&lt;P&gt;If you want and have time, I would appreciate your Vote(s) for &lt;A href="https://forums.autodesk.com/t5/forums/recentpostspage/post-type/message/interaction-style/idea/user-id/7812054/" target="_blank" rel="noopener"&gt;My IDEAS &lt;/A&gt; &lt;span class="lia-unicode-emoji" title=":light_bulb:"&gt;💡&lt;/span&gt; or you can Explore &lt;A href="https://knowledge.autodesk.com/profile/LTSUSR7HXMSAE/articles" target="_blank" rel="noopener"&gt;My CONTRIBUTIONS &lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 04 Nov 2021 14:06:10 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/inventor-programming-forum/quantity-in-assembly/m-p/10735619#M44091</guid>
      <dc:creator>WCrihfield</dc:creator>
      <dc:date>2021-11-04T14:06:10Z</dc:date>
    </item>
  </channel>
</rss>

