API: Failed to restore Edit-in-Place mode in assembly after sub-component modification

API: Failed to restore Edit-in-Place mode in assembly after sub-component modification

havlat_prefaservis
Participant Participant
133 Views
5 Replies
Message 1 of 6

API: Failed to restore Edit-in-Place mode in assembly after sub-component modification

havlat_prefaservis
Participant
Participant

Hi everyone,

I apologize for the state of my code, I’ve been struggling with this for several days now without the desired result. I would appreciate some guidance on a more elegant solution.

 

The Concept:

 

  1. I have a component in 'Edit-in-Place' mode within an assembly.

  2. I trigger an operation on this component (Sheet Metal Unfold) that requires opening the part in a separate document to process it.

  3. Once the operation is complete, I want to return to the original assembly and maintain the correct navigation/undo history.

The Problem:

Everything works as expected until the final step. Instead of returning to the assembly and focusing on the root assembly, the script leaves me stuck in the 'Edit-in-Place' mode of the original component where the whole process started.

I want the process to end with the root assembly active and the navigation history correctly restored, but my current approach keeps me trapped in the edit context of the child component.

Is there a more elegant way to handle this return to the root assembly? Maybe I am overcomplicating the whole process.

Thanks...

 

Here is my code:

Public Class AssemblyNavigator
    ' Logic to toggle Sheet Metal flat patterns and restore the original browser context
    Sub Main()

        Dim oADoc As AssemblyDocument = TryCast(ThisApplication.ActiveDocument, AssemblyDocument)
        If oADoc Is Nothing Then Exit Sub

        Dim oADef As AssemblyComponentDefinition = oADoc.ComponentDefinition
        Dim oEditOcc As ComponentOccurrence = oADef.ActiveOccurrence

        If oEditOcc Is Nothing Then
            MessageBox.Show("No occurrence is currently active.")
            Exit Sub
        End If

        ' 1. BUILD THE HIERARCHY LIST (From component up to root assembly)
        Dim AssemblyPath As New List(Of ComponentOccurrence)
        Dim oTempOcc As ComponentOccurrence = oEditOcc

        Do While oTempOcc IsNot Nothing
            AssemblyPath.Add(oTempOcc)
            oTempOcc = oTempOcc.ParentOccurrence
        Loop

        ' 2. PROCESS SHEET METAL UNFOLD/FOLD
        Dim oTargetOcc As ComponentOccurrence = AssemblyPath.Item(0)
        Dim oOccDoc As Document = oTargetOcc.Definition.Document
        Dim EditDocument As PartDocument = Nothing

        Try
            EditDocument = TryCast(ThisApplication.Documents.Open(oOccDoc.FullDocumentName, True), PartDocument)
            If EditDocument IsNot Nothing Then
                Dim oSMDef As SheetMetalComponentDefinition = EditDocument.ComponentDefinition
                If oSMDef.HasFlatPattern = True Then
                    oSMDef.FlatPattern.Delete()
                Else
                    oSMDef.Unfold()
                    oSMDef.FlatPattern.ExitEdit()
                End If
                EditDocument.Dirty = True
            End If
        Catch ex As Exception
            MessageBox.Show("Error processing flat pattern: " & ex.Message)
        End Try

        If EditDocument IsNot Nothing Then EditDocument.Close(False)

        ' 3. RESTORE ASSEMBLY CONTEXT (The problematic part)
        Try
            ' Attempting to return to the root assembly and re-drill down to the original context
            oADoc.Activate()
            ThisApplication.UserInterfaceManager.DoEvents()

            ' Re-drilling the path to restore the browser focus
            For i As Integer = AssemblyPath.Count - 1 To 0 Step -1
                Dim TargetOcc As ComponentOccurrence = AssemblyPath(i)
                TargetOcc.Edit()
                ThisApplication.UserInterfaceManager.DoEvents()
            Next

           
        Catch ex As Exception
            MessageBox.Show("Navigation failed: " & ex.Message)
        End Try

        Try
            ThisApplication.ActiveEditDocument.SelectSet.Clear()
        Catch
        End Try
    End Sub
End Class

 

0 Likes
Accepted solutions (2)
134 Views
5 Replies
Replies (5)
Message 2 of 6

WCrihfield
Mentor
Mentor

