Errors with BOM api on assembly with model states

Errors with BOM api on assembly with model states

pball
Mentor Mentor
865 Views
13 Replies
Message 1 of 14

Errors with BOM api on assembly with model states

pball
Mentor
Mentor

I have a script for sorting and renumbering the BOM which in turn sorts the drawing parts list how I wish. Since model states were introduced my script has been failing and I cannot figure why or how to correct it. Adding a model state to an assembly and then running the code below doesn't always cause a failure, but after renumbering an item in the assembly BOM the code will always fail. The primary failure is trying to set the BOM structured view first level only to False and the secondary failure is trying to import the BOM customization XML file.

I have a test drawing and related assembly attached with an iLogic rule in the drawing that has the below code.

 

 

 

        Dim oSheet As Sheet = ThisApplication.ActiveDocument.ActiveSheet

        Dim oDrawingView As DrawingView = oSheet.DrawingViews(1)

        If (oDrawingView.ReferencedDocumentDescriptor.ReferencedDocumentType <> DocumentTypeEnum.kAssemblyDocumentObject) Then
            MsgBox("This is not an assembly drawing")
            Exit Sub
        End If

        Dim oAssydoc As AssemblyDocument = oDrawingView.ReferencedDocumentDescriptor.ReferencedDocument

        Dim trans As Transaction = ThisApplication.TransactionManager.StartTransaction(oAssydoc, "Sort BOM")

        If (oAssydoc.ComponentDefinition.ModelStates.ActiveModelState.Name <> "[Primary]") Then
            If (MsgBox("Primary Model State not selected." & vbNewLine & "Click Yes to switch to Primary Model State or No to cancel.", MsgBoxStyle.YesNo) = MsgBoxResult.Yes) Then
                ThisApplication.Documents.Open(oAssydoc.FullFileName, False).ComponentDefinition.ModelStates("[Primary]").Activate()
            Else
                Exit Sub
            End If
        End If

        Dim oBOM As BOM = oAssydoc.ComponentDefinition.BOM

        oBOM.StructuredViewEnabled = True
        Try
            oBOM.StructuredViewFirstLevelOnly = False
        Catch ex As Exception
            MsgBox("Failed to set BOM view to first level only, try again or sort BOM manually")
            'Exit Sub
        End Try

        Dim oBOMView As BOMView = oBOM.BOMViews.Item("Structured")
        Dim oBOMRows As BOMRowsEnumerator = oBOMView.BOMRows

        Try
			'MsgBox(System.IO.Path.GetDirectoryName(ThisApplication.ActiveDocument.fullfilename) & "\Bom.xml")
            Call oBOM.ImportBOMCustomization(System.IO.Path.GetDirectoryName(ThisApplication.ActiveDocument.fullfilename) & "\Bom.xml")
        Catch ex As Exception
            MsgBox("Failed to import BOM customization, try again or sort BOM manually")
            'Exit Sub
        End Try
		

 

 

 

 

Check out my style edits for the Autodesk forums
pball's Autodesk Forum Style
0 Likes
Accepted solutions (2)
866 Views
13 Replies
Replies (13)
Message 2 of 14

WCrihfield
Mentor
Mentor

Hi @pball.  Due to corporate security policies, I am not allowed to download/open ZIP (and similar compressed) files from forums on work PC, but I may still be able to help some here.  First, you are not checking which ModelState the DrawingView is set to.  That is important.  You can use the ReadOnly property DrawingView.ActiveModelState to check that.  Just checking which one was active in the referenced document may not be good enough, because it might be different.  It is good to cross check those two pieces of data to be sure.  Next, when using the Open method, it is usually best to use the FullDocumentName, instead of just FullFileName, especially when ModelStates are involved.  The FullDocumentName will start with the FullFileName value, but then it may also include the name of the ModelState version of that file that it should be accessing (at the end, within < & > characters), which is often important.  Also, you are not capturing the Document object at that point in the code.  When you 'activate' a different ModelState, you will also be working with a different Document object.  There may be just one 'File' on disk, but when there are multiple ModelStates in that file, there will usually also be multiple Documents (one for each normal ModelState).  It is apparently possible for a ModelState to exist, without there being a Document generated for it (no value for ModelState.Document), but I think that is only when it has never been activated or edited independently of any other ModelState.  So, if the referenced assembly was not set to the primary ModelState, then your code activated that ModelState, then your document variable is no longer related to the newly activated ModelState, and would be considered representing a 'member', instead of the ModelState 'factory'.  And you can only make changes/edits to the ModelState factory version when there are multiple ModelStates (with a couple exceptions).  This is likely why it is failing at that point in the code.

 

Edit:  Below is an edited version of your code that you can try out.  I am showing a couple tricks that may help in the future, but decided to not bother with checking which ModelState the view was set to, since you will always want the primary version for the BOM.  This utilizes the FileManager and its methods to separate the FullFileName & ModelState name portions of the FullDocumentName, in order to get the FullDocumentName of the version that we want to be working with, then uses the Open method to get that version and set it to our existing variable.  It could have likely been done in fewer lines of code, but shorter code does not always equal better performance/results.  On a side note, this variation of the code may not always be best if the assembly may not have any ModelStates in it though.  Could check for empty String when checking ModelState name too, then deal with that differently.

