11 Replies Latest reply on Nov 9, 2017 6:46 PM by Thomas Hotchkin

    PDM Script Help

    Thomas Hotchkin

      Hey all,

       

      I've been trying for days to get a script working in PDM and I'm getting absolutely nowhere. Would anyone be able to give me some advice on why my script isn't working and how I can fix it, or any good resources to learn about scripting? I haven't been able to find much on the internet about it but I'm sure it's out there.

       

      This is the script I have at the moment. This is the entire script from start to finish, which is copied and pasted straight into the PDM Task script section. The data card it uses just has one drop down list to choose the recipient. The task is supposed to create a folder if it doesn't already exist, save any drawings as PDFs and any sheet metals parts as flat pattern DXFs. I thought this was a fairly simple task, but I can't get it to do literally anything. It doesn't even create a folder.

       

      Option Explicit
      
      
      Dim swApp As Object
      
      
      Sub main()
      Set swApp = Application.SldWorks
          Set swModel = swApp.ActiveDoc
      
      
      'get file name
      Dim fileName As String
      fileName = "<Filename>"
      
      
      'get file revision
      Dim fileRevision As String
      swCustPropMgr.Get3 "Revision", True, fileRevision, Empty
      
      
      'get document recipient
      Dim docRecipient As String
      docRecipient = "{Transmittal Recipient}"
      
      
      'get date and make string
      Dim todDate As Date 
      todDate = Date.Now()
      Dim docDate As String
      docDate = todDate.ToString("yyyy_MM_dd")
      
      
      'get vault path
      Dim vaultPath As String
      vaultPath = "<VaultPath>"
      
      
      'create save folder
      Dim folderPath As String
      folderPath = vaultPath & "\Document Transmittals\" & docRecipient & "\"
      Dim folder As IEdmFolder5
      folder = folderPath.AddFolder(Me.Handle.ToInt32(), fileDate)
      Dim savePath As String
      savePath = folderPath & fileDate & "\"
      
      
      'create save name
      Dim saveName As String
      saveName = fileName & "-" & fileRevision
      
      
      'if file is drawing save as PDF
      If "<Extension>" = ".slddrw" then
      swModel.Extension.SaveAs savePath & saveName & ".pdf", swSaveAsCurrentVersion, swSaveAsOptions_Silent, Nothing, Errors, Warnings
      
      
      'if file is part and has sheet metal save flat pattern as DXF
      Elseif "<Extension>" = ".sldprt" then
      bRet = swModel.ExportFlatPatternView(savePath & saveName & ".dxf", 1)
      End If
      
      
      End Sub
      

      I'd really appreciate any help or advice.

       

      Thanks,

      Tom.

        • Re: PDM Script Help
          Simon Turner

          Line 19: you haven't set swCustPropMgr yet.

          Insert a line before line 19:

          Set swCustPropMgr = swModel.Extension.CustomPropertyManager("")

           

          Also, I don't think you can just pass in Empty for the last argument.

          Dim fileRevisionResolved As String

          swCustPropMgr.Get3 "Revision", True, fileRevision, fileRevisionResolved

           

          There may be other issues, but that's the obvious one I could spot.

          • Re: PDM Script Help
            Lee CS Young

            Right after your main call (line 8), put

             

            Debug.Assert false
            

             

            That will open up the task macro in SW. Copy and paste it to a text file, and then close SW. Open SW again, create a new macro, and paste the text you copied. You'll be able to step through the code to see where it's failing.

            • Re: PDM Script Help
              Ulf Stockburger

              Hi Thomas Hotchkin

               

              Macros have to be error-free from the viewpoint of SolidWorks. Otherwise, it’s terminated before execution. Option Explicit forces the variable assignment. The first error is caused in line 9 because the active document is assigned to the undeclared variable swModel. This also applies to swCustPropMgr, Errors, Warnings.

               

              I may be wrong, but my knowledge is that the PDM standard task only supports VBA. Me.Handle.ToInt32() is available in VB.NET, not in VBA. I suggest to use the SolidWorks VBA editor to create the macro. The debugger allows you to identify and correct errors fast. During development, you can assign default values for variables, e.g."<Filename>", which are dynamically assigned later in the task.

               

              If the macro works well, it can be copied into the PDM task script section. For debugging from within the task, you can use either Debug.Assert false as Lee CS Young suggested, or Stop.

               

              I hope it helps.

               

              BiI SAP-PDM

                • Re: PDM Script Help
                  Thomas Hotchkin

                  Hi Ulf,

                   

                  I didn't know about the VBA editor! That is exactly what I need to hopefully figure some things out. Very hard to work out what's going on with no debug environment.

                   

                  I copied the Me.Handle.ToInt32() from a Solidworks example so I hope that bit at least is right.

                   

                  Thanks a lot!

                  • Re: PDM Script Help
                    Thomas Hotchkin

                    Hi Ulf,

                     

                    Thanks to the VBA Editor in Solidworks I have my task working as it should!

                     

                    Unfortunately I have copied it into the task add in script section, and it still does absolutely nothing. My best guess is that the references I added in the editor, aren't included in the task add in. But I could be wrong. This is the script as it is now, excuse the dodgy sleep function, I'll fix that later:

                     

                    Dim swApp As Object
                    Dim swModel As Object
                    Dim swCustPropMgr As SldWorks.CustomPropertyManager
                    Dim swExportPDFData     As SldWorks.ExportPdfData
                    Dim Errors As Long
                    Dim Warnings As Long
                    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
                    
                    
                    Sub main()
                        Set swApp = Application.SldWorks
                        Set swModel = swApp.ActiveDoc
                        Set swCustPropMgr = swModel.Extension.CustomPropertyManager(Empty)
                    
                    
                    'get file number
                        Dim drawingNumber As String
                        swCustPropMgr.Get3 "Drawing number", True, drawingNumber, Empty
                    
                    
                    'get file revision
                        Dim fileRevision As String
                        swCustPropMgr.Get3 "Revision", True, fileRevision, Empty
                    
                    
                    'get document recipient
                        Dim docRecipient As String
                        docRecipient = "Factory"
                    
                    
                    'get date as string
                        Dim docDate As String
                        docDate = Format(Date, "yyyy-MM-dd")
                    
                    
                    'get vault path
                        Dim vaultPath As String
                        vaultPath = "C:\PDMVault"
                    
                    
                    'create save folder
                        Dim folderPath As String
                        folderPath = "\Document Transmittals\" & docRecipient & "\" & docDate
                        Dim Vault As Object
                        Set Vault = CreateObject("ConisioLib.EdmVault")
                        Vault.LoginAuto "PDMVault", 0
                        Dim CreatedFolder As IEdmFolder5
                        Set CreatedFolder = Vault.RootFolder.CreateFolderPath(folderPath, 0)
                    
                    
                    'create save name
                        Dim saveName As String
                        saveName = vaultPath & folderPath & "\" & drawingNumber & "-" & fileRevision
                        Dim saveFile As String
                    
                    
                    'if file is drawing save as PDF
                        If swModel.GetType = 3 Then
                            saveFile = saveName & ".pdf"
                            Set swExportPDFData = swApp.GetExportFileData(1)
                            swModel.Extension.SaveAs saveFile, 0, 1, swExportPDFData, Errors, Warnings
                            
                    
                    
                    'if file is part and has sheet metal save flat pattern as DXF
                        ElseIf swModel.GetType = 1 Then
                            Dim sheetMetal As Integer
                            sheetMetal = swModel.GetBendState
                            If sheetMetal <> 0 Then
                                saveFile = saveName & ".dxf"
                                bRet = swModel.ExportFlatPatternView(saveFile, 1)
                            End If
                        Else
                            Set swApp = Application.SldWorks
                            End Sub
                        End If
                        
                    'check file in
                        Sleep (10000)
                        Dim checkVault As EdmVault5
                        Set checkVault = New EdmVault5
                        checkVault.LoginAuto "PDMVault", 0
                        Dim checkFile As IEdmFile5
                        Set checkFile = checkVault.GetFileFromPath(saveFile)
                        checkFile.UnlockFile 0, ""
                        
                    Set swApp = Application.SldWorks
                    End Sub
                    

                    Any idea what may cause it to not work?

                     

                    Thanks a lot,

                    Tom.

                      • Re: PDM Script Help
                        Ulf Stockburger

                        Hi Thomas Hotchkin

                         

                        Try to start with small and simple macros. The difference between a macro in CAD and in PDM Task may be huge. A macro that works in CAD can throw errors in a PDM Task. I think that a Compile Error has to be thrown in line 75, since End Sub has to be at the end of the subroutine.

                         

                        I suggest always work with Option Explicit. It looks like more work in the beginning, but it prevents many possible problems from the beginning. In this way, possible problems are reported before execution. For example, bRet in line 71 has not yet been declared with Dim bRet As Boolean. It doesn't have to be a problem, but it could turn into one.

                         

                        Declaring variables as objects (line 01) makes sense if the macro works well and the development is finished. During development, however, it makes sense to assign the API objects (line 03) to the variables. This way, you will be supported by Intellisense during programming.


                        If the macro works well in CAD, insert Stop to debug the macro from the PDM task, remark (') everything that can cause errors and copy it to the PDM Task script section. During debugging, delete the remark statement (') to see what happens and to detect errors. Start with a small macro and process line by line:

                         

                        Dim swApp As Object 

                        Dim swModel As Object 

                        Dim swCustPropMgr As SldWorks.CustomPropertyManager 

                        Dim swExportPDFData As SldWorks.ExportPdfData 

                        Dim Errors As Long 

                        Dim Warnings As Long 

                        Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr

                         

                        Sub main() 

                            Stop

                            Set swApp = Application.SldWorks <

                            Set swModel = swApp.ActiveDoc

                            Set swCustPropMgr = swModel.Extension.CustomPropertyManager(Empty)

                         

                        ' 'get file number

                        ' Dim drawingNumber As String 

                        ' swCustPropMgr.Get3 "Drawing number", True, drawingNumber, Empty 

                        ' . . .  

                        ' Dim checkFile As IEdmFile5 

                        ' Set checkFile = checkVault.GetFileFromPath(saveFile) 

                        ' checkFile.UnlockFile 0, "" 

                        End Sub 

                         

                        As far as I know, it is not enough to save the file into the vault. The file has also to be added to the vault before any PDM action, e.g. for check in. I think you will find information in Sub AddFiles_Click here: http://help.solidworks.com/2014/english/api/epdmapi/add_files_to_vault_example_vbnet.htm

                        But remember, it's VB not VBA.

                         

                        To get started, I would start with simple macros to learn the basics. The most important is error handling. It is fatal if a macro doesn't do what’s expected. VBA is VBA, therefore I think EXCEL is a very good environment to learn VBA. Among other things, because many good tutorials are available on the internet. Google helps.

                         

                        I hope it helps and I wish you success.

                         

                        BiI SAP-PDM

                          • Re: PDM Script Help
                            Thomas Hotchkin

                            Thankyou very much for the advice!

                             

                            I am so close to the macro working. It all works perfectly except when a DXF is created it isn't checked in. I don't know why, but the PDF gets checked in automatically.

                             

                            Here's the code for anyone interested:

                            Dim swApp As SldWorks.SldWorks
                            Dim swModel As SldWorks.ModelDoc2
                            Dim swModelTemp As SldWorks.ModelDoc2
                            Dim swModelDocExt As SldWorks.ModelDocExtension
                            Dim swCustProp As CustomPropertyManager
                            
                            
                            Dim filePath As String
                            Dim vaultPath As String
                            Dim docRecipient As String
                            Dim docDate As String
                            Dim savePath As String
                            
                            
                            Dim fileType As Integer
                            Dim scratch As String
                            Dim partNumber As String
                            Dim partRevision As String
                            
                            
                            Dim bool As Boolean
                            Dim res As Boolean
                            
                            
                            Dim Errors As Long
                            Dim Warnings As Long
                            
                            
                            Private Declare PtrSafe Function SHCreateDirectoryEx Lib "shell32" Alias "SHCreateDirectoryExA" (ByVal hwnd As Long, ByVal pszPath As String, ByVal psa As Any) As Long
                            
                            Sub main()
                                Set swApp = Application.SldWorks
                                'Set swModelTemp = swApp.ActiveDoc
                                filePath = "<Filepath>"
                                vaultPath = "<VaultPath>"
                                docRecipient = "{Transmittal Recipient}"
                                docDate = Format(Date, "yyyy-MM-dd")
                                savePath = vaultPath & "\Document Transmittals\" & docRecipient & "\" & docDate & "\"
                                SHCreateDirectoryEx ByVal 0&, savePath, ByVal 0&
                                If InStr(filePath, "SLDPRT") Then
                                    fileType = 1
                                    Set swModel = swApp.OpenDoc6("<Filepath>", fileType, 1, "", Errors, Warnings)
                                    Set swModelDocExt = swModel.Extension
                                    Set swCustProp = swModelDocExt.CustomPropertyManager("")
                                    bool = swCustProp.Get5("Revision", False, scratch, partRevision, res)
                                    bool = swCustProp.Get5("Drawing Number", False, scratch, partNumber, res)
                                    savePath = vaultPath & "\Document Transmittals\" & docRecipient & "\" & docDate & "\" & partNumber & "-" & partRevision & ".dxf"
                                    Dim sheetMetal As Integer
                                    sheetMetal = swModel.GetBendState
                                    If sheetMetal <> 0 Then
                                        Dim bRet As Boolean
                                        bRet = swModel.ExportFlatPatternView(savePath, 1)
                                    End If
                                    
                                ElseIf InStr(filePath, "SLDDRW") Then
                                    fileType = 3
                                    Set swModel = swApp.OpenDoc6("<Filepath>", fileType, 1, "", Errors, Warnings)
                                    Set swModelDocExt = swModel.Extension
                                    Set swCustProp = swModelDocExt.CustomPropertyManager("")
                                    bool = swCustProp.Get5("Revision", False, scratch, partRevision, res)
                                    bool = swCustProp.Get5("Drawing Number", False, scratch, partNumber, res)
                                    savePath = vaultPath & "\Document Transmittals\" & docRecipient & "\" & docDate & "\" & partNumber & "-" & partRevision & ".pdf"
                                    swModelDocExt.SaveAs savePath, 0, 1, Nothing, Errors, Warnings
                                Else
                                    Exit Sub
                                End If
                            End Sub
                            

                            I still need to go through and make it a bit neater, and also add some error handling and comments. Although with how our vault is setup I don't think this macro needs to be able to handle anything unexpected.

                             

                            Thanks again for everyone's help I could not have done this without the help of this forum.

                             

                            Cheers,

                            Tom.

                      • Re: PDM Script Help
                        Thomas Hotchkin

                        Thanks so much for everyone's help!

                         

                        Using the debugger in Solidworks is so much better than a text editor. I have majority of the code working now.

                         

                        The biggest part I am still struggling with though is how to create a folder in PDM. I have the full path as a string which is easy enough, and I am confident that the createfolderpath method is what I need to use, but I just can't get my head around the example on the API help section. Does anyone happen to have a task using this method they might be able to share with me?

                         

                        Thanks a lot,

                        Tom.

                          • Re: PDM Script Help
                            Thomas Hotchkin

                            Finally discovered this buried in the forums, but in case anyone else needs the answer:

                             

                                Dim folderPath As String

                                folderPath = "\Document Transmittals\" & docRecipient & "\" & docDate

                                Dim Vault As Object

                                Set Vault = CreateObject("ConisioLib.EdmVault")

                                Vault.LoginAuto "PDMVault", 0

                                Dim CreatedFolder As IEdmFolder5

                                Set CreatedFolder = Vault.RootFolder.CreateFolderPath(folderPath, 0)