ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 9441|回复: 39

Python与Excel交互最好的方式应该是这样

[复制链接]

TA的精华主题

TA的得分主题

发表于 2020-6-13 23:35 | 显示全部楼层 |阅读模式
本帖最后由 Askinofblue 于 2020-6-14 16:57 编辑

Python代替VBA之说

早就听说微软想用Python代替VBA开发Excel。
而实际上VBA有庞大的用户基础,舍弃VBA重新开发一个Python版本的Excel对象模型对用户来说会增加学习成本。

我们不妨畅想一下,微软真的把Python集成到了Excel里面生成了一个新的语言叫PyA。那么它会面临哪些挑战。

    1. VB解释器换成了Py解释器
    2. 常用的数据分析的类库一并加入Office中。数据分析类库是用Python开发Excel的唯一优势,除了这一项Python没有哪里比VB好。但是添加了一些类库那么整个Office都要变得更大,而这些类库对Office的其它产品没有意义。
    3. 开发的时候Python可能会添加外部引用,这样生成的启用宏的工作簿要把外部引用一并打包进去。
    4. 编辑器要换一套
    5. 开发一套Python的Excel对象模型

面对种种原因,我不觉得微软会把Python集成到Office。

Python与VBA合作

既然VBA是开发Excel最好的语言,那么我们用Python与Excel交互可以让Python与VBA相互合作从而实现优势互补。怎么合作,就是本篇文章的重点所在。

我们需要安装一个Excel插件SqlCel或者SqlCelFuncs引用其中的SqlCelFuncs函数实现交互。
SqlCelFuncs下载地址
https://sqlcel.com/sqlcel/sqlcel/sqlcelfuncs.zip
SqlCelFuncs具体使用方法请参考:
https://sqlcel.com/sqlcelfuncs/

接下来介绍在Python中引用这些函数的具体步骤。
1)在python项目中添加引用pythonnet(File->Settings->Project Interpreter->添加pythonnet引用);
2)将Bridge.dll(可在SqlCel或SqlCelNear安装目录找到)复制到Python项目根目录;
3)通过以下语句引用当前模块的函数

import clr
clr.FindAssembly('Bridge.dll')  #加载Bridge.dll
from Bridge import AddInFuncs   #导入类AddInFuncs
s = AddInFuncs()

if __name__ == '__main__':   #主程序
    s.AddMoudle()    #引用Python函数

给一个具体的栗子:
先在Python项目中新建一个文件取名为VBA(右键项目 -> New -> File -> Text)并录入以下VBA代码:

Function GetRngValue(add As String)
    GetRngValue = Range(add).Value
End Function

Function GetRng(add As String) As Range
    Set GetRng = Range(add)
End Function

'将Python的二维数组写入Excel
Sub TransPyArrToVba(pyarr As Variant, rn As Range)
    Dim arr() As Variant
    bound1 = UBound(pyarr)
    bound2 = UBound(pyarr(0))
    ReDim Preserve arr(bound1, bound2)
    Dim i As Long, j As Long
    For i = 0 To bound1
        For j = 0 To bound2
            arr(i, j) = pyarr(i)(j)
        Next j
    Next i
    Range(rn, Cells(rn.Row + UBound(arr, 1), rn.Column + UBound(arr, 2))).Value = arr
End Sub

新建一个Python文件并录入以下代码:

import clr
import sys
clr.FindAssembly('Bridge.dll')     #加载Bridge.dll
from Bridge import AddInFuncs      #导入AddInFuncs类
s = AddInFuncs()         #为便于引用将AddInFuncs类赋予变量s
if __name__ == '__main__':         #主程序
    s.ClearMoudle()                #先清空模块
    s.AppendFile(sys.path[0] + "\\VBA")    #将VBA代码写入Excel
    val = s.Run("GetRngValue", "A1:D3")     #调用自定义的VBA函数GetRngValue并传入参数"A1:D3"
    val = [[val[i, j] * *2 for j in range(1, val.GetUpperBound(1) + 1)]
           for i in range(1, val.GetUpperBound(0) + 1)]    #求取每个数字的平方
    s.Run("TransPyArrToVba", val, s.Run("GetRng", "F1"))    #结果从F1单元格向下写入

一般情况下我们不会直接在Python环境中写VBA代码,而是在Excel的VBE中写好之后再复制到Python环境中。

点我了解SqlCel(https://sqlcel.com/)

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2020-6-15 07:00 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2020-6-15 08:05 | 显示全部楼层
s = AddInFuncs()         #为便于引用将AddInFuncs类赋予变量s
s不是变量,这句是创建实列类对象,推荐用cython写function。

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-6-15 09:27 | 显示全部楼层
sheeboard 发表于 2020-6-15 08:05
s = AddInFuncs()         #为便于引用将AddInFuncs类赋予变量s
s不是变量,这句是创建实列类对象,推荐用 ...

实例化的同时赋予变量。

TA的精华主题

TA的得分主题

发表于 2020-6-15 10:14 | 显示全部楼层
本帖最后由 sheeboard 于 2020-6-15 10:17 编辑
Askinofblue 发表于 2020-6-15 09:27
实例化的同时赋予变量。

两者占地址空间是不同的。

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-6-15 10:17 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2020-6-15 10:18 | 显示全部楼层
本帖最后由 sheeboard 于 2020-6-15 10:21 编辑
Askinofblue 发表于 2020-6-15 10:17
这么纠结有意思吗,累不

这个和地址管理有关,如果是写C/C++的话还是会严格区分的。同样一个数据写在堆和栈里,操作不一样。

TA的精华主题

TA的得分主题

发表于 2020-6-15 10:26 | 显示全部楼层
请举一个用python可以实现,用VBA实现不了的例子。感觉这样做是画蛇添足,没有任何优势可言

TA的精华主题

TA的得分主题

发表于 2020-6-15 10:27 | 显示全部楼层
强大的VBA加上API,可以做任何你想做的事情。

TA的精华主题

TA的得分主题

发表于 2020-6-15 17:57 | 显示全部楼层
不懂python,用python操作excel的目的是什么?是为了让别人看不到代码吗?
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-7-15 20:46 , Processed in 0.038279 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表