彻底抛弃VAB,用Python就可以开发自定义函数了

公司休年假,近10来天的假期,本来计划去西藏旅游的,因为疫情又起,最后放弃了,选择宅在家继续处理EFunction项目 。很多朋友希望EFunction能够支持自定义函数开发工作,正好趁着这个假期研究下怎么利用Python开发自定义函数工作 。
【彻底抛弃VAB,用Python就可以开发自定义函数了】其实Python开发Excel自定义工具有很多,比如xlwings , pyxll等 。通过研究对比发现xlwings和pyxll都是对pywin32工具做了封装二次开发 。自己也依葫芦画瓢,利用pywin32开发自己的第一个自定义函数 。

自定义函数BUG处理

因为我的Python开发环境通过anaconda安装,已经自带pywin32工具包,刚开始使用默认的pywin32工具包开发自定义函数,函数在引入numpy工具包或者第三方引用了numpy工具包的其他包,例如pandas时,最后使用自定义函数时,会报错 。


彻底抛弃VAB,用Python就可以开发自定义函数了

numpy错误
因为这个问题 , 苦恼了很久 。为了解决这个问题,翻阅N多帖子,都没有找到解决办法 。后来瞎猫碰到死老鼠,把这个问题给解决了 。
其实这个问题如果使用xlwings开发自定义函数,也会同样存在这个问题 。最后解决这个问题方法很简单 , 只需要重新手动安装numpy工具包就可以,网络上帖子大多解释,该问题可能是anaconda环境引起 。
划重点,不是所有的的anaconda环境都存在该问题,我台式机存在该BUG,但我笔记本就无该问题 。如果没有该报错可以无需处理该问题 。
在手动安装前,可以通过conda list命令查阅下,当前你的numpy版本是多少,记录下来 。安装numpy前,先要卸载环境内numpy包,再安装同版本numpy 。
彻底抛弃VAB,用Python就可以开发自定义函数了

先查阅 numpy版本
卸载完成后,再安装指定版本numpy,我的版本为1.21.6,安装命 令为:
pip3 install numpy==1.21.6 -i https://pypi.tuna.tsinghua.edu.cn/simple
以上准备后好,就可以进入下一个主题了 , 如果你目前暂且不使用numpy包,只想体验Python开发Excel自定义函数,该步骤可以跳过 。直接进入下一个环节 。

开发第一个自定义函数

以实际案例来开发第一个自定义函数,函数使用到EFunction,jupyter开发工具,启用工具后录入两段代码 。
代码1:自定义函数主体类,后续有新增自定义函数需求,可以在该类内添加或者修改 。样例代码为:
%%writefile filename.pyimport pythoncom as pcimport win32com.client as cl#import pandas as pdimport numpy as npimport jiebafrom win32com.client import Dispatchclass PythonComTestObject:_reg_clsid_ = '{BB58C07E-B9AD-4BC7-BB8C-01D2FF8FD4E9}' #replace this_reg_clsctx_ = pc.CLSCTX_LOCAL_SERVER_reg_progid_ = "PythonComTestObject"_reg_desc_ = "A library for doubling things."# a list of strings that indicate the public methods for the object. If they aren't listed they are considered private._public_methods_ = ['cutWord']# double every value in array and returndef cutWord(self,data):#the VARIANT array comes gets converted to an [[]] arrayseg_list = jieba.cut(data, cut_all=False)word_list = []for a in seg_list:word_list.append(a)return "happy"if __name__ == '__main__':import win32com.server.registerwin32com.server.register.UseCommandLine(PythonComTestObject)
上述代码定义了函数类主体,有一个自定义函数cutWord , 该函数功能为对文本数据进行分词,结果以数组方式返回 。如果有新增函数,依葫芦画瓢,添加一个函数即可 。
写好函数函数类后,将该段代码执行,执行完成后 , 就可以在同目录下生成一个“filename.py”同名Python脚本文件 。用以下脚本执行该文件即可,即可实现函数com注册,注册成功后,就可以通过Excel VBA调用该函数了 。
%run filename.py
执行成功后,jupyter notebook界面会提示注册成功提示 。例如下图界面 。


彻底抛弃VAB,用Python就可以开发自定义函数了

注册com组件
完成函数注册后,就可以在VBA之中调用了 。其实调用脚本非常简单 , 大家可以用同一个模板,就可以,只需要做细微修改 。
Function cut_word(x)On Error GoTo MyErrSet det = VBA.CreateObject("PythonComTestObject")If IsObject(x) Thencut_word = det.cutWord(x.Value)Elsecut_word = det.cutWordArray(x)End IfExit FunctionMyErr:cut_word = Err.DescriptionEnd Function


彻底抛弃VAB,用Python就可以开发自定义函数了

VBA自定义函数模板,在VBA内调用Python函数
最后就可以在Excel内调用自定义的函数了 。最终的分词结果为:
彻底抛弃VAB,用Python就可以开发自定义函数了

分词函数分词结果
总结下用pywin32开发Excel自定义函数方法流程:
彻底抛弃VAB,用Python就可以开发自定义函数了

Python自定义函数三部法
按照模板定义自己的函数,定义完成后,将jupyter notebook内的代码写入py文件内 。如果不通过EFunction jupyter notebook管理自定义函数,也可以使用其他的IDE工具编写Python脚本 。编写完成后 , 就是执行模板脚本,在EFunction jupyter notebook内,就使用%fun filename.py就可以 。完成自定义函数com注册后,就可以在vba内调用了函数了 。也可以参照模板 。
如果Python自定义函数新增或者函数名有更改,需要重复上述步骤 , 如果只是更改函数内的脚本,不更改函数Python名及参数 。不需要重复执行Py文件 。
下一步骤研究怎样用EFunction jupyter notebook管理自定义函数

相关经验推荐