Save and Replace with Drawing

Save and Replace with Drawing

peterjoachim
Enthusiast Enthusiast
2,818 Views
19 Replies
Message 1 of 20

Save and Replace with Drawing

peterjoachim
Enthusiast
Enthusiast

I needed a tool that works as the Save and Replace command but I needed it to also make a copy of the original drawing and replace the reference of that drawing with the new component.  I've written the rule below, which works great, but when the rule has finished Inventor seems to be stuck in an add to selection type of state (cursor shows a plus sign next to it). A simple hit of the Esc key clears it up but I was wondering if there is something I can code differently to exit cleanly. I'm relatively new to iLogic. Thanks.

Dim oDWGType As String = ".idw"
Dim oDoc As Document = ThisApplication.ActiveDocument
Dim oSelected As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection

'CHECK THAT ONLY ONE COMPONENT IS SELECTED
If oDoc.SelectSet.Count <> 1 Then
    MessageBox.Show("ONE component must be selected.", "ERROR")
    Exit Sub
End If

'ADD TO OBJECT COLLECTION
For i = 1 To oDoc.SelectSet.Count
    If TypeOf oDoc.SelectSet.Item(i) Is ComponentOccurrence Then
        oSelected.Add (oDoc.SelectSet.Item(i))
    End If
Next

'CAPTURE OLD FILE INFORMATION
oOldDoc = oSelected.Item(1).Definition.Document
Dim oOldComp As String = System.IO.Path.GetFileName(oOldDoc.FullDocumentName)
Dim oOldIDW As String = System.IO.Path.ChangeExtension(oOldDoc.FullDocumentName, oDWGType)

'RUN Save&Replace COMMAND
ThisApplication.CommandManager.ControlDefinitions.Item("AssemblyBonusTools_SaveAndReplaceComponentCmd").Execute

'CAPTURE NEW FILE INFORMATION
oNewDoc = oSelected.Item(1).Definition.Document
Dim oNewComp As String = System.IO.Path.GetFileName(oNewDoc.FullDocumentName)
Dim oNewIDW As String = System.IO.Path.ChangeExtension(oNewDoc.FullDocumentName, oDWGType)

'EXIT IF Save&Replace WAS CANCELLED
If oOldComp = oNewComp Then
	Return
End If

'OPEN OLD DRAWING
If System.IO.File.Exists(oOldIDW) Then
Dim DrawingDoc As DrawingDocument = ThisApplication.Documents.Open(oOldIDW)

'REPLACE REFERENCE
Dim oFD As FileDescriptor = DrawingDoc.ReferencedFileDescriptors(1).DocumentDescriptor.ReferencedFileDescriptor
oFD.ReplaceReference(oNewComp)
DrawingDoc.Update()

'SAVE NEW DRAWING
DrawingDoc.SaveAs(oNewIDW, False)

'REACTIVATE ASSEMBLY
oDoc.Activate()

Else
	MessageBox.Show("A drawing file of the replaced component was not found.", "Missing " & oDWGType,MessageBoxButtons.OK,MessageBoxIcon.Information)
End If

 

Accepted solutions (1)
2,819 Views
19 Replies
Replies (19)
Message 2 of 20

peterjoachim
Enthusiast
Enthusiast

Or even better.. Can this be turned into a Macro? Unfortunately I'm not proficiant in VB.

0 Likes
Message 3 of 20

WCrihfield
Mentor
Mentor

So you're saying this code accomplishes everything you want it to do, as it is right now, but when it finishes a (successful) run, it is in a selection state, correct?  I want to ask you how that command that you are executing knows which component you want to replace, AND which component you want to replace it with?  My guess is that the command is still wanting you to select a component to replace the one that was in your SelectSet at the start of the code, when it finishes.  Is that possible?

 

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

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 4 of 20

peterjoachim
Enthusiast
Enthusiast

Yes everything works perfectly. I was surprised to find out (by accident) that it was able to recall the new replacement parts info after running the SaveAndReplaceComonentCmd. So I can't tell you exactly how that part works, I just know it does.

That was kind of my assumption as well regarding the selection state. Any idea on how to cancel that?

0 Likes
Message 5 of 20

WCrihfield
Mentor
Mentor
Accepted solution

When I pre-select a component in an assembly, then click on that "Save and Replace" tool manually, it immediately opens up a sort of SaveAs dialog that is titled "Create Part" and it is looking at the current Project Workspace directory.  I would imagine that because we're launching the command from iLogic, it is just bypassing this dialog, and assuming a confirming OK to the default location and default renaming convention of the copy file, so that's likely not it either.

