使用Python的`win32com`传递变量`Nothing`

时间:2016-12-15 23:28:51

标签: python vba win32com

我正在尝试使用Python的Nothing在VBA中传递变量win32com。我尝试使用None,但它返回了“类型不匹配”。

有人可以帮忙吗?

谢谢!

一个例子:

' 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)

REPL说:

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)

2 个答案:

答案 0 :(得分:1)

在VBA中,Nothing仅用作两种类型的未初始化默认值:ObjectVariant,它们通常引用COM对象(即Excel对象库或外部应用程序的对象库) )。无法为VBA的原始整数,长整数和字符串类型分配 Nothing 值。通常程序员在代码块的末尾使用它来从内存中释放对象。

因此,VBA的Nothing(COM类型的特殊值)和Python的值类型(包括None)之间没有严格的转换,这对于任何类型。

如上所述,如果传递已使用xl初始化的COM对象,则代码不会出错。低于输出FAILURE。如果以某种方式你可以声明一个未初始化的COM对象然后将携带 Nothing ,那么你可以将它传递给你的函数。但要调用Dispatch需要一个命名对象。捉住22!

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

答案 1 :(得分:0)

这是一个工作示例(在python中),该示例将VBA Nothing对象传递给SolidWorks API。

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)

以下是Sublime Text 3中的输出:

[在0.7秒内完成]

该脚本尝试选择坐标为(75mm,-4mm)的草图轮廓。 SolidWorks API“ SelectByID2”的“标注”参数分配为pythoncom.Nothing。为了使脚本正常工作,前提是您正在编辑草图,如下图所示。

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

Pass Nothing to SW API SelectByID2

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

感谢您的发帖!您的讨论可以帮助我找到这个。