Reply
Solved! Go to solution

Use VBA to copy Asm, xlsm and Dft with Revision Manager

Hey,

 

I'm struggling for a while now with the following problem.

With VBA I want to copy an assembly which has a couple of parts and smaller assemblies, an excel file and a draft file.

With a command like this everything works fine with the asm's and parts, the links will be updated to the new directory.

 

Set revman = CreateObject("RevisionManager.Application")

            Set objDoc = revman.Open(oldfilepath)

            objDoc.Copy (newfilepath)

            Set objDoc = revman.Open(oldrelatedfilepath)

            objDoc.Copy (newrelatedfilepath)

 

Even though the procedure is the same for the excel file and the draft in RevisionManager, that command doesn't work. Meaning that the files are copied, but the assembly still links to the old folder. I tried to use "replace" instead of "copy" but it seemed as there is no action at all. For an emergency solution I also tried to just open the file in RM with vba, but the application closes after some miliseconds.

 

I'm happy about every experience and advise. =)

10 REPLIES

Re: Use VBA to copy Asm, xlsm and Dft with Revision Manager

You may need to iterate through all linked documents and distinguish between SE documents and other linked documents , e.g. an Excel workbook. Use RevMgr for SE documents and a normal file copy for others. The following code was working for me with a simple test assembly linked to an excel sheet.

Sub CopyLinkedDocuments(ByVal objDoc As RevisionManager.Document, ByVal strDstPath As String, ByRef copiedFiles As Collections.Specialized.StringDictionary)
  Dim objLinks As RevisionManager.LinkedDocuments = objDoc.LinkedDocuments
  If objLinks IsNot Nothing Then
    Dim objLinkInfo As FileInfo
    Dim strExt As String
    For Each objLinkedDoc As RevisionManager.Document In objLinks
      objLinkInfo = New FileInfo(objLinkedDoc.FullName)
      strExt = objLinkInfo.Extension.ToLower()
      If strExt = ".asm" OrElse strExt = ".par" OrElse strExt = ".dft" OrElse strExt = ".psm" Then
        If Not copiedFiles.ContainsKey(objLinkInfo.FullName) Then
          copiedFiles.Add(objLinkInfo.FullName, "")
          CopyLinkedDocuments(objLinkedDoc, strDstPath, copiedFiles)
          objLinkedDoc.Copy(IO.Path.Combine(strDstPath, objLinkInfo.Name))
        End If
      Else
        ' Do a simple file copy
        copiedFiles.Add(objLinkInfo.FullName, "")
        objLinkInfo.CopyTo(IO.Path.Combine(strDstPath, objLinkInfo.Name), True)
      End If
    Next
  End If
End Sub

'----------------------------------------------------------------------
' REVMGR: Create a copy of an entire assembly
' Sample: 
'   CopySEDocsAndLinks("Coffee Pot.asm", "C:\Program Files\Solid Edge ST8\Training", "C:\temp\Copy")
'----------------------------------------------------------------------
Sub CopySEDocsAndLinks(ByVal strSrcFile AS String, ByVal strSrcPath AS String, ByVal strDstPath As String) 
	Dim copiedFiles As New Collections.Specialized.StringDictionary()
	Dim objTopLevelInfo As New FileInfo(IO.Path.Combine(strSrcPath, strSrcFile))
	Dim objRevMgr As New RevisionManager.Application()
	Dim objDoc As RevisionManager.Document = objRevMgr.Open(objTopLevelInfo.FullName)
	copiedFiles.Add(objTopLevelInfo.FullName, "")
	CopyLinkedDocuments(objDoc, strDstPath, copiedFiles)
	objDoc.Copy(IO.Path.Combine(strDstPath, strSrcFile))
	objRevMgr.Quit()
End Sub

Re: Use VBA to copy Asm, xlsm and Dft with Revision Manager

[ Edited ]

mlue,

 

as requested an example in VBA (executable from within i.e. Excel):

 

Sub CopyAll()

    Dim revMgrApp As RevisionManager.Application
    Dim revMgrDoc As RevisionManager.Document
    
    Dim sourceFileFolderName As String
    Dim sourceFileFileName As String
    Dim destFileFolderName As String
    Dim destFileFileName As String
    
    sourceFileFolderName = "D:\Benutzer\Wku\Etc\Solid Edge\Test01\"
    sourceFileFileName = "Asm00.asm"
    destFileFolderName = "D:\Benutzer\Wku\Etc\Solid Edge\Test02\"
    destFileFileName = "Asm00.asm"
    
    Dim nFileCount As Long
    Dim listOfInputFileNames(1) As Variant
    Dim listOfInputActions(1) As Variant
    Dim listOfNewFileNames(1) As Variant
    Dim newFilePathForAllFiles As Variant
    
    Set revMgrApp = CreateObject("RevisionManager.Application")
    Set revMgrDoc = revMgrApp.OpenFileInRevisionManager(sourceFileFolderName & sourceFileFileName)
    
    nFileCount = 1
    listOfInputFileNames(1) = sourceFileFolderName & sourceFileFileName
    listOfInputActions(1) = CopyAllAction
    listOfNewFileNames(1) = destFileFolderName & destFileFileName
    newFilePathForAllFiles = destFileFolderName
    
    revMgrApp.SetActionForAllFilesInRevisionManager CopyAllAction, newFilePathForAllFiles
    revMgrApp.SetActionInRevisionManager nFileCount, listOfInputFileNames, listOfInputActions, listOfNewFileNames, newFilePathForAllFiles
    
    MsgBox revMgrApp.PerformActionInRevisionManager, vbOKOnly
    
    revMgrApp.Quit
    