Is it possible this phenomenon is simply that same command is still active, and awaiting another selection to continue a string of (save and replace) operations, sort of like if you clicked 'Continue' or 'Next'?  Perhaps you just need to add a line similar to SendKeys.SendWait("{ESC}") to the end of the code, to exit out of the continuing command?

 

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

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 6 of 20

peterjoachim
Enthusiast
Enthusiast

It's not bypassing the "Create Part" dialog. This still comes up when using the iLogic rule. Adding the SendKeys.SendWait("{ESC}")  at the end does work. I'm still curious as to what's really happening behind the scenes though. Thanks for the help. 

0 Likes
Message 7 of 20

Kassenbouw
Enthusiast
Enthusiast

When I'm trying to use this code Inventor will make a new part for me but doesn't make a new drawing for me. Instead it will open the drawing of the item I'm trying to replace and gives me this error 'The parameter is incorrect. (Exception from HRESULT: 0x80070057 (E_INVALIDARG))'

Does anyone know how to fix this?

 

Thanks

0 Likes
Message 8 of 20

peterjoachim
Enthusiast
Enthusiast

Hmmm... would you be able to share a copy of a part and drawing that produces this error?

0 Likes
Message 9 of 20

WCrihfield
Mentor
Mentor

You said it was opening the old drawing file up OK, right?  So that would mean that it is finding that drawing OK.  So it must be having a problem with the ReplaceReference part if the code.  I was going to suggest using FullFileName, instead of FullDocumentName when setting the values of the oNewIDW/oNewComp variables, but since it found the drawing OK, that's not likely to be the issue, but you can try it.  The FullDocumentName say's that it is the FullFileName concatenated with the 'document name', so it's not as simple/straightforward as the FullFileName.

Does the drawing have views of more than just that one model document within it?  If so, this might be where it is having a problem.  It might be trying to replace the wrong model reference, or something similar.  It seems like Inventor's drawing documents were originally only meant to work with one model document at a time, because the API for working with a drawing mainly just recognizes one (the first) 'model' document.

 

Also...are you pre-selecting a component before running the rule?

 

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

If you want and have time, I would appreciate your Vote(s) for My IDEAS 💡or you can Explore My CONTRIBUTIONS

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 10 of 20

Kassenbouw
Enthusiast
Enthusiast

Thanks for the replys. I have replaced the FullDocumentName with FullFileName in this rule and this does exactly the same. 

There must be something in the replace reference part. 

No there is only model reference in my drawning. I have tried the code on a simpel assembly. 

I'm selecting a part in my assembly, run this rule, save the new part on my workspace. Then I get the question if I want to save the session of the old part. After this the drawning will open and I'm getting an error . The parameter is incorrect. (Exception from HRESULT: 0x80070057 (E_INVALIDARG))

0 Likes
Message 11 of 20

Ralf_Krieg
Advisor
Advisor

Hello

 

This only returns a filename with extension instead of the full path, file name and extension. The ReplaceReference method expects the FullFileName.

Dim oNewComp As String = System.IO.Path.GetFileName(oNewDoc.FullDocumentName)

 


R. Krieg
RKW Solutions
www.rkw-solutions.com
0 Likes
Message 12 of 20

peterjoachim
Enthusiast
Enthusiast

I guess I have tweaked this a little since my original posting. Here is the code I am currently using. This has been working well for me... (I had to comment out the Vault deactivation as that seems to have broke after updating to 2021).

Dim oDrawingType As String = ".idw"
Dim oDoc As Document = ThisApplication.ActiveDocument
Dim oSelected As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection

'CHECK THAT A COMPONENT IS SELECTED----------------------
If oDoc.SelectSet.Count = 0 Then
    MessageBox.Show("A component must first be selected to run the operation.", "Invalid selection.",MessageBoxButtons.OK,MessageBoxIcon.Error)
    Exit Sub
End If

'CHECK THAT ONLY ONE COMPONENT IS SELECTED-----------------------
If oDoc.SelectSet.Count > 1 Then
    MessageBox.Show("Only one component can be selected at a time.", "Invalid selection.",MessageBoxButtons.OK,MessageBoxIcon.Error)
    Exit Sub
End If

'ADD TO OBJECT COLLECTION-----------------------------------------
For i = 1 To oDoc.SelectSet.Count
    If TypeOf oDoc.SelectSet.Item(i) Is ComponentOccurrence Then
        oSelected.Add (oDoc.SelectSet.Item(i))
    End If
Next

'CAPTURE OLD FILE INFORMATION---------------------------------------
oOldDoc = oSelected.Item(1).Definition.Document
Dim oOldComp As String = System.IO.Path.GetFullPath(oOldDoc.FullDocumentName)
Dim oOldIDW As String = System.IO.Path.ChangeExtension(oOldDoc.FullDocumentName, oDrawingType)

