![](/img/trans.png)
[英]Strava API Python - AttributeError object has no attribute
[英]Solidworks PDM API in Python--getting AttributeError object has no attribute 'QueryInterface'
我已经编写了一堆 Python 代码,用于在 Solidworks PDM 中标记我们的供应商文件,并且我正在尝试使用 Solidworks PDM API 来实际应用该信息。 官方 API 仅支持 C# 和 VB,但如果可能的话,我想将所有内容都保留在 Python 中,因为其他所有内容都已经在 Python 中了(这是我最习惯使用的编程语言)。 这是我要完成的工作的高级列表:
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.