Save and Replace Rule

Save and Replace Rule

layochim
Enthusiast Enthusiast
141 Views
13 Replies
Message 1 of 14

Save and Replace Rule

layochim
Enthusiast
Enthusiast

I'm trying to modify a rule i acquired to have it save and replace all parts in an iam that begin with only the characters "Project" since there are content center parts i cant have these be replaced.  Also, there are children iams in the parent iam i wish to save and replace as well.

 

For example original file name is "Project-200000 FRAME SIDE A"  I'd like to replace only "Project" with 5 characters such as 25100 for example.  Can anyone help me with this?

 

Below is the code i'm working with and attached in a txt file.

 

If ThisApplication.ActiveDocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
	MsgBox("This rule '" & iLogicVb.RuleName & "' only works for Assembly Documents.",vbOK, "WRONG DOCUMENT TYPE")
	Return
End If

Dim oADoc As AssemblyDocument = ThisApplication.ActiveDocument

Dim oFileDlg As Inventor.FileDialog = Nothing
ThisApplication.CreateFileDialog(oFileDlg)
oFileDlg.Filter = "Autodesk Inventor Assembly Files (*.iam)|*.iam"
oFileDlg.InitialDirectory = ThisApplication.DesignProjectManager.ActiveDesignProject.WorkspacePath
oFileDlg.FileName = IO.Path.GetFileName(oADoc.FullFileName).TrimEnd("."c,"i"c,"a"c,"m"c)
oFileDlg.DialogTitle = "Specify New Name & Location For Copied Assembly"
oFileDlg.CancelError = True

On Error Resume Next
oFileDlg.ShowSave
If Err.Number <> 0 Then
	MsgBox("No File Saved.", vbOKOnly, "DIALOG CANCELED")
ElseIf oFileDlg.FileName <> "" Then
	oNewFileName = oFileDlg.FileName
	oADoc.SaveAs(oNewFileName, False)
End If

oADoc = Nothing

InventorVb.DocumentUpdate()

oADoc = ThisApplication.ActiveDocument

' Get the new base name without extension and path
Dim oNewBaseName As String = IO.Path.GetFileNameWithoutExtension(oADoc.FullFileName)

' Extract the new prefix (everything before the first hyphen)
Dim oNewPrefix As String = ""
Dim oHyphenPos As Integer = oNewBaseName.IndexOf("-")
If oHyphenPos > 0 Then
    oNewPrefix = oNewBaseName.Substring(0, oHyphenPos)
End If

' Calculate how many characters to keep from original name (excluding "Project")
' Based on your example: "Project-100000" -> "250001-100000"
' We keep 8 characters total, minus 6 for "Project" = 6 characters after "Project"
Dim oCharsToKeepAfterProject As Integer = oNewBaseName.Length - oNewPrefix.Length

