Using iLogic to Save As Components in an assembly

Using iLogic to Save As Components in an assembly

Anonymous
Not applicable
1,246 Views
7 Replies
Message 1 of 8

Using iLogic to Save As Components in an assembly

Anonymous
Not applicable

Hello,

 

Please could someone help me? I need a piece of iLogic code that will save as a part (or assembly) inside of a main assembly if it has a certain file name.

 

ie

If part in assembly is named "x" Then

Save As that part to name "y"

 

If you could control the file path destination as well that would be brilliant, although the file will always go in the same folder as the parent assembly.

 

Any help would be greatly appreciated, I've looked for a while but cannot find the answer I'm looking for,

 

Thank you

0 Likes
1,247 Views
7 Replies
Replies (7)
Message 2 of 8

Stakin
Collaborator
Collaborator

This rule will create a sub directory named “SaveAs” at the acitive document's position.

and

1\if acitive document is a part, it save as it in the new directory,and named the new file  to "****_SaveAs.ipt" (***is the origin name of it)

2\if acitive document is a assembly, it save as it in the new directory,and named the new file  to "****_SaveAs.iam" (***is the origin name of it);and save all the part,subasm, in the new directory with a  suffix “_SaveAs”。

 

Sub main
Dim oDoc As Document
oDoc = ThisApplication.ActiveDocument
Dim oFullFileName As String
oFullFileName=oDoc.FullFileName
Dim oPath As String
oPath = Left(oFullFileName, InStrRev(oFullFileName, "\")) & "SaveAs\"
Dim oTargetDir As System.IO.DirectoryInfo
	oTargetDir	=New System.IO.DirectoryInfo(oPath)
If Not oTargetDir.Exists Then
	oTargetDir.Create()
End If
If oDoc.DocumentType = Inventor.DocumentTypeEnum.kPartDocumentObject Then
	oDocSaveAs(oDoc,oPath)
ElseIf oDoc.DocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then
	Dim oAsmDoc As AssemblyDocument
	oAsmDoc=oDoc
	oAsmSaveAs(oAsmDoc,oPath)
End If	
End Sub

Private Function oAsmSaveAs(oDoc As AssemblyDocument,oPath As String)
Call oDocSaveAs(oDoc,oPath)
Dim odef As AssemblyComponentDefinition
odef=oDoc.ComponentDefinition
Dim oCC As ComponentOccurrence
For Each oCC In odef.Occurrences
	If oCC.DefinitionDocumentType = Inventor.DocumentTypeEnum.kPartDocumentObject Then		
		Dim oPrt As PartDocument
		oPrt = oCC.Definition.Document
		Call oDocSaveAs(oPrt,oPath)
	ElseIf oCC.DefinitionDocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then
		Dim oSubAsm As AssemblyDocument
		oSubAsm=oCC.Definition.Document
		Call oAsmSaveAs(oSubAsm,oPath)
	End If	
Next
End Function

Private Function oDocSaveAs(oDoc As Document,oPath As String)
Dim opartName As String
opartName = oDoc.FullFileName
Dim ostart As Integer=InStrRev(opartName, "\")
Dim oFullName As String=Right(opartName,Len(opartName)-ostart)
Dim oFilesuffix As String = Right(oFullName, 4)
Dim oFileNameBody As String = Left(oFullName, Len(oFullName) -4)
Dim oFileName As String= oPath & oFileNameBody & "_SaveAs" & oFilesuffix
If Not System.IO.File.Exists(oFileName) Then
	oDoc.SaveAs(oFileName,True)
End If	
End Function

 

0 Likes
Message 3 of 8

Stakin
Collaborator
Collaborator

The previous rule didn't to change  parts to the new created file  in Assembly,

Try this one, this version can package all the Parts to one folder named "SaveAs"

Sub main
Dim oDoc As Document
oDoc = ThisApplication.ActiveDocument
Dim oFullFileName As String
oFullFileName=oDoc.FullFileName
Dim oPath As String
oPath = Left(oFullFileName, InStrRev(oFullFileName, "\")) & "SaveAs\"
Dim oTargetDir As System.IO.DirectoryInfo
	oTargetDir	=New System.IO.DirectoryInfo(oPath)
If Not oTargetDir.Exists Then
	oTargetDir.Create()
End If
If oDoc.DocumentType = Inventor.DocumentTypeEnum.kPartDocumentObject Then
	Dim oNewPartName As String
	oNewPartName=oGetFileName(oDoc,oPath)
	oDocSaveAs(oDoc,oNewPartName)
ElseIf oDoc.DocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then
	Dim oAsmDoc As AssemblyDocument
	oAsmDoc=oDoc
	oAsmSaveAs(oAsmDoc,oPath)
End If	
End Sub

Private Function oAsmSaveAs(oDoc As AssemblyDocument,oPath As String)
Dim oFileName As String = oGetFileName(oDoc,oPath)
Dim oNewAsmDoc As AssemblyDocument
If Not System.IO.File.Exists(oFileName) Then	
	oNewAsmDoc=ThisApplication.Documents.Add(Inventor.DocumentTypeEnum.kAssemblyDocumentObject,,True)
	oNewAsmDoc.SaveAs(oFileName, False)
Else
	Exit Function
End If
Dim oNewdef As AssemblyComponentDefinition
oNewdef = oNewAsmDoc.ComponentDefinition
Dim oNewCC As ComponentOccurrence
Dim odef As AssemblyComponentDefinition
odef=oDoc.ComponentDefinition
Dim oCC As ComponentOccurrence
Dim oNewPartName As String
For Each oCC In odef.Occurrences
	If oCC.DefinitionDocumentType = Inventor.DocumentTypeEnum.kPartDocumentObject Then		
		Dim oPrt As PartDocument
		oPrt = oCC.Definition.Document
		oNewPartName=oGetFileName(oPrt,oPath)
		Call oDocSaveAs(oPrt,oNewPartName)
		oNewCC = oNewdef.Occurrences.Add(oNewPartName, oCC.Transformation)
		oNewCC.Grounded=True
	ElseIf oCC.DefinitionDocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then
		Dim oSubAsm As AssemblyDocument
		oSubAsm = oCC.Definition.Document
		Call oAsmSaveAs(oSubAsm, oPath)
		oNewPartName=oGetFileName(oSubAsm,oPath)
		oNewCC = oNewdef.Occurrences.Add(oNewPartName, oCC.Transformation)
		oNewCC.Grounded=True
	End If	
Next
oNewAsmDoc.Close
End Function

Private Function oDocSaveAs(ByVal oDoc As Document,ByVal oNewPartName As String)
If Not System.IO.File.Exists(oNewPartName) Then
	oDoc.SaveAs(oNewPartName,True)
End If	
End Function

Private Function oGetFileName(ByVal oDoc As Document,ByVal oPath As String) As String
	Dim opartName As String
	opartName = oDoc.FullFileName
	Dim ostart As Integer=InStrRev(opartName, "\")
	Dim oFullName As String=Right(opartName,Len(opartName)-ostart)
	Dim oFilesuffix As String = Right(oFullName, 4)
	Dim oFileNameBody As String = Left(oFullName, Len(oFullName) -4)
	oGetFileName= oPath & oFileNameBody & "_SaveAs" & oFilesuffix	
End Function	

Like this: asm0.iam,

before run,

the file is:

Stakin_1-1633657880146.png

 

the model tree  is

Stakin_0-1633657765714.png

After:

the folder

Stakin_2-1633657944659.png

in the "saveas" folder

Stakin_3-1633657987876.png

the Asm0_SaveAs.iam Model tree:

Stakin_4-1633658228313.png

 

 

 

 

0 Likes
Message 4 of 8

Anonymous
Not applicable

That's brilliant thank you I will have a look

0 Likes
Message 5 of 8

RNate
Participant
Participant

This works really well, and I would like to modify it, but is so far past my code writing understanding that I am having difficulty. Do you have suggestions for:

  1. I would like to use this as an external rule, does any consideration need to be made beyond having an internal rule that runs the external rule?
  2. Opening a dialogue where the user can navigate to the desired target directory instead of creating a "Save As" sub file in the current directory (do this one time, save all new files the same new location)
  3. For each component, show the user the current file name (without path or extension), and provide an input for a new file name (without path or extension) to be saved as
  4. Copy any drawings of the assembly and components (some components may have drawings, some may not)
  5. Copy the rule(s) to the new file(s) so this could be repeated using copies if needed.
  6. I have renamed subcomponents in the assembly tree in order to push parameter changes to them when using the "Save and Replace" tool. These have file names like WFES011, WFES012, etc. Can that renaming be kept in the new assembly? Maybe there is a better way to send parameters to subcomponents?

That is a lot to ask for, I appreciate any help you can give on this.

0 Likes
Message 6 of 8

A.Acheson
Mentor
Mentor

Here is some help on the requested changes.

 

1. This looks like an external rule allready. You wouldn't want an internal rule when trying to copy files..

2. From this post to select a folder

Dim dlgFolder = New FolderBrowserDialog

'Set Root Path from where to start from
dlgFolder.SelectedPath = "C:\Temp"

dlgFolder.ShowDialog

Dim absolutePath As String = dlgFolder.SelectedPath

MessageBox.Show(absolutePath, "absolutePath")

3. Haven't tested this code but the function oGetFileName looks like it will retrieve the filename so feed it into an inputbox. Codesnippet is in the ilogic editor under messagebox. 

4. Copying a drawing is a different task so maybe best to get it running as a separate rule before trying to integrate to this larger rule. Here is a post replacing a reference to a drawing. 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 7 of 8

RNate
Participant
Participant

I have tweaked the ilogic somewhat succesfully. A few outstanding issues:

1. The new files no longer contain any rules, forms, or parameters, these need to be kept from the original.

2. If the top level assembly contains a subassembly, the rule fails, I think something is weird about nesting the oAsmSaveAs function inside itself

3. If the assembly contains multiple occurrences of the same part, it wants to make additional copies rather than replacing all occurrences.

4. I'm open to code improvements, I suspect there are better ways of changing paths and file extensions: maybe "ThisDoc.ChangeExtension"? Not sure on how to implement though

 

Sub main
Dim oDoc As Document = ThisApplication.ActiveDocument

'Set directory for new file creation
Dim dlgFolder = New FolderBrowserDialog()
dlgFolder.SelectedPath = "F:\AFE Crane\2022 Jobs\0 end stop target"
dlgFolder.ShowNewFolderButton = True
dlgFolder.Description = "Select target folder for new files"
dlgFolder.ShowDialog()
Dim oPath As String = dlgFolder.SelectedPath & "\"

'is file a part or assembly
If oDoc.DocumentType = Inventor.DocumentTypeEnum.kPartDocumentObject Then
	Dim oNewPartName As String
	oNewPartName = oGetFileName(oDoc, oPath) 'run oGetFileName function
	oDocSaveAs(oDoc, oNewPartName) 'run oDocSaveAs function
ElseIf oDoc.DocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then
	Dim oAsmDoc As AssemblyDocument
	oAsmDoc=oDoc
	oAsmSaveAs(oAsmDoc, oPath) 'run oAsmSaveAs function
End If
End Sub

Private Function oAsmSaveAs(oDoc As AssemblyDocument,oPath As String)
Dim oFileName As String = oGetFileName(oDoc, oPath) 'new assembly name
Dim oNewAsmDoc As AssemblyDocument

'check if same new file already exist and that oGetFileName function was not cancelled and did not return a blank string
If Not System.IO.File.Exists(oFileName) And Not oFileName = Nothing Then	
	oNewAsmDoc=ThisApplication.Documents.Add(Inventor.DocumentTypeEnum.kAssemblyDocumentObject,,True)
	oNewAsmDoc.SaveAs(oFileName, False)
	
	Dim oCurrentDrw As String
	oCurrentDrw = Left(oDoc.FullFileName, InStrRev(oDoc.FullFileName, ".")) & "idw"
	If System.IO.File.Exists(oCurrentDrw) 'does current assembly have a drawing? Save it and update references
	    Dim oNewDrw As String
		oNewDrw = Left(oFileName, InStrRev(oFileName, ".")) & "idw"

		'open original drawing
	    oDestinationDoc = ThisApplication.Documents.Open(oCurrentDrw)
	    oDestinationDoc.saveas(oNewDrw,True)
	    oDestinationDoc.Close
		
	    'open new drawing
	    oDestinationDoc = ThisApplication.Documents.Open(oNewDrw)
	    Dim oDocDescriptor As DocumentDescriptor
	    oDocDescriptor = oDestinationDoc.ReferencedDocumentDescriptors.Item(1)
	    
	    Dim oFileDescriptor As FileDescriptor
	    oFileDescriptor = oDocDescriptor.ReferencedFileDescriptor
	    
	    oFileDescriptor.ReplaceReference(oFileName)
	    oDestinationDoc.Update()
	    oDestinationDoc.Save
		oDestinationDoc.Close
	End If
Else
	MessageBox.Show("Operation Cancelled")
	Exit Function
End If
Dim oNewdef As AssemblyComponentDefinition
oNewdef = oNewAsmDoc.ComponentDefinition 'create new assembly object
Dim oNewCC As ComponentOccurrence
Dim odef As AssemblyComponentDefinition
odef = oDoc.ComponentDefinition
Dim oCC As ComponentOccurrence
Dim oNewPartName As String
For Each oCC In odef.Occurrences
	If oCC.DefinitionDocumentType = Inventor.DocumentTypeEnum.kPartDocumentObject Then		
		Dim oPrt As PartDocument
		oPrt = oCC.Definition.Document
		oNewPartName = oGetFileName(oPrt, oPath)
		Call oDocSaveAs(oPrt,oNewPartName)
		oNewCC = oNewdef.Occurrences.Add(oNewPartName, oCC.Transformation)
		oNewCC.Grounded = True
		oNewCC.Name = oCC.Name
	ElseIf oCC.DefinitionDocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then
		Dim oSubAsm As AssemblyDocument
		oSubAsm = oCC.Definition.Document
		Call oAsmSaveAs(oSubAsm, oPath)
		oNewPartName = oGetFileName(oSubAsm, oPath)
		oNewCC = oNewdef.Occurrences.Add(oNewPartName, oCC.Transformation)
		oNewCC.Grounded = True
		oNewCC.Name = oCC.Name
	End If	
Next
oNewAsmDoc.Close
End Function

Private Function oDocSaveAs(ByVal oDoc As Document,ByVal oNewPartName As String)
If Not System.IO.File.Exists(oNewPartName) And Not oNewPartName = Nothing Then
	oDoc.SaveAs(oNewPartName, True)
	Dim oCurrentDrw As String
	oCurrentDrw = Left(oDoc.FullFileName, InStrRev(oDoc.FullFileName, ".")) & "idw"
	If System.IO.File.Exists(oCurrentDrw)
	    Dim oNewDrw As String
		oNewDrw = Left(oNewPartName, InStrRev(oNewPartName, ".")) & "idw"

		'open original drawing
	    oDestinationDoc = ThisApplication.Documents.Open(oCurrentDrw)
	    oDestinationDoc.saveas(oNewDrw,True)
	    oDestinationDoc.Close
		
	    'open new drawing
	    oDestinationDoc = ThisApplication.Documents.Open(oNewDrw)
	    Dim oDocDescriptor As DocumentDescriptor
	    oDocDescriptor = oDestinationDoc.ReferencedDocumentDescriptors.Item(1)
	    
	    Dim oFileDescriptor As FileDescriptor
	    oFileDescriptor = oDocDescriptor.ReferencedFileDescriptor
	    
	    oFileDescriptor.ReplaceReference(oNewPartName)
	    oDestinationDoc.Update()
	    oDestinationDoc.Save
		oDestinationDoc.Close
	End If
Else
	MessageBox.Show("File not saved")
	Exit Function
End If	
End Function

Private Function oGetFileName(ByVal oDoc As Document,ByVal oPath As String) As String
	oGetFileName = Nothing
	Dim oDesc As String = oDoc.PropertySets.Item("Design Tracking Properties").Item("Description").Value
	
	'determine file path and name parts
	Dim opartName As String
	opartName = oDoc.FullFileName 'full file name with path and extension
	Dim ostart As Integer = InStrRev(opartName, "\")
	Dim oend As Integer = InStrRev(opartName, ".") -1
	Dim oFullName As String = Right(opartName, Len(opartName) -ostart) 'file name with extension
	Dim oFilesuffix As String = Right(opartName, Len(opartName) -oend) 'extension
	Dim oFileNameBody As String = Left(oFullName, Len(oFullName)-(Len(opartName) - oend)) 'file name without extension
	
	Dim oInput As String
	Dim TryFileName As String
	While oGetFileName = Nothing
		oInput = InputBox("Description: " & oDesc _ 'launch input box for new file name, line 1
		& vbCrLf & " " _ 'line 2
		& vbCrLf & "Source Path: " & oDoc.FullFileName & "\" _ 'line 3
		& vbCrLf & " " _ 'line 4
		& vbCrLf & "Target Path: " & oPath _ 'line 5
		& vbCrLf & " " _ 'line 6
		& vbCrLf & "New File name: ", "Save As", oFileNameBody & "_copy") 'line7, intial input box content
		TryFileName = oPath & oInput & oFilesuffix
			If oInput = "" Then
				Exit Function
			Else
				If System.IO.File.Exists(TryFileName) Then
					MessageBox.Show("The file already exists")
			    Else 
			  		oGetFileName = TryFileName
				End If
			End If
		End While
End Function

 

0 Likes
Message 8 of 8

ralfmja
Advocate
Advocate

hi @RNate,

 

Any progress in the rule's operation, especially regarding point 2 and subassemblies within the assembly?

 

And point 3 as well? 🙂 

 

Thanks in advance,

ralfmja

0 Likes