使用Python传递变量'Nothing'';s`win32com`

使用Python传递变量'Nothing'';s`win32com`,python,vba,win32com,Python,Vba,Win32com,我试图使用Python的win32com在VBA中传递变量Nothing。我试图使用None,但它返回“Type dismatch” 有人能帮忙吗 谢谢大家! 例如: ' Book1.xlsm!Module1 Function test(arg As Object) As String If arg Is Nothing Then test = "Success" Exit Function Else test = "Failure

我试图使用Python的
win32com
在VBA中传递变量
Nothing
。我试图使用
None
,但它返回“Type dismatch”

有人能帮忙吗

谢谢大家!

例如:

' Book1.xlsm!Module1
Function test(arg As Object) As String
    If arg Is Nothing Then
        test = "Success"
        Exit Function
    Else
        test = "Failure"
        Exit Function
    End If

End Function
在Python中:

import win32com.client
import os
import pythoncom


xl = win32com.client.Dispatch('Excel.Application')
xl.Visible = True
xl.Workbooks.Open(Filename=os.path.abspath('Book1.xlsm'))
test_str = xl.Application.Run('Book1.xlsm!Module1.test', pythoncom.Empty)
答复说:

runfile('C:/Users/shwang/Downloads/untitled0.py', wdir='C:/Users/shwang/Downloads')
Traceback (most recent call last):

  File "<ipython-input-22-301693920f2c>", line 1, in <module>
    runfile('C:/Users/shwang/Downloads/untitled0.py', wdir='C:/Users/shwang/Downloads')

  File "C:\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 866, in runfile
    execfile(filename, namespace)

  File "C:\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "C:/Users/shwang/Downloads/untitled0.py", line 16, in <module>
    test_str = xl.Application.Run('Book1.xlsm!Module1.test', pythoncom.Empty)

  File "<COMObject <unknown>>", line 14, in Run

  File "C:\Anaconda3\lib\site-packages\win32com\client\dynamic.py", line 287, in _ApplyTypes_
    result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args)

com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147352561), None)
runfile('C:/Users/shwang/Downloads/untitled0.py',wdir='C:/Users/shwang/Downloads')
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
运行文件('C:/Users/shwang/Downloads/untitled0.py',wdir='C:/Users/shwang/Downloads')
文件“C:\Anaconda3\lib\site packages\spyder\utils\site\sitecustomize.py”,第866行,在runfile中
execfile(文件名、命名空间)
文件“C:\Anaconda3\lib\site packages\spyder\utils\site\sitecustomize.py”,第102行,在execfile中
exec(编译(f.read(),文件名,'exec'),命名空间)
文件“C:/Users/shwang/Downloads/untitled0.py”,第16行,在
test_str=xl.Application.Run('Book1.xlsm!Module1.test',pythoncom.Empty)
文件“”,第14行,正在运行
文件“C:\Anaconda3\lib\site packages\win32com\client\dynamic.py”,第287行,在ApplyTypes中_
结果=self.\u oleobj.\u.InvokeTypes(*(dispid、LCID、wFlags、retType、argTypes)+args)
com_错误:(-2147352567,‘发生异常’,(0,无,无,无,0,-2147352561),无)

在VBA中,
用作未初始化的默认值,该值通常引用COM对象(即Excel对象库或外部应用程序的对象库)。VBA的基本整型、长型和字符串类型不能指定Nothing值。通常程序员在代码块的末尾使用它来释放内存中的对象

因此,VBA的
Nothing
(COM类型的特殊值)和Python的值类型(包括
None
)之间没有严格的转换,后者粗略地表示任何类型都为空或无值

话虽如此,如果您传递的COM对象已经用
xl
初始化,那么您的代码就不会出错。以下输出
故障
。如果您可以声明一个未初始化的COM对象,而该对象将不携带任何内容,那么您可以将其传递到函数中。但是调用
Dispatch
需要一个命名对象。第二十二条军规

import win32com.client
import os

try:
    xl = win32com.client.Dispatch('Excel.Application')
    xl.Visible = True

    wb = xl.Workbooks.Open(Filename=os.path.abspath('Book1.xlsm'))
    test_str = xl.Application.Run('test', xl)
    print(test_str)
    # FAILURE

    wb.Close(False)
    xl.Quit

except Exception as e:
    print(e)

finally:
    wb = None
    xl = None
下面是一个将VBA Nothing对象传递给SolidWorksAPI的工作示例(python)

import win32com.client
import pythoncom
swApp = win32com.client.Dispatch('SldWorks.Application')
Part = swApp.ActiveDoc
boolstatus = Part.Extension.SelectByID2("", "SKETCHCONTOUR", 75e-3, -4e-3, 0, False, 0, pythoncom.Nothing, 0)
print(boolstatus)
以下是升华文本3中的输出:

真的

[在0.7秒内完成]

脚本尝试选择坐标为(75mm,-4mm)的草图轮廓。SolidWorksAPI“SelectByID2”的“Callout”参数被指定为pythoncom.Nothing。要使脚本正常工作,前提是您正在编辑草图,如下图所示

附图显示了SolidWorks中发生的情况(之前|之后)

一些背景。我想通过python在SolidWorks中绘制一些电机几何图形,因为我已经有了其他绘图工具(如JMAG Designer、FEMM或PyX)的python代码


谢谢你的帖子!您的讨论帮助我找到了这一点。

您是否通过了
None
'None'
?您可能可以使用
pythoncom.Empty
。另请看您能否创建一个我们可以尝试的小示例?看看如何创建一个新的应用程序。@PeterWood非常感谢您!我加了一个例子。我试过了,但是pythoncom.Empty、None或None似乎都不起作用。谢谢你的冻糕!我明白其中的逻辑。太糟糕了,我正在使用SolidWorksAPI(一种3D CAD软件),它不需要任何东西作为特定目的的输入参数。我想我可以用VBA代码来包装它,并在不需要任何东西的时候调用包装器——虽然不漂亮,但可行。再次感谢!变量的默认值为空。谢谢@SMeaden。根据,您是正确的,因此我删除了对
变量的任何提及,因为Excel COM对象甚至不会使用此类型。您可以添加一个不返回任何内容的VBA函数,即具有一个工厂函数,其目的是生成一个不返回任何内容的函数;从Python中调用它;将结果存储在变量中,然后传递该变量。