Dim oSheet As Sheet = ThisApplication.ActiveDocument.ActiveSheet
Dim oDrawingView As DrawingView = oSheet.DrawingViews(1)
If (oDrawingView.ReferencedDocumentDescriptor.ReferencedDocumentType <> DocumentTypeEnum.kAssemblyDocumentObject) Then
	MsgBox("This is not an assembly drawing")
	Exit Sub
End If
Dim oAssydoc As AssemblyDocument = oDrawingView.ReferencedDocumentDescriptor.ReferencedDocument
'this would be one way of getting the 'factory' version, if one exists
'If oAssydoc.ComponentDefinition.IsModelStateMember Then
'	oAssydoc = oAssydoc.ComponentDefinition.FactoryDocument
'End If
'but we don't just need the 'factory' (which may be a different Document),
'we specifically need the [Primary] ModelState version of it (for BOM purposes),
'then make sure that one becomes the factory version, if it is not already
'so, lets do this another way here
Dim oFileMgr As Inventor.FileManager = ThisApplication.FileManager
Dim sFDN As String = oAssydoc.FullDocumentName
'get the name of ModelState associated with this document, if any
Dim sMSName As String = oFileMgr.GetModelStateName(sFDN)
'if it is not "[Primary]", then force our Document reference to be that version
If sMSName <> "[Primary]" Then
	'put FullFileName & ModelState name together to make new FullDocumentName
	sFDN = oFileMgr.GetFullDocumentName(oAssydoc.FullFileName, "[Primary]")
	'use that new FullDocumentName to open, get a reference to that version of it
	oAssydoc = ThisApplication.Documents.Open(sFDN, False)
End If
'at this point, our oAssydoc variable should be OK to work with
Dim trans As Transaction = ThisApplication.TransactionManager.StartTransaction(oAssydoc, "Sort BOM")
Dim oBOM As BOM = oAssydoc.ComponentDefinition.BOM
oBOM.StructuredViewEnabled = True
Try
	oBOM.StructuredViewFirstLevelOnly = False
Catch ex As Exception
	MsgBox("Failed to set BOM view to first level only, try again or sort BOM manually")
	'Exit Sub
End Try
Dim oBOMView As BOMView = oBOM.BOMViews.Item("Structured")
Dim oBOMRows As BOMRowsEnumerator = oBOMView.BOMRows
Try
	'MsgBox(System.IO.Path.GetDirectoryName(ThisApplication.ActiveDocument.fullfilename) & "\Bom.xml")
	oBOM.ImportBOMCustomization(System.IO.Path.GetDirectoryName(ThisApplication.ActiveDocument.fullfilename) & "\Bom.xml")
Catch ex As Exception
	MsgBox("Failed to import BOM customization, try again or sort BOM manually")
	'Exit Sub
End Try

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 14

pball
Mentor
Mentor

@WCrihfield
Thanks for your input. I tried out your code but it does not prevent the errors from occurring. I'm beginning to wonder if this might be a defect in the api. I was going to try sharing the files via Autodesk Drive but you can't share folders with a link apparently.

Check out my style edits for the Autodesk forums
pball's Autodesk Forum Style
0 Likes
Message 4 of 14

Maxim-CADman77
Advisor
Advisor

@pball 
 Running your rule on your IDW does not produce any errors/exceptions and also does not change anything in PartsList (at least visually).

Inv 2024.3.1

Please vote for Inventor-Idea Text Search within Option Names

0 Likes
Message 5 of 14

pball
Mentor
Mentor

It does run the first time after opening the file, but try running it after manually changing an item number inside of the BOM for 1111-213.iam. It fails every time after I do that.

 

pball_0-1722341980070.png

I also tried to make a simplified assembly and the issue did not seem to happen when running the rule from inside of the assembly. But I did make a more simple drawing which still has the issue, though it runs without after opening but after manually changing the BOM item number it fails every time. See next post for the part file as posts have a 3 file limit.

Check out my style edits for the Autodesk forums
pball's Autodesk Forum Style
0 Likes
Message 6 of 14

pball
Mentor
Mentor

Part file to go with files on previous post.

Check out my style edits for the Autodesk forums
pball's Autodesk Forum Style
0 Likes
Message 7 of 14

WCrihfield
Mentor
Mentor

This may be due to having two different ModelState versions of the same file loaded/open within Inventor's session memory at the same time.  Try adding a line or two of code in there that attempts to update the assembly document, after you get the version of the assembly document you need to be working with.  There is documentation to support an update being needed before you can make any changes to a second instance of the same file, set to a different ModelState, within Inventor's memory.

https://help.autodesk.com/view/INVNTOR/2024/ENU/?guid=GUID-418B956A-AC3F-48D8-BEBC-FC28C4B51DA2 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 8 of 14

pball
Mentor
Mentor

I put in both of the updates below in a few places in the code and they also made no difference. I think I'm going to open a support ticket as this is starting to look like a bug.

 

InventorVb.DocumentUpdate
oAssydoc.Update

 

