Probably not the best title, but here goes the explanation.
I have a VBA macro that uses the sample code in inventor that basically cycles through an assembly and allows you to pick which items you want to add to a list that will eventually get exported to an excel file.
I've run this on a multi-level assembly and it works great. I have about 10 assemblies in the main file, most have sub-assemblies, and there are nuts/bolts and even virtual parts in the top level and it works just fine. no problems at all.
I was trying to show someone how to use it today and it failed. I couldn't figure out why. I tried running it on my machine and it worked on the main assembly i'd been using, but when i went down to a single assembly - it gave me errors. To be fair, it's given me the error on a couple assemblies with just one sub-assembly as well, but i'm at a loss to explain why.
The second portion (QueryBomRowProperties) doesn't seem to generate any text when you click YES on these files.
You run the macro and it'll ask you if you want to do just the top level of the assembly or go recursively through the whole thing. Then it prompts you part by part to see what you want to add. It's supposed to simply create a text string and then add a line to it every time you say yes. It's just that i'm getting some assemblies that generate no text. If I click yes 8 times, it's giving me 8 blank lines. Any idea why it would generate blanks likes when every piece gives it's full information in the dialog to ask you if you want to add it or not? I have no idea why it works on large assemblies with many subs, but not a basic piece. What am I missing here?
Dim MyCount As Integer Dim SL_Text As String Public Sub CreateNewShiplist() ' Set a reference to the assembly document. ' This assumes an assembly document is active. Dim oDoc As AssemblyDocument Set oDoc = ThisApplication.ActiveDocument ' Make sure that the structured view is enabled. Dim TopLevelOnly As Boolean If MsgBox("Do you want create a shipping list just the top level assembly?", vbYesNo) = vbYes Then TopLevelOnly = True Else TopLevelOnly = False End If ' Set a reference to the BOM Dim oBOM As BOM Set oBOM = oDoc.ComponentDefinition.BOM ' Set to do correct levels If TopLevelOnly Then oBOM.StructuredViewFirstLevelOnly = True Else oBOM.StructuredViewFirstLevelOnly = False End If oBOM.StructuredViewEnabled = True 'Set a reference to the "Structured" BOMView Dim oBOMView As BOMView Set oBOMView = oBOM.BOMViews.Item("Structured") 'Initialize the tab for ItemNumber Dim ItemTab As Long ItemTab = -3 MyCount = 0 SL_Text = "" Call QueryBOMRowProperties(oBOMView.BOMRows, ItemTab) ' for future reference - once the called function completes itself completely it comes back and continues with the next line from here Debug.Print SL_Text CreateShiplist (SL_Text) End Sub Private Sub QueryBOMRowProperties(oBOMRows As BOMRowsEnumerator, ItemTab As Long) Dim PartInfo As String Dim AddBox As Boolean AddBox = False ItemTab = ItemTab + 3 ' Iterate through the contents of the BOM Rows. Dim i As Long For i = 1 To oBOMRows.Count ' Get the current row. Dim oRow As BOMRow Set oRow = oBOMRows.Item(i) 'Set a reference to the primary ComponentDefinition of the row Dim oCompDef As ComponentDefinition Set oCompDef = oRow.ComponentDefinitions.Item(1) Dim oPartNumProperty As Property Dim oDescripProperty As Property Dim oTagProperty As Property If TypeOf oCompDef Is VirtualComponentDefinition Then 'Get the file property that contains the "Part Number" 'The file property is obtained from the virtual component definition Set oPartNumProperty = oCompDef.PropertySets _ .Item("Design Tracking Properties").Item("Part Number") 'Get the file property that contains the "Description" Set oDescripProperty = oCompDef.PropertySets _ .Item("Design Tracking Properties").Item("Description") On Error Resume Next Set oTagProperty = oCompDef.PropertySets _ .Item("User Defined Properties").Item("TAG_NO") PartInfo = "Part Number: " & oPartNumProperty.Value & vbCrLf PartInfo = PartInfo & " Mark No: " & oTagProperty.Value & vbCrLf PartInfo = PartInfo & " Description: " & oDescripProperty.Value & vbCrLf PartInfo = PartInfo & " Qty: " & oRow.ItemQuantity If MsgBox("Do you want to add the following part to the Ship List?" & vbCrLf & vbCrLf & PartInfo, vbYesNo) = vbYes Then AddBox = True 'Exit Sub Else AddBox = False End If If AddBox = True Then 'If Len(oTagProperty.Value) > 0 Then Debug.Print Tab(0); oTagProperty.Value; Tab(20); oDescripProperty.Value; Tab(90); oPartNumProperty.Value; Tab(110); oRow.ItemQuantity; Tab(120); MyCount; SL_Text = SL_Text & oTagProperty.Value & "|" & oDescripProperty.Value & "|" & oPartNumProperty.Value & "|" & oRow.ItemQuantity & vbCrLf End If Else 'Get the file property that contains the "Part Number" 'The file property is obtained from the parent 'document of the associated ComponentDefinition. Set oPartNumProperty = oCompDef.Document.PropertySets _ .Item("Design Tracking Properties").Item("Part Number") 'Get the file property that contains the "Description" Set oDescripProperty = oCompDef.Document.PropertySets _ .Item("Design Tracking Properties").Item("Description") On Error Resume Next ' oTagProperty.Value = "" Set oTagProperty = oCompDef.Document.PropertySets _ .Item("User Defined Properties").Item("TAG_NO") 'PartInfo = oPartNumProperty.Value & Space(10) & oTagProperty.Value & Space(10) & oDescripProperty.Value PartInfo = "Part Number: " & oPartNumProperty.Value & vbCrLf PartInfo = PartInfo & " Mark No: " & oTagProperty.Value & vbCrLf PartInfo = PartInfo & " Description: " & oDescripProperty.Value & vbCrLf PartInfo = PartInfo & " Qty: " & oRow.ItemQuantity If MsgBox("Do you want to add the following part to the Ship List?" & vbCrLf & vbCrLf & PartInfo, vbYesNo) = vbYes Then AddBox = True 'MsgBox "Add it" 'Exit Sub Else AddBox = False 'MsgBox "Don't add" End If If AddBox Then 'If Len(oTagProperty.Value) > 0 Then Debug.Print Tab(0); oTagProperty.Value; Tab(20); oDescripProperty.Value; Tab(90); oPartNumProperty.Value; Tab(110); oRow.ItemQuantity; Tab(120); MyCount; 'MsgBox "here" SL_Text = SL_Text & oTagProperty.Value & "|" & oDescripProperty.Value & "|" & oPartNumProperty.Value & "|" & oRow.ItemQuantity & vbCrLf End If 'Recursively iterate child rows if present. If Not oRow.ChildRows Is Nothing Then Dim CheckSA As Boolean If MsgBox("Do you want to seach the following sub assembly for the Ship List?" & vbCrLf & vbCrLf & PartInfo, vbYesNo) = vbYes Then Call QueryBOMRowProperties(oRow.ChildRows, ItemTab) End If End If End If Next ItemTab = ItemTab - 3 End Sub
I'm now thinking it has something to do with library parts.
I created a new assembly with a a few normal parts from a project and added a virtual part for good measure. No problem at all.
I made another assembly out of 2 library parts and a virtual part and it generates a blank response....why would it skip library parts if that's all that's present?
I can do a full assembly where library exist but are three levels deep and they get added just fine. What makes it different on a single assembly?
Update - I've made a new assembly in the following order:
Virtual part
3 normal project parts
it worked. I then added a library part. It worked. I then built a new assembly using the exact same parts in the following order:
library part
virtual part
3 normal project parts
The library and normal parts failed. Just generated blank results, but the virtual part worked. Seems as if there's a problem if a library part is first in the BOM listing because that seems to be when an assembly fails to generate a response.
There is not check for library part in the API code I based this on, the check is for virtual. If virtual, do this.....else, do this. Apparently a library part in the first slot causes a problem. Is this a bug?
Any ideas here? It's not really feasible to go through all existing assemblies to see if they have a library part in the first slot the BOM checks. I've tried moving them out of the first spot in the BOM, too. Doesn't work. Seems you'd have to delete it from the browser and re-add it. Not really something you can do if the whole assembly is made of library parts.
I've narrowed it all the way down to this line(s):
On Error Resume Next Set oTagProperty = oCompDef.Document.PropertySets _ .Item("User Defined Properties").Item("TAG_NO")
Apparently if the first object (ipt, iam, ipn) that the BOM exports is a library part - this part fails.
My understanding is that that phrasing is creating a property called oTagProperty and that i'm assigning the text from the objects TAG_NO value field to the oTagProperty.
I'd prefer to error check it with something like:
On Error Resume Next Set oTagProperty = oCompDef.Document.PropertySets _ .Item("User Defined Properties").Item("TAG_NO") if err.number <> 0 then set oTagProperty="" 'leaves it blanks end if
Seems OK in theory. Upon trying to run it that line apparently generates an error that's skipped and all subsequent lines involving the oTagProperty are skipped as well.
I've tried set otagproperty.value and even just otagproperty.value = "" but nothing seems to be able to set the property to a string value.
How do I go about setting the property oTagProperty to a string value? FWIW, there is a Dim oTagProperty as Property line a bit up in the function