Search code examples
pythoncomsolidworkspdm

Getting files using SolidWorks PDM API (Python)


I'm trying to write a script in python that automatically gets the latest versions of all Excel files in the "Documents" folder in my SolidWorks EPDM vault. Here is my code:

import pythoncom
import win32com.client


def connect_to_vault(vaultName):
    newVault = None

    interface = pythoncom.LoadTypeLib('C:/Program Files (x86)/SOLIDWORKS PDM/EdmInterface.dll')

    for index in range(0, interface.GetTypeInfoCount()):
        type_name = interface.GetDocumentation(index)[0]

        if 'EdmVault5' == type_name:
            type_iid = interface.GetTypeInfo(index).GetTypeAttr().iid
            newVault = win32com.client.Dispatch(type_iid)
            break

    newVault.LoginAuto(vaultName, 0)
    return newVault


def traverse_folder(folder, parent_level="", directory_array=None):
    if directory_array is None:  # First time through
        directory_array = []

    current_directory = parent_level + folder.Name + "\\"

    # Go through all files in current folder
    pdm_file_pos = folder.GetFirstFilePosition()
    # Loop files
    while not pdm_file_pos.IsNull:
        pdm_file = folder.GetNextFile(pdm_file_pos)
        currNm = pdm_file.Name
        # Test for excel file
        if ('.xlsx' not in currNm) and ('.xlsm' not in currNm):
            file_path = 'VAULT\\' + current_directory + currNm
            directory_array.append(file_path)

    # Go through all sub-folders in current folder
    pdm_sub_folder_pos = folder.GetFirstSubFolderPosition()  # Get first sub-folder
    # Loop sub-folders
    while not pdm_sub_folder_pos.IsNull:
        # Get next sub-folder and traverse
        pdm_sub_folder = folder.GetNextSubFolder(pdm_sub_folder_pos)
        traverse_folder(pdm_sub_folder, current_directory, directory_array)
        if len(directory_array) >= 80:
            return directory_array

    return directory_array


def getLatestVersions():
    vault_name = 'VAULT'
    newPath = "C:\\PDM\\"
    folder_path = "VAULT\\Documents\\"

    # Connect
    vault = connect_to_vault(vault_name)

    folder_path = newPath + folder_path
    temp_ProjID = vault.GetFolderFromPath(folder_path)

    # Get list of all files
    filteredFiles = traverse_folder(temp_ProjID)
    
    changedFiles = []  # List of files that have been updated
    # Loop through files & Get Latest Version of each
    for idx, file in enumerate(filteredFiles):

        temp_ProjID = vault.GetFolderFromPath(folder_path)
        temp_DocID = vault.GetFileFromPath(newPath + file, temp_ProjID)[0]

        # Get versions to compare
        currentVersion = temp_DocID.CurrentVersion
        localVersion = temp_DocID.GetLocalVersionNo(newPath + file)

        if localVersion != currentVersion:  # Version mismatch
            
            # --------- THIS LINE THROWS ERROR -------------------
            temp_DocID.GetFileCopy(0, '', temp_DocID.ID, 16, '')
            # ----------------------------------------------------
            changedFiles.append(newPath + file)

        filteredFiles[idx] = newPath + file

    return filteredFiles, changedFiles


if __name__ == "__main__":
    getLatestVersions()

It all works until it gets to the GetFileCopy() command, then it gives me this error:

pywintypes.com_error: (-2147352573, 'Member not found.', None, None)

I've tried a bunch of approaches and PDM commands and this is the closest I'm getting. I'm on Windows 11 with Solidworks PDM 2021 using Python 3.7 and win32com

Any suggestions?


Solution

  • I believe this just boils down to an incorrect argument, according to the API documentation, the function expects a directory path or the ID of the folder where it should be copied. Instead of the document ID, you need to pass the project (folder) ID.

    Corrected Line:

    temp_DocID.GetFileCopy(0, '', temp_ProjID.ID, 16, '')