'RUN Save&Replace COMMAND-------------------------------------------
ThisApplication.CommandManager.ControlDefinitions.Item("AssemblyBonusTools_SaveAndReplaceComponentCmd").Execute

'CAPTURE NEW FILE INFORMATION----------------------------------------
oNewDoc = oSelected.Item(1).Definition.Document
Dim oNewComp As String = System.IO.Path.GetFullPath(oNewDoc.FullDocumentName)
Dim oNewIDW As String = System.IO.Path.ChangeExtension(oNewDoc.FullDocumentName, oDrawingType)

'EXIT IF Save&Replace WAS CANCELLED-------------------------------------
If oOldComp = oNewComp Then
	Return
End If

''---DEACTIVATE VAULT---
'Dim oVault As ApplicationAddIn
'For Each oVault In ThisApplication.ApplicationAddIns
'	If oVault.DisplayName = "Inventor Vault" Then Exit For
'Next
'If oVault IsNot Nothing Then oVault.Deactivate

'SAVE A COPY OF THE OLD DRAWING-----------------------------------------
If System.IO.File.Exists(oOldIDW) Then
Dim DrawingDoc As DrawingDocument = ThisApplication.Documents.Open(oOldIDW)
DrawingDoc.SaveAs(oNewIDW, True)
DrawingDoc.Close(True)

'REPLACE REFERENCE-------------------------------------------------------
Dim NewDoc = ThisApplication.Documents.Open(oNewIDW)
Dim oFD As FileDescriptor = NewDoc.ReferencedFileDescriptors(1).DocumentDescriptor.ReferencedFileDescriptor
oFD.ReplaceReference(oNewComp)
NewDoc.Update()
NewDoc.Save


'REACTIVATE ASSEMBLY & VAULT--------------------------------------------------------
oDoc.Activate()
'oVault.Activate

Else
	MessageBox.Show("Component has been replaced but the drawing file was not found.", "Missing " & oDrawingType,MessageBoxButtons.OK,MessageBoxIcon.Information)
End If

SendKeys.SendWait("{ESC}")

 

0 Likes
Message 13 of 20

WCrihfield
Mentor
Mentor

In your originally posted code you had the lines:

Dim oFD As FileDescriptor = DrawingDoc.ReferencedFileDescriptors(1).DocumentDescriptor.ReferencedFileDescriptor
oFD.ReplaceReference(oNewComp)

I was going to suggest that you change that line.  Since that variable had already been defined as a DrawingDocument.

1) The DrawingDocument doesn't have a ReferencedFileDescriptors directly available, but it does have a ReferencedDocumentDescriptors directly available, so you may have needed to change that.

2) Once you've done the above, you would have needed to either get rid of the "(1)" or the ".DocumentDescriptor", because Item(1) of the ReferencedDocumentDescriptors will already be a DocumentDescriptor, making one or the other unnecessary.  Then you can get the FileDescriptor from that DocumentDescriptor, as usual.  Your next line, where you use the ReplaceReference method, should then be just fine.

So...the line should look something like this:

Dim oFD As FileDescriptor = DrawingDoc.ReferencedDocumentDescriptors.Item(1).ReferencedFileDescriptor

But I see now that you're using a different variable, that hasn't been specifically defined as a DrawingDocument.

 

To simplify, I would still change the following sections of code in your current version:

'CAPTURE OLD FILE INFORMATION---------------------------------------
oOldDoc = oSelected.Item(1).Definition.Document
Dim oOldComp As String = oOldDoc.FullFileName
Dim oOldIDW As String = System.IO.Path.ChangeExtension(oOldComp, oDrawingType)
'CAPTURE NEW FILE INFORMATION----------------------------------------
oNewDoc = oSelected.Item(1).Definition.Document
Dim oNewComp As String = oNewDoc.FullFileName
Dim oNewIDW As String = System.IO.Path.ChangeExtension(oNewComp, oDrawingType)

because the "System.IO.Path.GetFullPath()" was not necessary.

 

But good to hear you've got it working now. 👍

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 14 of 20

Kassenbouw
Enthusiast
Enthusiast

This allmost works for me. I'm selecting the part, then save it as a new number on my workspace. Then I'm getting the question if I want to save the session edits prior to delete. When I choose "No" the action is cancelled. If I choose "Yes" I have to save again to my workspace. 

After that the drawning is created, the refference is changed and the assembly is active again. 

Is there a way to skip the save session prior to delete part? 

0 Likes
Message 15 of 20

peterjoachim
Enthusiast
Enthusiast

The "Save session edits to **** prior to delete?" prompt shouldn't have an effect on it. I just tested this and it worked with both a yes or a no selection. There must be something else going on. 