Dim oReferenceSuffix As String
For Each oRefDoc As Document In oADoc.AllReferencedDocuments
	ThisApplication.Documents.Open(oRefDoc.FullFileName,False)
	
	' Get original filename without extension
	Dim oOriginalName As String = IO.Path.GetFileNameWithoutExtension(oRefDoc.FullFileName)
	
	' Check if it starts with "Project" and extract the suffix
	If oOriginalName.StartsWith("Project") And oOriginalName.Length > 7 Then
		' Take the specified number of characters after "Project"
		Dim oAfterProject As String = oOriginalName.Substring(7)
		If oAfterProject.Length >= oCharsToKeepAfterProject Then
			oReferenceSuffix = oAfterProject.Substring(0, oCharsToKeepAfterProject)
		Else
			oReferenceSuffix = oAfterProject ' Use all available characters if less than needed
		End If
	Else
		' If it doesn't start with "Project", use a fallback approach
		' You might want to modify this based on your specific needs
		oReferenceSuffix = oOriginalName
	End If
	
	' Save with new naming convention
	If oRefDoc.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
		oRefDoc.SaveAs(Left(oADoc.FullFileName, Len(oADoc.FullFileName) -4) & "\" & oNewPrefix & oReferenceSuffix & ".ipt", True)
	ElseIf oRefDoc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
		oRefDoc.SaveAs(Left(oADoc.FullFileName, Len(oADoc.FullFileName) -4) & "\" & oNewPrefix & oReferenceSuffix & ".iam", True)
	End If
	oRefDoc.Close
Next

Dim oOccDoc As Document
Dim oOccNewFileName As String
For Each oOcc As ComponentOccurrence In oADoc.ComponentDefinition.Occurrences
	oOccDoc = oOcc.Definition.Document
	
	' Get original filename without extension
	Dim oOriginalName As String = IO.Path.GetFileNameWithoutExtension(oOccDoc.FullFileName)
	
	' Check if it starts with "Project" and extract the suffix
	If oOriginalName.StartsWith("Project") And oOriginalName.Length > 7 Then
		' Take the specified number of characters after "Project"
		Dim oAfterProject As String = oOriginalName.Substring(7)
		If oAfterProject.Length >= oCharsToKeepAfterProject Then
			oReferenceSuffix = oAfterProject.Substring(0, oCharsToKeepAfterProject)
		Else
			oReferenceSuffix = oAfterProject
		End If
	Else
		oReferenceSuffix = oOriginalName
	End If
	
	' Build new filename
	If oOccDoc.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
		oOccNewFileName = Left(oADoc.FullFileName,Len(oADoc.FullFileName)-4) & "\" & oNewPrefix & oReferenceSuffix & ".ipt"
	ElseIf oOccDoc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
		oOccNewFileName = Left(oADoc.FullFileName,Len(oADoc.FullFileName)-4) & "\" & oNewPrefix & oReferenceSuffix & ".iam"
	End If
	oOcc.Replace(oOccNewFileName, True)
Next

 

0 Likes
Accepted solutions (1)
142 Views
13 Replies
Replies (13)
Message 2 of 14

ryan.rittenhouse
Advocate
Advocate

Here's code that should work and can be tweaked to fit your needs. It starts with a given assembly document (ThisDoc.Document in the test case) and recursively goes through everything looking for files to replace. It will suppress/unsuppress components as needed. Let me know how it goes.

 

Option Explicit On
Sub Main()
	
	Dim prefix As String = "25100"
	CopyAndReplace(ThisDoc.Document, prefix)
	
End Sub 'Main

Sub CopyAndReplace(doc As AssemblyDocument, prefix As String)
	
	Dim fileName As String
	Dim newFileName As String
	Dim suppressed As Boolean
	For Each comp As ComponentOccurrence In doc.ComponentDefinition.Occurrences
		fileName = GetFileName(comp)
		If fileName Is Nothing Then Continue For
		If Not fileName.StartsWith("Project") Then Continue For
		newFileName = fileName.Replace("Project", prefix)
		
		suppressed = comp.Suppressed
		If suppressed Then comp.Unsuppress
			
		CopyFile(fileName, newFileName)
		comp.Replace(newFileName, True)
		
		If TypeOf comp.Definition Is AssemblyComponentDefinition Then CopyAndReplace(comp.Definition.Document, prefix)
		
		If suppressed Then comp.Suppress
	Next comp

End Sub 'CopyAndReplace

Sub CopyFile(sourceFile As String, targetFile As String)

    If Not System.IO.File.Exists(targetFile) Then System.IO.File.Copy(sourceFile, targetFile, True)
    My.Computer.FileSystem.GetFileInfo(targetFile).IsReadOnly = False
    
End Sub 'CopyFile

Function GetFileName(comp As ComponentOccurrence) As String

    Dim fileName As String = Nothing

    If comp IsNot Nothing AndAlso comp.ReferencedFileDescriptor IsNot Nothing Then
        fileName = comp.ReferencedFileDescriptor.FullFileName
    End If

    Return fileName

End Function 'GetFilename
If this solved your problem, or answered your question, please click Accept Solution.
0 Likes
Message 3 of 14

layochim
Enthusiast
Enthusiast

I tried the code but nothing happened.

0 Likes
Message 4 of 14

ryan.rittenhouse
Advocate
Advocate

Can you post some of your file names? Are they capitalized the same ("Project") as the code is looking for?

If this solved your problem, or answered your question, please click Accept Solution.
0 Likes
Message 5 of 14

layochim
Enthusiast
Enthusiast

Yes, they're all capitalized.  The objective is to do a Save As on the conveyor shown below, replacing  the word "PROJECT" in the filename with a conveyor number of consisting of 5 characters.  I've also attached a picture of the browser as well.

 

layochim_0-1757443429101.png

 

0 Likes
Message 6 of 14

ryan.rittenhouse
Advocate
Advocate

That's the problem. In your example you only capitalized the first letter. Edit the code and replace "Project" with "PROJECT" and it'll work.

If this solved your problem, or answered your question, please click Accept Solution.
0 Likes
Message 7 of 14

layochim
Enthusiast
Enthusiast

I've replaced the words in the code with no response.

0 Likes
Message 8 of 14

ryan.rittenhouse
Advocate
Advocate

Please confirm the actual file names of what you are trying ot rename. Not the names in the model browser (unless that's what you want it to go by), the names of the files on the disk. If you need to re-copy and replace base on the model browser name, that's a different program

If this solved your problem, or answered your question, please click Accept Solution.
0 Likes
Message 9 of 14

layochim
Enthusiast
Enthusiast

The second case, to replace only the model browser iams any ipts within iams and individual ipts that have the prefix "PROJECT".  My apologies i may not have been clear on what my objective is.

0 Likes
Message 10 of 14

ryan.rittenhouse
Advocate
Advocate

I did find a case where the code might not work for you. I made an update and added logging. If it's still not working, reply with the iLogic log:

Option Explicit On
Sub Main()
	
	Dim prefix As String = "25100"
	CopyAndReplace(ThisDoc.Document, prefix)
	
End Sub 'Main

Sub CopyAndReplace(doc As AssemblyDocument, prefix As String)
	
	Dim fileName As String
	Dim newFileName As String
	Dim suppressed As Boolean
	For Each comp As ComponentOccurrence In doc.ComponentDefinition.Occurrences
		fileName = GetFileName(comp)
		If fileName Is Nothing Then Continue For
		If Not System.IO.Path.GetFileName(fileName).StartsWith("PROJECT") Then
			Logger.Info("Skipping: " & comp.Name)
			Continue For
		Else
			Logger.Info("Copying: " & comp.Name)
		End If
		newFileName = fileName.Replace("PROJECT", prefix)
		
		suppressed = comp.Suppressed
		If suppressed Then comp.Unsuppress
			
		CopyFile(fileName, newFileName)
		comp.Replace(newFileName, True)
		
		If TypeOf comp.Definition Is AssemblyComponentDefinition Then CopyAndReplace(comp.Definition.Document, prefix)
		
		If suppressed Then comp.Suppress
	Next comp

End Sub 'CopyAndReplace

Sub CopyFile(sourceFile As String, targetFile As String)

    If Not System.IO.File.Exists(targetFile) Then System.IO.File.Copy(sourceFile, targetFile, True)
    My.Computer.FileSystem.GetFileInfo(targetFile).IsReadOnly = False
    
End Sub 'CopyFile

Function GetFileName(comp As ComponentOccurrence) As String

    Dim fileName As String = Nothing

    If comp IsNot Nothing AndAlso comp.ReferencedFileDescriptor IsNot Nothing Then
        fileName = comp.ReferencedFileDescriptor.FullFileName
    End If

    Return fileName

End Function 'GetFilename
If this solved your problem, or answered your question, please click Accept Solution.
0 Likes
Message 11 of 14

layochim
Enthusiast
Enthusiast

Oh Wow! This worked like a treat!  The only action that I'm hoping to get is to be able to do a Save As on the Parent conveyor before running the rule, to allow all the new files to be saved under the respected project folder.  Is that possible?

0 Likes
Message 12 of 14

ryan.rittenhouse
Advocate
Advocate
Accepted solution

I've updated to code to follow the same rules, replacing PROJECT with the prefix on the main document. Feel free to edit it if you want different behavior

Option Explicit On
Sub Main()
	
	Dim prefix As String = "25100"
	Dim fileName As String = System.IO.Path.GetFileName(ThisDoc.Document.FullFileName)
	Dim newFileName As String = fileName.Replace("PROJECT", prefix)
	If newFileName <> fileName Then ThisDoc.Document.SaveAs(ThisDoc.Path & "\" & newFileName, False)
	
	CopyAndReplace(ThisDoc.Document, prefix)
	
End Sub 'Main

Sub CopyAndReplace(doc As AssemblyDocument, prefix As String)
	
	Dim fileName As String
	Dim newFileName As String
	Dim suppressed As Boolean
	For Each comp As ComponentOccurrence In doc.ComponentDefinition.Occurrences
		fileName = GetFileName(comp)
		If fileName Is Nothing Then Continue For
		If Not System.IO.Path.GetFileName(fileName).StartsWith("PROJECT") Then
			Logger.Info("Skipping: " & comp.Name)
			Continue For
		Else
			Logger.Info("Copying: " & comp.Name)
		End If
		newFileName = fileName.Replace("PROJECT", prefix)
		
		suppressed = comp.Suppressed
		If suppressed Then comp.Unsuppress
			
		CopyFile(fileName, newFileName)
		comp.Replace(newFileName, True)
		
		If TypeOf comp.Definition Is AssemblyComponentDefinition Then CopyAndReplace(comp.Definition.Document, prefix)
		
		If suppressed Then comp.Suppress
	Next comp

End Sub 'CopyAndReplace

Sub CopyFile(sourceFile As String, targetFile As String)

    If Not System.IO.File.Exists(targetFile) Then System.IO.File.Copy(sourceFile, targetFile, True)
    My.Computer.FileSystem.GetFileInfo(targetFile).IsReadOnly = False
    
End Sub 'CopyFile

Function GetFileName(comp As ComponentOccurrence) As String

    Dim fileName As String = Nothing

    If comp IsNot Nothing AndAlso comp.ReferencedFileDescriptor IsNot Nothing Then
        fileName = comp.ReferencedFileDescriptor.FullFileName
    End If

    Return fileName

End Function 'GetFilename
If this solved your problem, or answered your question, please click Accept Solution.
0 Likes
Message 13 of 14

layochim
Enthusiast
Enthusiast

This is great, thank you very much for this!

0 Likes
Message 14 of 14

layochim
Enthusiast
Enthusiast

@ryan.rittenhouse is there a way to also get the "Part Number" in the iProperties to update with the new file name as well?

0 Likes