簡體   English   中英

Python 中的 Solidworks PDM API--獲取 AttributeError 對象沒有屬性“QueryInterface”

[英]Solidworks PDM API in Python--getting AttributeError object has no attribute 'QueryInterface'

我已經編寫了一堆 Python 代碼,用於在 Solidworks PDM 中標記我們的供應商文件,並且我正在嘗試使用 Solidworks PDM API 來實際應用該信息。 官方 API 僅支持 C# 和 VB,但如果可能的話,我想將所有內容都保留在 Python 中,因為其他所有內容都已經在 Python 中了(這是我最習慣使用的編程語言)。 這是我要完成的工作的高級列表:

  1. 查看一堆文件
  2. 更新數據卡變量
  3. 重新檢入這些文件

API 定義了兩種主要方式來檢入/檢出/更新單個文件中的變量——一種用於單個文件,另一種用於文件組。 您可以使用可通過 IEdmVault5 接口訪問的方法對單個文件執行所有 3 項操作,而要對文件組執行這些操作,您必須使用 3 個單獨的接口——IEdmBatchGet(檢出)、IEdmBatchUpdate2(更新變量)和 IEdmBatchUnlock(報到)。

我能夠編寫為每個文件完成所有 3 件事的功能代碼,但是在處理多個文件時速度很慢——我的目標是一次更新幾千個文件。 事實證明,使批處理接口工作要困難得多,但我最終能夠使批處理檢出和檢入工作(這絕對值得——使用 Vault 接口,每個操作的速度提高了大約 10 倍)。 但是,我在嘗試使變量更新工作時遇到了困難。 這是我更新變量的代碼:

import win32com.client
import os

import comtypes.client as cc
cc.GetModule('C:\Program Files (x86)\SOLIDWORKS PDM\EdmInterface.dll')
import comtypes.gen._5FA2C692_8393_4F31_9BDB_05E6F807D0D3_0_5_22 as pdm_lib2

vault_name = 'vault_name'
folder_path = 'some_folder_path'

def connect_to_vault(vault_name, lib = 'comtypes'):
    if lib == 'comtypes':
        vault = cc.CreateObject('ConisioLib.EdmVault.1')
        vault.LoginAuto(vault_name, 0)

    else: 
        vault = win32com.client.dynamic.Dispatch('ConisioLib.EdmVault.1')
        vault.LoginAuto(vault_name, 0)

    return vault

def getrefs(vault, filenames, folder_path):
    DocIDs = []
    ProjIDs = []

    for filename in filenames:
        temp_ProjID = vault.GetFolderFromPath(folder_path)
        temp_DocID = vault.GetFileFromPath(filename, temp_ProjID)[0] #this fails when I use a comtypes generated vault

        DocIDs.append(temp_DocID.ID)
        ProjIDs.append(temp_ProjID.ID)

    print('Document and Project IDs pulled')

    return DocIDs, ProjIDs

vault = connect_to_vault(vault_name)
ref_vault =connect_to_vault(vault_name, lib = 'win32com') 

filenames = [folder_path + s for s in os.listdir(folder_path)]
DocIDs, ProjIDs = getrefs(ref_vault, filenames, folder_path)

#Using Comtypes to update files
VarIDs = [54] * len(DocIDs) #Updating description only
var_values = [['foo' + str(s)] for s in range(len(DocIDs))] #dummy values for now

update_vars = vault.CreateUtility(2) #create instance of BatchUpdate 

for i, file in enumerate(DocIDs): 
    update_vars.SetVar(file, VarIDs[i], var_values[i], '', 1)

pdm_error = [pdm_lib2.EdmBatchError2()] * len(DocIDs)
update_vars.CommitUpdate([pdm_error])

當我調用 update_vars.CommitUpdate([pdm_error]) 時,出現以下錯誤:

ArgumentError: argument 2: <class 'AttributeError'>: 'list' object has no attribute 'QueryInterface'

我不確定為什么這個方法需要一個具有“QueryInterface”屬性的對象——我只是向它傳遞一個結構列表,而不是像我的文件庫那樣的完整 COM 對象。 我也嘗試使用 win32com 來執行該方法:

update_vars = ref_vault.CreateUtility(2) #create instance of BatchUpdate, use win32com instead

for i, file in enumerate(DocIDs): 
    update_vars.SetVar(file, VarIDs[i], var_values[i], '', 1)

pdm_error = [pdm_lib2.EdmBatchError2()] * len(DocIDs)
update_vars.CommitUpdate([pdm_error])

現在我收到這個錯誤:

Traceback (most recent call last):

  File "<ipython-input-222-0c49fb0861b9>", line 7, in <module>
    update_vars.CommitUpdate([pdm_error])

  File "D:\Users\apreacher\Documents\Shared Files\Python\Webscraping_projects\Helper Modules\pdm_lib.py", line 1500, in CommitUpdate
    , poCallback)

  File "C:\Users\apreacher\AppData\Local\Continuum\anaconda3\lib\site-packages\win32com\client\__init__.py", line 467, in _ApplyTypes_
    self._oleobj_.InvokeTypes(dispid, 0, wFlags, retType, argTypes, *args),

MemoryError: CreatingSafeArray

這就是我被困的地方。 我一直無法在讓 CommitUpdate 方法正常工作方面取得任何進展。 我也有 makepy.py 和 comtypes 生成的文件中的方法定義,但我真的不知道如何解釋它們:

makepy.py 方法定義:

def CommitUpdate(self, ppoRetErrors=pythoncom.Missing, poCallback=0):
    'method Commit'
    return self._ApplyTypes_(3, 1, (3, 0), ((24612, 2), (9, 49)), 'CommitUpdate', None,ppoRetErrors
        , poCallback)

comtypes 生成的文件:

COMMETHOD([dispid(3), helpstring('method Commit')], HRESULT, 'CommitUpdate',
          ( ['out'], POINTER(_midlSAFEARRAY(EdmBatchError2)), 'ppoRetErrors' ),
          ( ['in', 'optional'], POINTER(IEdmCallback), 'poCallback', 0 ),
          ( ['out', 'retval'], POINTER(c_int), 'plErrorCount' )),

有任何想法嗎?

您使用的是哪個版本的 PDM? (我使用的是 Pro 2019 sp4。)

我只是注意到您的代碼不一致。 vault.CreateUtility(2)將(在 .NET 中)返回類型為IEdmBatchUpdate的對象。 4 行之后,您將調用CommitUpdate方法,該方法僅適用於較新的 API IEdmBatchUpdate2 (請參閱https://help.solidworks.com/2020/english/api/epdmapi/EPDM.Interop.epdm~EPDM.Interop.epdm。 IEdmBatchUpdate2.html )。

我可以肯定地告訴您,在 C# 下,這需要將CreatUtility的結果CreatUtility為正確的對象類型。

您似乎正在尋找一種方法來自動將數據輸入到文件數據卡中。 您是否嘗試過使用數據導入規則? https://help.solidworks.com/2020/English/EnterprisePDM/Admin/c_Working_With_Variable_Values_overview.htm

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM