【问题标题】:error msg in VBA when calling a COM server created in Python using Win32使用 Win32 调用在 Python 中创建的 COM 服务器时 VBA 中的错误消息
【发布时间】:2016-11-30 10:14:42
【问题描述】:

我正在阅读 Mark Hammond 关于 Python 和 win32 的书,使用下面的代码片段(创建一个模仿 Python 的 <variable.split> 函数的迷你 COM 服务器,以及一个在 VBA 上发送要拆分的字符串的小型客户端。

我的问题是,虽然一切看起来都很好(COM 服务器已注册并且确实存在于 regedit 中),但我得到了法语版本的 VBA 错误:

代码 438:“不受此对象管理的属性或方法”。

不用说,我确实使用 pythoncom.CreateGuid() 创建了一个特定的 reg_clsid !

环境:Windows 10,Anaconda 4.1.1下的Python 3.5.2,ASUS 8GB 64bits

非常感谢。

Python部分:


 class PythonUtilities:
     _public_methods_ = ['SplitString']
     _reg_progid_ = "PythonDemos.Utilities"

     _reg_clsid_ = "{C44B2DFA-3E19-478C-9599-3DFE7A0D619A}"

 def SplitString(self, val, item=None):
     import string
     if item != None: item = str(item)
     return string.split(str(val), item)

 if __name__=='__main__':

     print("Registering COM server…")
     import win32com.server.register
     win32com.server.register.UseCommandLine(PythonUtilities)

控制台消息:


Registering COM server…
Requesting elevation and retrying...
Registering COM server…
Registered: PythonDemos.Utilities 

VBA 部分:


 Sub TestPython()

     Set PythonUtils = CreateObject("PythonDemos.Utilities")
     myResp = PythonUtils.SplitString("Hello from VB")
     For Each Item In myResp
         MsgBox (Item)
     Next

 End Sub

【问题讨论】:

  • VBA 错误似乎表明注册的 typedef 有问题。
  • 谢谢。显然,其他人在 2012 年已经遇到了同样的问题:参见 [stackoverflow.com/questions/9805498/…。显然没有找到解决方案。
  • 我忘了提一点:错误信息出现在 VBA 指令 'myResp = PythonUtils.SplitString("Hello from VB")' 的级别,not 在CreateObject 行似乎在上面的链接帖子中就是这种情况。很抱歉。
  • 我看到,当您以这种方式注册组件时,它会在 CLSID 下创建 InProcServer32 和 LocalServer32 键,其中 InProcServer32 为 pythoncomloader27.dll,LocalServer32 正在运行 C:\Python27\pythonw.exe "C:\Python27\lib\site-packages\win32com\server\localserver.py" {C44B2DFA-3E19-478C-9599-3DFE7A0D619A}。为什么不删除 InProcServer32,将 LocalServer32 更改为 C:\Python27\python.exe -m pdb "C:\Python27\lib\site-packages\win32com\server\localserver.py" {C44B2DFA-3E19-478C-9599-3DFE7A0D619A} 并尝试调试它? (看完之后……)
  • + 编写一个小型 C++ 客户端来查明失败的操作。每条 VB 行都是一个数不胜数的动作。 (QueryInterface(IID_IDispatch) 发生在哪里?在 CreateProcess 行还是在方法调用行?)

标签: python vba winapi com


【解决方案1】:

在您的代码中,SplitString 不是PythonUtilities 的成员(关于缩进)。因此,您要调用的函数不是您创建的对象的一部分。 此外,您的函数中不需要import string。 请尝试以下操作:

import pythoncom
import win32com.client

class PythonUtilities:

    _public_methods_ = ['SplitString']
    _reg_progid_ = "PythonDemos.Utilities"
    _reg_clsid_ = "{C44B2DFA-3E19-478C-9599-3DFE7A0D619A}"

    def SplitString(self, val, item=None):
        if item != None: item = str(item)
        return str(val).split(item)

def run_testclient():
    obj = win32com.client.Dispatch("PythonDemos.Utilities")
    print(obj.SplitString("Hello from VB"))

if __name__=='__main__':

    print ("Registering COM server...")
    import win32com.server.register
    win32com.server.register.UseCommandLine(PythonUtilities)

    run_testclient()

有点晚了。但也许它仍然可以帮助......

【讨论】:

  • 您知道我如何返回#N/A 类型的 VT_ERROR (for Excel) 吗?我已经尝试过VARIANT(pythoncom.VT_ERROR, 2042),但这会返回从 Excel 中看到的错误 448(DISP_E_PARAMNOTFOUND = -2147352572)
猜你喜欢
  • 1970-01-01
  • 2012-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-20
  • 2023-02-07
  • 2013-10-10
  • 2014-07-23
相关资源
最近更新 更多