End Sub

 

As test i used an assembly structured as follows:

 

 

All files got saved flat to the destination folder (including the linked Excel file) and are correctly linked by the new pathes:

 

 

DFT files have to be handled different:

 

If you just want the DFT file of the top assembly to be copied too, you simply use in the code example above the DFT file of the top assembly. This will work, because the DFT file links to the assembly file and the assembly file links to ... (and so on).

 

To also copy all DFT files of sub components, you have to find and copy them individually and use i.e. the SetPath method of the RevisionManager object to correct the path of their ModelLink(s).

Kind regards,
Wolfgang Kunert - www.wksyspro.de

Re: Use VBA to copy Asm, xlsm and Dft with Revision Manager

Thanks wku!

 

That worked immediately! But I have an additional question - where can I find a tutorial or an overview about all these commands? I would like to have a new filename for the new main assembly and for the excel file. That is probably one line of code, but hard to make up out of nowhere. =)

Re: Use VBA to copy Asm, xlsm and Dft with Revision Manager

[ Edited ]

mlue,

 

unfortunately there doesn't  exist any additional official documentation other than provided by the API help file. Trial and error is the only way Smiley Sad

 

Regarding your wish to rename certain files is not as easy as you might think!

To achieve this you could operate on your copied folder, rename (if required) the top level document by normal file operation, then open the (renamed) top level document into the revision manager and traverse recursively all of its LinkedDocuments. If a LinkedDocument matches your old name criteria you may rename it by using the Rename method of the LinkedDocument object. The revision manager will ensure to correct the link in the parent document adequatly.

As Bernhard has shown in his VB.NET solution, you could take use of a Dictionary object (VBA) to avoid multiple processing of documents.

Another note to internal assembly file names. They might not always end with ".asm", which should be considered when comparing to the old file name.

 

Kind regards,
Wolfgang Kunert - www.wksyspro.de

Re: Use VBA to copy Asm, xlsm and Dft with Revision Manager

Thanks for the answer Wolfgang.

 

That's a pity that there is no proper documentation. Also for me as a beginner it is not easy to translate code from vb.net to vba.

Is there really no easy way to open the top assembly and just select one file and do an operation with this one? The command .SetActionInRevisionManager seems only to work as a batch processing.

 

Regards

Solution
Solution
Accepted by topic author mlue
‎10-07-2015 07:40 AM

Re: Use VBA to copy Asm, xlsm and Dft with Revision Manager

mlue,

 

the keypoint is to traverse the structure beginning from the root file (DFT or ASM) via recursively processing all LinkedDocuments of each LinkedDocument. To give you an idea how to do so, I've prepared the following code for you:

 

Sub Traverse()

    Dim revMgrApp As RevisionManager.Application
    Dim revMgrDoc As RevisionManager.Document
    
    Set revMgrApp = CreateObject("RevisionManager.Application")
    Set revMgrDoc = revMgrApp.OpenFileInRevisionManager("D:\Benutzer\Wku\Etc\Solid Edge\Test02\Asm00.dft")
    
    TraverseLinkedDocuments revMgrDoc
    
    revMgrApp.Quit

End Sub

Private Sub TraverseLinkedDocuments(revMgrDoc As RevisionManager.Document)

    Dim linkedDoc As RevisionManager.Document

    Debug.Print revMgrDoc.FullName
    
    Select Case revMgrDoc.FullName
        Case "D:\Benutzer\Wku\Etc\Solid Edge\Test02\Part01.xlsx"
            revMgrDoc.Replace "D:\Benutzer\Wku\Etc\Solid Edge\Test02\PartXX.xlsx"
            Debug.Print " replaced by D:\Benutzer\Wku\Etc\Solid Edge\Test02\PartXX.xlsx"
    End Select
    
    If IsSolidEdgeDocument(revMgrDoc.FullName) Then
        For Each linkedDoc In revMgrDoc.LinkedDocuments
            TraverseLinkedDocuments linkedDoc
        Next
    End If

End Sub

Private Function IsSolidEdgeDocument(pathName As String) As Boolean

    Select Case LCase(Right(pathName, 4))
        Case ".asm", ".dft", ".par", ".psm"
            IsSolidEdgeDocument = True
        Case Else
            IsSolidEdgeDocument = False
    End Select
    
