python - 如何将 pandas 导入 VBA 的 Python COM 对象
问题描述
我必须将数据从 VBA 传递到 Python 并返回。
我还需要 VBA 中的 Python Obj 才能使用 Pandas 库(以及其他库,例如 numpy,...)。
- 我已经成功使用了Florent B.提供的 SOLUTION 2 :将 numpy 数组从 VBA 移动到 Python 并返回
- 如果我根本不尝试导入熊猫,则对象已成功创建并正常工作(但未使用熊猫)。任何传递给 Python 对象的 VBA 数组都被识别为元组的元组
- 我需要将数据输入(元组的元组)转换为 pandas DataFrames。因此,在 MyLibrary.py 文件中,我将“pandas”添加到导入列表中(在文件顶部 - 请参阅下面的 Python 代码)
- 然后,我在 Python shell 中成功注册了模块(使用 pandas)
在 VBA 中,创建对象时...
Set Py = CreateObject("Python.MyModule")
...我收到与以下内容相关的错误消息:
返回 retObj。CreateInstance (clsid, reqID)
或者...
如果我从 MyFunction 中导入 pandas(没有在文件顶部声明),则成功创建 Python 对象(这是从 Python 中的 MyFunction 导入 pandas 的方式):
def MyFunction(self, data) : import pandas
但是当我从 VBA 调用 MyFunction 时(这是导入熊猫的时候)......
ArrayOutput = Py.MyFunction(ArrayInput)
...我收到一条错误消息:
return self._invoke(dispid, lcid, wFlags, args)
代码如下(我在文件顶部报告了导入pandas的版本):
VBA代码:
Sub UsePythonObj(ArrayInput)
''''''''''''''''''''''''''''''
' Create Python Object
Dim ArrayOutput As Variant
Dim Py As Object
Set Py = CreateObject("Python.MyModule")
''''''''''''''''''''''''''''''''''''''
' Run Python
ArrayOutput = Py.MyFunction(ArrayInput)
End Sub
Python代码:
import sys, os, win32api, win32com.server.localserver, win32com.server.register, pandas
class MyModule(object):
_reg_clsid_ = "{5B4A4174-EE23-4B70-99F9-E57958CFE3DF}"
_reg_desc_ = "My Python COM Server"
_reg_progid_ = "Python.MyModule"
_public_methods_ = ['MyFunction']
def MyFunction(self, data) :
ProcessingData = pandas.DataFrame(list(data))
return ProcessingData
def register(*classes) :
regsz = lambda key, val: win32api.RegSetValue(-2147483647, key, 1, val)
isPy = not sys.argv[0].lower().endswith('.exe')
python_path = isPy and win32com.server.register._find_localserver_exe(1)
server_path = isPy and win32com.server.register._find_localserver_module()
for cls in classes :
if isPy :
file_path = sys.modules[cls.__module__].__file__
class_name = '%s.%s' % (os.path.splitext(os.path.basename(file_path))[0], cls.__name__)
command = '"%s" "%s" %s' % (python_path, server_path, cls._reg_clsid_)
else :
file_path = sys.argv[0]
class_name = '%s.%s' % (cls.__module__, cls.__name__)
command = '"%s" %s' % (file_path, cls._reg_clsid_)
regsz("SOFTWARE\\Classes\\" + cls._reg_progid_ + '\\CLSID', cls._reg_clsid_)
regsz("SOFTWARE\\Classes\\AppID\\" + cls._reg_clsid_, cls._reg_progid_)
regsz("SOFTWARE\\Classes\\CLSID\\" + cls._reg_clsid_, cls._reg_desc_)
regsz("SOFTWARE\\Classes\\CLSID\\" + cls._reg_clsid_ + '\\LocalServer32', command)
regsz("SOFTWARE\\Classes\\CLSID\\" + cls._reg_clsid_ + '\\ProgID', cls._reg_progid_)
regsz("SOFTWARE\\Classes\\CLSID\\" + cls._reg_clsid_ + '\\PythonCOM', class_name)
regsz("SOFTWARE\\Classes\\CLSID\\" + cls._reg_clsid_ + '\\PythonCOMPath', os.path.dirname(file_path))
regsz("SOFTWARE\\Classes\\CLSID\\" + cls._reg_clsid_ + '\\Debugging', "0")
print('Registered ' + cls._reg_progid_)
if __name__ == "__main__":
if len(sys.argv) > 1 :
win32com.server.localserver.serve(set([v for v in sys.argv if v[0] == '{']))
else :
register(MyModule)
解决方案
推荐阅读
- android - 在 Termux 上安装 apk 并等待它完成或检查 apk 是否已安装
- r - 如何在R中按行格式化数据表
- mysql - Mysql - 查询特定日期
- java - spring boot:如何为列值加密设置db2加密密码
- java - Eclipse IDE进程间死锁,不断重启和休眠,进度永不解决
- angular - Angular AOT 编译失败,因为“无法为属性构造查询..”
- ios - iOS webview CSS hack
- python - 如何使用点运算符在python中传递多个参数
- c++ - LLVM 构建错误(再次缺少函数)
- c# - 组合框文本 ValueConverter 滞后 - C# WPF XAML