从VBA调用自定义Python COM对象

4 投票
1 回答
815 浏览
提问于 2025-04-18 05:59

我有一个Python脚本,我把它转换成了一个COM服务器。现在我想从VBA(Access)中调用它。

我试过这样做:

Sub test()
    Dim PyScript
    Dim var

    Set PyScript = CreateObject("PythonDemos.CodeScript")    
    var = PyScript.CodeReader()    
    Debug.Print var    
End Sub

但是在CreateObject(...)这行代码时,我遇到了一个错误: 自动化错误 2147024770

根据我了解到的,这个错误意味着找不到模块“PythonDemos”。

这是我的Python代码:

class Main:
    _public_methods_ = ['CodeReader']
    _reg_progid_ = "PythonDemos.CodeScript"
    _reg_clsid_ = "{B74B241B-0699-4332-8145-145512D332D1}"

    def CodeReader(self, item=None):
        #do stuff here and return values


if __name__ == '__main__':
    win32com.server.register.UseCommandLine(Main)

这段代码单独运行得很好,并且作为COM服务器注册时没有问题。

我的问题是:如何正确地从VBA调用这个Python脚本?我哪里出错了?

1 个回答

2

经过很多次尝试和错误,我终于让它工作了。VBA的语法是正确的,但我更新了Python脚本。我不太确定,但我觉得

pythoncom.CLSCTX_LOCAL_SERVER

解决了问题。我有点困惑,因为PyCharm告诉我这不是一个有效的命令。我就忽略了这个提示,并像这样扩展了头部

class Main:
    _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER
    _reg_clsid_ = "{F223CC90-AB60-442C-BE81-C79701C47059}" 
    _reg_desc_ = "Python Code Reader"
    _reg_progid_ = "PythonDemos.CodeScript"
    _public_methods_ = ['CodeReader', 'test']
    _readonly_attrs_ = []
    _public_attrs_ = []


    def test(self):
        return "Test Erfolgreich"


    def CodeReader(self):
        #calculate and return stuff...


if __name__ == '__main__':
    if hasattr(sys, 'importers'):
        if '--register' in sys.argv[1:] or '--unregister' in sys.argv[1:]:
            win32com.server.register.UseCommandLine(Main)
        else:
            from win32com.server import localserver
            localserver.serve('{F223CC90-AB60-442C-BE81-C79701C47059}')
    else:
        win32com.server.register.UseCommandLine(Main)

我还不能确定底部的代码是否能像预期那样在.exe文件中工作,但在.py文件中是可以的。

撰写回答