Check out my style edits for the Autodesk forums
pball's Autodesk Forum Style
0 Likes
Message 9 of 14

WCrihfield
Mentor
Mentor

You may be correct...not sure.  I have not had a good opportunity to do actual tests with your files yet, due to multiple factors and being pretty busy on multiple fronts lately.  Not being able to make any changes to an assembly after a ModelState gets involved/changed is classic sign that the code is attempting to work with a ModelState 'member' version of the document, instead of its factory version.  However, I'm pretty sure that is not the only thing that may cause this type of behavior.  I suspect that, if the view was set to the same ModelState that was active when the model file was last saved, and that same ModelState was currently active in that model file (because the model file should already be loaded into memory just by opening the drawing that references it), then their likely would not be a problem.  But when that is not the case, or if there are is another view somewhere within that drawing that is set to a different ModelState, or if there was an assembly open, in which that model file was being referenced by one or more assembly components, and any of those is set to a different ModelState, then all those scenarios may cause the same types of issues.  Because multiple versions of the same file are currently loaded/open in Inventor's session memory, and this is apparently difficult to 'manage' properly.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 10 of 14

pball
Mentor
Mentor

@CGBenner 
Would you be able to help and tag any Autodesk employees who might be able to look at this API issue. I tried making a case through my work account and the response was "Moving forward, due to being iLogic related and creating a customization of Inventor with rules, it is considered a customization of Inventor and would be outside of our Technical Support."

Check out my style edits for the Autodesk forums
pball's Autodesk Forum Style
0 Likes
Message 11 of 14

CGBenner
Community Manager
Community Manager

@jan_priban Would you be able to look at this issue, or tag someone whom you think might have some ideas on this?

Did you find a post helpful? Then feel free to give likes to these posts!
Did your question get successfully answered? Then just click on the 'Accept solution' button.  Thanks and Enjoy!


Chris Benner
Community Manager

0 Likes
Message 12 of 14

jan_priban
Alumni
Alumni

I tried to run both iLogic rules on R 2025.1 and I am getting the "Failed to set BOM view to first level only, try again or sort BOM manually" error as well. Let me inform (internally) API Model States expert.

 

Regards

 

Jan Priban

0 Likes
Message 13 of 14

YuhanZhang
Autodesk
Autodesk
Accepted solution

@pball If you add below two MsgBox lines to your iLogic code you can see that the referenced assembly document is a model state member document, and if it is not modifiable then your change to it will fail:

Dim oAssydoc As AssemblyDocument = oDrawingView.ReferencedDocumentDescriptor.ReferencedDocument
		MsgBox(oAssydoc.ComponentDefinition.IsModelStateMember)
		MsgBox(oAssydoc.IsModifiable)
        Dim trans As Transaction = ThisApplication.TransactionManager.StartTransaction(oAssydoc, "Sort BOM")

 

This may happen:

1. If your assembly document has both its model state factory document and member document opened, in this case you can use the AssemblyComponentDefinition.FactoryDocument property to get the model state factory document to edit, and update it to all the member documents.

2. If you have not model state factory document open, but several model state member documents opened, only one member document can be in edit mode, so you need to check the AssemblyDocument.IsModifiable property to know if your model state member document can be edited or not. If not then you need to find the other model state member document which is dirtied and save it or update it to make sure all member documents are up to date, so you can then edit either one after that.

 

So please try to get the model state factory document to edit the BOM if possible, which should succeed. Or you need to make sure your current model state member document is modifiable before you edit it.

 

Pleae let me if you have more trouble to update your code.

 

Also you can refer to below topic about model state for more information:

Inventor 2025 Help | Working with Model States | Autodesk  

 



If this solves the problem please click ACCEPT SOLUTION so other people can find it easily.



Rocky Zhang
Inventor API PD
Manufacturing Solutions
Autodesk, Inc.

0 Likes
Message 14 of 14

pball
Mentor
Mentor
Accepted solution

@YuhanZhang 
Thanks for the information. It seems the change from level of details to model states was more involved than I realized. So I've gotten rid of the active model state check and have it checking IsModelStateMember and IsModifiable instead and setting the assembly doc to the FactoryDocument if needed. So far in my test example this works.

 

        Dim oAssydoc As AssemblyDocument = oDrawingView.ReferencedDocumentDescriptor.ReferencedDocument

        If (oAssydoc.ComponentDefinition.IsModelStateMember) And Not (oAssydoc.IsModifiable) Then
            oAssydoc = oAssydoc.ComponentDefinition.FactoryDocument
        End If

        'If (oAssydoc.ComponentDefinition.ModelStates.ActiveModelState.Name <> "[Primary]") Then
        '    If (MsgBox("Primary Model State not selected." & vbNewLine & "Click Yes to switch to Primary Model State or No to cancel.", MsgBoxStyle.YesNo) = MsgBoxResult.Yes) Then
        '        ThisApplication.Documents.Open(oAssydoc.FullFileName, False).ComponentDefinition.ModelStates("[Primary]").Activate()
        '    Else
        '        Exit Sub
        '    End If
        'End If

 

Check out my style edits for the Autodesk forums
pball's Autodesk Forum Style