End Function
Kind regards,
Wolfgang Kunert - www.wksyspro.de

Re: Use VBA to copy Asm, xlsm and Dft with Revision Manager

Alright, now everything works. =) I'm impressed that you wrote an example code for me.
To make it work, I had to add two things, though:
I had to add the SaveAllLinks command to make the changes actually work and secondly i had to change the links such as "D://" to //EURO/ but that is probably only important when you work on a server.
Thanks again

Re: Use VBA to copy Asm, xlsm and Dft with Revision Manager


mlue wrote:
...
I had to add the SaveAllLinks command to make the changes actually work ...

 

Fine, thank you for your feedback and the extra tip

 

Kind regards,
Wolfgang Kunert - www.wksyspro.de

Re: Use VBA to copy Asm, xlsm and Dft with Revision Manager

[ Edited ]

Maybe I'm a bit late in this issue, but this is not working as expected. I will explain:

 


MartinBernhard wrote:

You may need to iterate through all linked documents and distinguish between SE documents and other linked documents , e.g. an Excel workbook. Use RevMgr for SE documents and a normal file copy for others. The following code was working for me with a simple test assembly linked to an excel sheet.

Sub CopyLinkedDocuments(ByVal objDoc As RevisionManager.Document, ByVal strDstPath As String, ByRef copiedFiles As Collections.Specialized.StringDictionary)
  Dim objLinks As RevisionManager.LinkedDocuments = objDoc.LinkedDocuments
  If objLinks IsNot Nothing Then
    Dim objLinkInfo As FileInfo
    Dim strExt As String
    For Each objLinkedDoc As RevisionManager.Document In objLinks
      objLinkInfo = New FileInfo(objLinkedDoc.FullName)
      strExt = objLinkInfo.Extension.ToLower()
      If strExt = ".asm" OrElse strExt = ".par" OrElse strExt = ".dft" OrElse strExt = ".psm" Then
        If Not copiedFiles.ContainsKey(objLinkInfo.FullName) Then
          copiedFiles.Add(objLinkInfo.FullName, "")
          CopyLinkedDocuments(objLinkedDoc, strDstPath, copiedFiles)
          objLinkedDoc.Copy(IO.Path.Combine(strDstPath, objLinkInfo.Name))
        End If
      Else
        ' Do a simple file copy
        copiedFiles.Add(objLinkInfo.FullName, "")
        objLinkInfo.CopyTo(IO.Path.Combine(strDstPath, objLinkInfo.Name), True)
      End If
    Next
  End If
End Sub

'----------------------------------------------------------------------
' REVMGR: Create a copy of an entire assembly
' Sample: 
'   CopySEDocsAndLinks("Coffee Pot.asm", "C:\Program Files\Solid Edge ST8\Training", "C:\temp\Copy")
'----------------------------------------------------------------------
Sub CopySEDocsAndLinks(ByVal strSrcFile AS String, ByVal strSrcPath AS String, ByVal strDstPath As String) 
	Dim copiedFiles As New Collections.Specialized.StringDictionary()
	Dim objTopLevelInfo As New FileInfo(IO.Path.Combine(strSrcPath, strSrcFile))
	Dim objRevMgr As New RevisionManager.Application()
	Dim objDoc As RevisionManager.Document = objRevMgr.Open(objTopLevelInfo.FullName)
	copiedFiles.Add(objTopLevelInfo.FullName, "")
	CopyLinkedDocuments(objDoc, strDstPath, copiedFiles)
	objDoc.Copy(IO.Path.Combine(strDstPath, strSrcFile))
	objRevMgr.Quit()
End Sub

 

I have tried this iterative approach, from bottom to top and, although it effectively copies and re-links copied parts, I have found that original assembly gets the links of a number of its nodes (at different depth levels) updated to the new locations. Since original files are kept, most of the time this is not noticeable since SE catches "old" file from relative path, rather than using the new absolute path, which has been updated to the new location.

 

In order to show the problem, you can modify the code in order to change filenames when copying. Although, in the original assembly, all original files are kept (with their original name, of course), if you open it, you can see that a number of assemblies are linked to the new copied files, using their updated names. In short, the original assembly structure has been destroyed.

 

An even simpler approach is watching original .asm files Modification Date on Windows. You'll see that, after copied to a new location, those files have been modified (Modification Date updated), which shouldn't be the case, since our objective is making a new copy and preserve original assembly and its structure.

 

As far as I can see, the problem here is that some of the original assemblies have been modified prior to being copied in the iterative game. I'm sure the solution is close, but I guess this is not yet polished.

 

I have tried to reverse the iterative approach, thus copying first top level objects and then their children. In this case the original assembly remais intact, but not all files are copied and, in short, the result copied assembly is a mesh of broken links. With all, the bottom to top approach seems a better path!

 

Thanks in advance, hope this helps someone.