Hi @havlat_prefaservis.  Once you are done editing the part document that the occurrence represents, you should be able to use its 'PartDocument.Views.Item(1).Close() method.  But that will only work if you actually visibly opened the part, otherwise that step should not be necessary.  This will close the 'view' of that part, which is essentially all we can do for it at that point, because the part file actually needs to remain 'open' (just not visibly), due to it currently being referenced by the open assembly, and its component.  Next, you should be able to use the ComponentOccurrence.ExitEdit method, and specify the most appropriate variation of the ExitTypeEnum as input to that method.  That should return 'edit' focus back to the 'previous', 'parent', or 'top' edit scope.  But on another side note, there is actually already a built-in property for getting the 'path' of an assembly component.  You can use the ComponentOccurrence.OccurrencePath for that.  Its value is a ComponentOccurrencesEnumerator, containing every 'parent' occurrence up the 'assembly structure ladder' from it (if any).

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 6

havlat_prefaservis
Participant
Participant

Thanks for the quick response! I'll check it out and get back to you.

0 Likes
Message 4 of 6

WCrihfield
Mentor
Mentor
Accepted solution

You are welcome.  I hope it works out OK for you.  Below is a version of your original code that I modified, to add a few additional checks, more detailed error handling, and more feedback into.  Not sure if this will meet your needs, but thought it might at least be helpful, if nothing else.  I don't think you should 'need' to visually open the part to perform those operations on it, so I left one line of code in this (Line 21) 'commented out' for now.  If it needs to be opened visually (maybe because its occurrence is in 'edit mode' in the assembly), you can just uncomment that one line.

Public Class AssemblyNavigator
	' Logic to toggle Sheet Metal flat patterns and restore the original browser context
	Sub Main
		Dim oADoc As AssemblyDocument = TryCast(ThisApplication.ActiveDocument, AssemblyDocument)
		If oADoc Is Nothing Then Exit Sub
		Dim oADef As AssemblyComponentDefinition = oADoc.ComponentDefinition
		'get 'active' component occurrence (one in in-place edit mode)
		Dim oEditOcc As ComponentOccurrence = oADef.ActiveOccurrence
		If oEditOcc Is Nothing Then
			MessageBox.Show("No occurrence is currently active.")
			Exit Sub
		End If
		' 2. PROCESS SHEET METAL UNFOLD/FOLD
		Dim oOccDoc As PartDocument = TryCast(oEditOcc.Definition.Document, PartDocument)
		If oOccDoc Is Nothing Then
			MessageBox.Show("Could not get PartDocument from active occurrence!")
			Return
		End If
		'we should not need to visually open the part to do this, but you can if you want
		'we already know it is the right type, so no need for TryCast
		'oOccDoc = CType(ThisApplication.Documents.Open(oOccDoc.FullDocumentName, True), PartDocument)
		If Not oOccDoc.IsModifiable Then
			MessageBox.Show("This part document is 'NOT MODIFIABLE'!")
			Return
		End If
		If Not TypeOf oOccDoc.ComponentDefinition Is SheetMetalComponentDefinition Then
			MessageBox.Show("Occurrence Part was not a Sheet Metal Part!")
			Return
		End If
		Dim oSMDef As SheetMetalComponentDefinition = oOccDoc.ComponentDefinition
		If oSMDef.HasFlatPattern = True Then
			Try
				oSMDef.FlatPattern.Delete()
				oOccDoc.Dirty = True
			Catch
				MessageBox.Show("Error deleting existing FlatPattern!")
			End Try
		Else
			Try
				oSMDef.Unfold()
				oSMDef.FlatPattern.ExitEdit()
				oOccDoc.Dirty = True
			Catch
				MessageBox.Show("Error Unfolding Sheet Metal Part!")
			End Try
		End If
		If oOccDoc.Views.Count > 0 Then 'if no views, then no need to close it
			For Each oView As Inventor.View In oOccDoc.Views
				oView.Close()
			Next
		End If
		'make sure the assembly is still the 'active' document (it may still be)
		oADoc.Activate()
		'exit 'edit mode' for this component, back to the 'top' exit scope
		oEditOcc.ExitEdit(ExitTypeEnum.kExitToTop)
		'clear the SelectSet
		Try
			ThisApplication.ActiveEditDocument.SelectSet.Clear()
		Catch
		End Try
	End Sub
End Class

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 5 of 6

havlat_prefaservis
Participant
Participant

Thanks for your time. The code works partially, and it needs a little fix (for me).