The only way to "skip" this prompt is to set a permanent response by selecting "Do not show this message again ever", but I don't think I would recommend that.

0 Likes
Message 16 of 20

Kassenbouw
Enthusiast
Enthusiast

Could this have something to do with the number generator I'm using from Vault?

0 Likes
Message 17 of 20

peterjoachim
Enthusiast
Enthusiast

It shouldn't, because I am also using the Vault number generator. What version of Inventor are you using?

0 Likes
Message 18 of 20

Kassenbouw
Enthusiast
Enthusiast

I'm using Inventor Professional 2021.

0 Likes
Message 19 of 20

bram4PQQD
Explorer
Explorer

Hello,

 

I am using this iLogic rule to replace my components and it works great.

However, some drawings have a dwg extension. When exchanging parts with a dwg drawing, I get the message that the drawing cannot be found. Can the code be modified so that idw and dwg can both be found? Or can I modify this code to work for dwg?

 

 

0 Likes
Message 20 of 20

yuzeaa
Advocate
Advocate

We don't need "AssemblyBonusTools_SaveAndReplaceComponentCmd".

Following codes give you three path choices:

1.Parent Path(run rule whithout selection)

2.Occurrence Path(select an occurrence first)

3.Last Path(click 'cancel buttion')

txtfile = "C:\Users\Public\Documents\temp.txt"
If System.IO.File.Exists(txtfile) Then 
oRead = System.IO.File.ReadAllText(txtfile)
LastPath = IO.Path.GetDirectoryName(oRead) & "\"
End If 

Dim oDoc As AssemblyDocument
	oDoc = ThisApplication.ActiveEditDocument
Dim oOcc As ComponentOccurrence

Select Case oDoc.SelectSet.Count
	Case 0
	oOcc = ThisApplication.CommandManager.Pick(kAssemblyOccurrenceFilter, "Select part")
	If oOcc Is Nothing Then Return
	FileName = oOcc.Definition.Document.Fulldocumentname
	NewPathName = IO.Path.GetDirectoryName(oDoc.FullDocumentName) & "\" &  IO.Path.GetFileNameWithoutExtension(FileName) & "copy"
	Case 1
	oOcc = oDoc.SelectSet.Item(1)
	FileName = oOcc.Definition.Document.Fulldocumentname
	NewPathName = IO.Path.GetDirectoryName(FileName) & "\" &  IO.Path.GetFileNameWithoutExtension(FileName) & "copy" 
    Case Else 
	oDoc.SelectSet.Clear
	Return
End Select

idwName = Left(FileName,Len(FileName)-4) & ".idw"
extName = IO.Path.GetExtension(FileName)
Dim oFileDlg As Inventor.FileDialog = Nothing
ThisApplication.CreateFileDialog(oFileDlg)
If LCase(extName) = "iam" Then
oFileDlg.Filter = "Inventor Files (*.iam)|*.iam|All Files (*.*)|*.*"
ElseIf LCase(extName) = "ipt" Then
oFileDlg.Filter = "Inventor Files (*.ipt)|*.ipt|All Files (*.*)|*.*"
End If
oFileDlg.DialogTitle = "Replace: " & FileName
'oFileDlg.InitialDirectory = ThisDoc.Path 'do not need InitialDirectory
oFileDlg.FileName = NewPathName
oFileDlg.CancelError = True
On Error Resume Next
oFileDlg.ShowSave()
If Err.Number <> 0 Then
oFileDlg.FileName = LastPath & IO.Path.GetFileNameWithoutExtension(FileName) & "copy"
oFileDlg.ShowSave()
selectedfile = oFileDlg.FileName
ElseIf oFileDlg.FileName <> "" Then
selectedfile = oFileDlg.FileName
End If
If selectedfile Is Nothing Then Return
If Right(selectedfile,4) <> extName Then
selectedfile = selectedfile & LCase(extName)
End If 
newIdwName = Left(selectedfile, Len(selectedfile) -4) & ".idw"
oOcc.Definition.Document.SaveAs(selectedfile, True)
Call oOcc.Replace(selectedfile, False)
If System.IO.File.Exists(idwName) Then
	System.IO.File.Copy(idwName, newIdwName)
	Dim newIdwFile As DrawingDocument= ThisApplication.Documents.Open(newIdwName, True)
newIdwFile.Sheets(1).DrawingViews(1).referencedFile.DocumentDescriptor.ReferencedFileDescriptor.replacereference(selectedfile)
	newIdwFile.Update
	newIdwFile.Save
	newIdwFile.Close
End If
iWrite = System.IO.File.CreateText(txtfile)
iWrite.Write(selectedfile)
iWrite.Close()