..............
End If
		'make sure the assembly is still the 'active' document (it may still be)
		oADoc.Activate()
		'exit 'edit mode' for this component, back to the 'top' exit scope
		'oEditOcc.ExitEdit(ExitTypeEnum.kExitToTop)
		'clear the SelectSet
		oEditOcc.Edit
		Try
			ThisApplication.ActiveEditDocument.SelectSet.Clear()
		Catch
		End Try
	End Sub
End Class


Line 55 throws an error 0x80004005 sometimes, and it doesn't return me back to the edit document as i wanted.

It doesn't reconstruct the full path through the deeper sub-assemblies, but the main part works. I am back in the edit doc and I can manually go back to the main assembly.

Sorry if I didn't explain the problem properly, but the language is for me some kind of barrier.

0 Likes
Message 6 of 6

havlat_prefaservis
Participant
Participant
Accepted solution

I tried to join my logic with this navigation code using AI just to get it done quickly. It works exactly as I wanted now. Thanks again for the help, I couldn't find a more elegant way to do this.

Public Class AssemblyNavigator
    ' Logic to toggle Sheet Metal flat patterns and restore the original assembly browser context
   
    Public Sub Main()
        ' 1. Get active assembly document
        Dim oADoc As AssemblyDocument = TryCast(ThisApplication.ActiveDocument, AssemblyDocument)
        If oADoc Is Nothing Then Exit Sub

        Dim oADef As AssemblyComponentDefinition = oADoc.ComponentDefinition
        Dim oEditOcc As ComponentOccurrence = oADef.ActiveOccurrence

        ' Check if any component is currently being edited in-place
        If oEditOcc Is Nothing Then
            MessageBox.Show("No occurrence is currently active. Please edit a component in-place first.")
            Exit Sub
        End If

        ' 2. Build the hierarchy path (from the component up to the root assembly)
        Dim AssemblyPath As New List(Of ComponentOccurrence)
        Dim oTempOcc As ComponentOccurrence = oEditOcc

        Do While oTempOcc IsNot Nothing
            AssemblyPath.Add(oTempOcc)
            oTempOcc = oTempOcc.ParentOccurrence
        Loop

        ' 3. Process Sheet Metal Unfold/Fold
        Dim oOccDoc As PartDocument = TryCast(oEditOcc.Definition.Document, PartDocument)
        If oOccDoc Is Nothing Then
            MessageBox.Show("Could not get PartDocument from active occurrence!")
            Return
        End If

        If Not oOccDoc.IsModifiable Then
            MessageBox.Show("This part document is not modifiable!")
            Return
        End If

        If Not TypeOf oOccDoc.ComponentDefinition Is SheetMetalComponentDefinition Then
            MessageBox.Show("Selected component is not a Sheet Metal part.")
            Return
        End If

        Dim oSMDef As SheetMetalComponentDefinition = oOccDoc.ComponentDefinition
        
        ' Toggle Flat Pattern status
        If oSMDef.HasFlatPattern = True Then
            Try
                oSMDef.FlatPattern.Delete()
                oOccDoc.Dirty = True
            Catch ex As Exception
                MessageBox.Show("Error deleting Flat Pattern: " & ex.Message)
            End Try
        Else
            Try
                oSMDef.Unfold()
                oSMDef.FlatPattern.ExitEdit()
                oOccDoc.Dirty = True
            Catch ex As Exception
                MessageBox.Show("Error unfolding Sheet Metal part: " & ex.Message)
            End Try
        End If

        ' Close any open views of the part to prevent UI conflicts
        If oOccDoc.Views.Count > 0 Then
            For Each oView As Inventor.View In oOccDoc.Views
                oView.Close()
            Next
        End If

        ' 4. Restore assembly context
        Try
            oADoc.Activate()
            ThisApplication.UserInterfaceManager.DoEvents()

            ' Drill down the saved path to restore the browser focus and in-place edit mode
            For i As Integer = AssemblyPath.Count - 1 To 0 Step -1
                Dim TargetOcc As ComponentOccurrence = AssemblyPath(i)
                TargetOcc.Edit()
                ThisApplication.UserInterfaceManager.DoEvents()
            Next

            ' Clear selection set
            Try
                ThisApplication.ActiveEditDocument.SelectSet.Clear()
            Catch
            End Try
        Catch ex As Exception
            MessageBox.Show("Navigation restore failed: " & ex.Message)
        End Try
    End Sub
End Class

 

0 Likes