个人主页杨利杰YJlio❄️个人专栏《Sysinternals实战教程》 《Windows PowerShell 实战》 《WINDOWS教程》 《IOS教程》《微信助手》 《锤子助手》 《Python》 《Kali Linux》《那些年未解决的Windows疑难杂症》让复杂的事情更简单让重复的工作自动化《超简单用 Python 让 Excel 飞起来》读书笔记9.2.2 手动创建文件并调用 Python 自定义函数1. 9.2.2 手动创建文件并调用 Python 自定义函数2. 核心原理单元格就是参数通道3. 第一步先搭一个 Config 参数面板4. 第二步VBA 端负责写参数、校验和调度5. 第三步Python 端读取 Config 并写回结果6. 第四步把执行状态也写回 Excel7. 效果验证不要只看有没有报错8. 常见问题与踩坑记录8.1 Excel 没有反应Python 没有执行8.2 报错 No module named xlwings8.3 Config 表名写错8.4 源范围写错8.5 文本数字导致统计结果不对9. 总结把脚本升级成工具关键是可配置、可追踪、可交付1. 9.2.2 手动创建文件并调用 Python 自定义函数V4修正版进度标记本篇为 07月16日 第2篇承接 06月07日第2篇“2.7.2 自定义函数”之后继续更新。读书笔记定位本文是我阅读《超简单用 Python 让 Excel 飞起来》时整理的学习笔记重点不是照搬原书而是把本节内容重新整理成更适合博客阅读、实操复盘和后续查阅的版本。这一节要解决的痛点很现实当我们把 Excel 自动化脚本交付给同事使用时不能要求每个人都去改 Python 代码。真正好用的办公自动化工具应该做到业务人员改 Excel 参数程序自动执行结果自动回写。如果每次换数据范围、换 Sheet、换输出位置都要打开 Python 文件改变量那这个脚本本质上还是“作者本人专用”。更推荐的做法是把 Excel 工作表当作配置入口让单元格成为 VBA 与 Python 之间的参数通道。本文会围绕“Config 参数面板 VBA 调度 Python 执行 状态回写”这条链路讲清楚如何手动创建文件并通过 Excel 调用 Python 自定义函数。建议阅读方式先看整体流程理解 Excel、VBA、Python 各自负责什么再看 Config 参数面板明确参数应该如何设计最后看状态回写和常见坑避免脚本只能跑一次、不能交付关键词Python、Excel 自动化、xlwings、VBA、RunPython、Config 参数面板、自定义函数、办公自动化Excel 工作簿Config 参数面板VBA 写入和校验参数RunPython 调用 PythonPython 读取 Config执行统计或业务逻辑结果写回 Report状态写回 Config读完这篇文章至少要带走三件事为什么要把 Excel 单元格设计成“参数通道”VBA 和 Python 在混合自动化中分别承担什么角色如何让脚本执行结果可追踪、可排错、可交付。2. 核心原理单元格就是参数通道很多人第一次接触 Excel 调用 Python 时会把注意力全部放在“Python 怎么跑起来”上。这个方向没错但不够完整。真正可维护的自动化工具关键不是让 Python 跑一次而是让它能在不同输入、不同参数、不同输出场景下稳定运行。我的理解是Excel 负责承载数据和配置VBA 负责调度Python 负责计算和处理。这套结构里最关键的设计就是把 Excel 的某个工作表固定为 Config 参数面板。Python 不再直接写死路径、范围、Sheet 名而是从 Config 表读取参数。这张图展示了Excel 工作簿、参数通道、VBA 调度器、Python 计算引擎之间的完整关系。从这张图中我们可以看出参数通道并不是一个抽象概念而是一个非常具体的单元格矩阵。VBA 可以把参数写入这些单元格Python 可以从这些单元格读取配置执行完成后再把结果写回 Excel。这种设计最大的好处是脚本逻辑和业务参数分离。业务参数放在 Excel 里方便普通用户修改核心逻辑放在 Python 里方便开发者维护。不要把所有参数都写死在 Python 代码里。这样后期需求一变你就只能反复改代码脚本很难交付给别人长期使用。3. 第一步先搭一个 Config 参数面板我建议在工作簿里固定创建一个名为Config的工作表用来集中放置运行参数。这个表不要放业务明细数据它的职责只有一个告诉程序应该读哪里、算什么、写到哪里。一个最小可用的 Config 参数面板可以这样设计参数项单元格示例值含义源 SheetB2Sheet1Python 从哪个工作表读取数据源范围B3A1:A20Python 读取哪个区域输出 SheetB4ReportPython 把结果写到哪个工作表输出起点B5A1结果从哪个单元格开始写模式B6summary执行哪种业务逻辑Config 表本质上就是一个轻量级配置文件只不过它不是 JSON、YAML 或 INI而是 Excel 单元格。这张图展示了在 Excel 中建立 Config 参数面板的效果包括源 Sheet、源范围、输出 Sheet、输出起点和运行模式。从这张图中我们可以看出Config 参数面板的设计要尽量简单、直观。交付给同事时不需要解释 Python 代码只需要告诉他以后要改输入范围、输出位置、运行模式就改这几个格子。我更推荐把参数项放在 A 列参数值放在 B 列说明放在 C 列。这样既方便用户填写也方便后期维护文档。Config 表名、参数位置、单元格地址必须尽量固定。如果今天放 B2:B6明天换成 D2:D6Python 代码就会变得很难维护。4. 第二步VBA 端负责写参数、校验和调度在这套结构里VBA 不负责复杂计算。它的定位应该很清楚写入参数、做基础校验、调用 Python。为什么不建议把复杂逻辑都写在 VBA 里原因很简单VBA 适合和 Excel 交互但在数据清洗、文件处理、批量统计、图表生成、接口调用等方面Python 的可维护性更强。所以比较合理的分工是VBA 做“按钮和调度器”Python 做“计算引擎”。这张图展示了VBA 调度执行的完整流程先写入 Config 参数再做基础校验最后通过 RunPython 调用 Python 脚本。这一步的核心要点是VBA 不要只会一行RunPython。在真正交付时应该先检查参数是否为空、Sheet 是否存在、范围是否合法否则脚本失败后用户只会看到一堆看不懂的报错。下面是一段可复用的 VBA 模板Option Explicit Sub Run_With_Config_Channel() Dim wb As Workbook Set wb ThisWorkbook 1. 写入或更新 Config 参数 With wb.Worksheets(Config) .Range(B2).Value Sheet1 源 Sheet .Range(B3).Value A1:A20 源范围 .Range(B4).Value Report 输出 Sheet .Range(B5).Value A1 输出起点 .Range(B6).Value summary 执行模式 End With 2. 读取关键参数并做基础校验 Dim srcSheet As String Dim srcRange As String Dim outSheet As String Dim outCell As String With wb.Worksheets(Config) srcSheet Trim(.Range(B2).Value) srcRange Trim(.Range(B3).Value) outSheet Trim(.Range(B4).Value) outCell Trim(.Range(B5).Value) End With If srcSheet Or srcRange Or outSheet Or outCell Then MsgBox Config 参数不能为空请检查 B2:B5。, vbExclamation Exit Sub End If 3. 调用 Python RunPython import channel_demo; channel_demo.main() MsgBox Python 已执行完成结果已写回 Excel。, vbInformation End Sub这段 VBA 的价值不是代码有多复杂而是把调度流程规范化了。它明确告诉读者先准备参数再校验参数最后再执行 Python。如果直接 RunPython不做任何参数检查问题迟早会暴露在用户手里。尤其是企业环境中别人不会帮你看代码只会反馈“点了没反应”。5. 第三步Python 端读取 Config 并写回结果Python 端的核心动作也很清楚读取 Config 参数 → 执行业务逻辑 → 写回结果。这里可以通过xlwings的xw.Book.caller()获取当前调用 Python 的 Excel 工作簿然后读取 Config 表里的参数。xw.Book.caller()是 Excel 调用 Python 时非常关键的入口它让 Python 知道“是谁在调用我”。这张图展示了Python 从 Config 工作表读取参数执行处理逻辑并把统计结果写回 Report 工作表的过程。从这张图中我们可以看出Python 并不是孤立运行的脚本而是被 Excel 参数驱动的计算引擎。左边是 Config 输入中间是 Python 逻辑右边是 Report 输出结果。下面是 Python 示例文件channel_demo.pyimportxlwingsasxwdefread_config(wb:xw.Book)-dict:读取 Config 工作表中的参数cfgwb.sheets[Config]return{src_sheet:str(cfg.range(B2).value).strip(),src_range:str(cfg.range(B3).value).strip(),out_sheet:str(cfg.range(B4).value).strip(),out_cell:str(cfg.range(B5).value).strip(),mode:str(cfg.range(B6).value).strip().lower(),}defensure_sheet(wb:xw.Book,sheet_name:str)-xw.Sheet:如果输出工作表不存在则自动创建sheet_names[s.nameforsinwb.sheets]ifsheet_namenotinsheet_names:wb.sheets.add(sheet_name)returnwb.sheets[sheet_name]defflatten_values(values):把 Excel 区域读取出来的二维数据压平成一维列表ifnotisinstance(values,list):return[values]result[]forrowinvalues:ifisinstance(row,list):result.extend(row)else:result.append(row)returnresultdefsummarize(values):对数值数据做基础统计nums[]forvalueinflatten_values(values):ifvalueisNoneorvalue:continuetry:nums.append(float(value))exceptException:passifnotnums:returnNonereturn{count:len(nums),sum:sum(nums),avg:sum(nums)/len(nums),max:max(nums),min:min(nums),}defmain():Excel 调用 Python 的主入口wbxw.Book.caller()cfgread_config(wb)src_shtwb.sheets[cfg[src_sheet]]datasrc_sht.range(cfg[src_range]).value out_shtensure_sheet(wb,cfg[out_sheet])ifcfg[mode]summary:resultsummarize(data)ifresultisNone:out_sht.range(cfg[out_cell]).value[[没有可用数值数据]]returnrows[[指标,值],[数量 count,result[count]],[总和 sum,result[sum]],[平均 avg,result[avg]],[最大 max,result[max]],[最小 min,result[min]],]out_sht.range(cfg[out_cell]).valuerowselse:out_sht.range(cfg[out_cell]).value[[f未知模式{cfg[mode]}]]这段代码真正可复用的地方在于 mode 字段。现在我们只写了summary模式后面完全可以扩展成clean、chart、pivot、export等不同模式。不要让一个 Python 文件只能处理一种固定场景。如果你已经做了 Config 参数面板就应该顺手给脚本留出扩展入口。6. 第四步把执行状态也写回 Excel很多 Excel 自动化脚本最大的问题不是不能运行而是失败后无法定位问题。用户点了按钮没看到结果也不知道是 Python 没启动、参数错了、Sheet 不存在还是代码异常。所以我建议把执行状态也写回 Config 表。这样 Excel 不只是输入参数的地方也变成了一个简单的状态面板。可以增加三个字段字段建议单元格作用运行时间戳B7记录本次脚本开始执行时间执行状态B8Running / OK / Fail错误信息B9记录异常摘要方便排障这张图展示了执行状态可视化的设计包括 OK、Fail、Running、错误信息回写等关键状态。从这张图中我们可以看出状态回写能让脚本从“黑盒工具”变成“可追踪工具”。一旦失败用户至少能看到失败阶段和错误摘要后续排障成本会低很多。Python 端可以这样封装状态回写importxlwingsasxwfromdatetimeimportdatetimedefset_status(wb:xw.Book,status:str,message:str):将执行状态写回 Config 表cfgwb.sheets[Config]cfg.range(B7).valuedatetime.now().strftime(%Y-%m-%d %H:%M:%S)cfg.range(B8).valuestatus cfg.range(B9).valuemessagedefmain():wbxw.Book.caller()try:set_status(wb,Running,)# 这里写你的正常业务逻辑cfgread_config(wb)src_shtwb.sheets[cfg[src_sheet]]datasrc_sht.range(cfg[src_range]).value out_shtensure_sheet(wb,cfg[out_sheet])resultsummarize(data)ifresultisNone:out_sht.range(cfg[out_cell]).value[[没有可用数值数据]]else:rows[[指标,值],[数量 count,result[count]],[总和 sum,result[sum]],[平均 avg,result[avg]],[最大 max,result[max]],[最小 min,result[min]],]out_sht.range(cfg[out_cell]).valuerows set_status(wb,OK,)exceptExceptionase:set_status(wb,Fail,str(e))raise状态回写是非常值得保留的工程化细节。它不会让代码复杂多少但能显著提升工具的可维护性。如果不给用户任何错误信息自动化工具一旦失败就会变成只能作者本人排查的“私人工具”。7. 效果验证不要只看有没有报错脚本执行完成后不能只看“有没有弹出完成提示”。真正的验证应该看三类结果参数是否被正确读取、结果是否被正确写回、状态是否被正确更新。我一般会按下面这个顺序验证验证项预期结果Config 参数是否完整B2:B6 有源表、范围、输出表、输出起点和模式VBA 是否能正常调用点击按钮后无宏报错Python 是否能读取当前工作簿xw.Book.caller()能正常工作Report 表是否生成如果输出表不存在应自动创建统计结果是否正确count、sum、avg、max、min 与源数据一致状态是否回写B8 显示 OK 或 FailB9 有错误摘要验证结果时建议用一组非常小的数据先跑通。例如 A1:A5 放几个简单数字手工算一遍再对比 Python 输出结果。不要一上来就拿几万行真实数据测试。如果基础链路没打通大数据只会把排查范围放大。8. 常见问题与踩坑记录8.1 Excel 没有反应Python 没有执行优先检查 xlwings 插件是否加载成功以及 VBA 中是否能识别RunPython。建议先用 xlwings quickstart 生成一个最小项目确认 Excel 调 Python 的链路是通的。8.2 报错 No module named xlwings这个问题通常不是 xlwings 没装而是 Excel 调用的 Python 环境和你安装 xlwings 的 Python 环境不是同一个。本质是 Python 解释器路径不一致。可以在 xlwings 设置中检查 Interpreter也可以在当前环境重新执行pipinstallxlwings8.3 Config 表名写错如果 Python 中写的是wb.sheets[Config]那么 Excel 里工作表名称必须完全一致。多一个空格、少一个字母都会失败。工作表名称、参数单元格、输出范围这类信息最好不要频繁改。8.4 源范围写错常见错误包括把英文冒号写成中文冒号例如A1A20。Excel 看起来差不多但程序读取时可能失败。建议所有范围地址统一使用英文符号例如A1:A20。8.5 文本数字导致统计结果不对Excel 里有些数字看起来是数字实际是文本。Python 做统计前最好统一尝试转换为float无法转换的值跳过或单独记录。这也是为什么上面的 summarize 函数没有直接 sum 原始数据而是先做了数值转换。9. 总结把脚本升级成工具关键是可配置、可追踪、可交付这一节表面上讲的是“手动创建文件并调用 Python 自定义函数”但我真正想沉淀的是一个更通用的办公自动化思路不要只写能跑的脚本要写能交付的工具。这套方案可以总结为四句话Config 表负责配置让用户通过单元格修改参数VBA 负责调度写参数、做校验、调用 PythonPython 负责计算读取参数、执行逻辑、写回结果状态面板负责反馈记录 Running、OK、Fail 和错误信息。如果一个自动化脚本只能作者本人维护那它还不算真正完成。真正可交付的脚本应该让别人看得懂入口、改得动参数、查得到状态、复现得了结果。所以我建议后续写 Excel Python 自动化工具时都优先考虑“参数通道”这个设计。它不是复杂架构而是把 Excel、VBA、Python 三者的职责边界划清楚。下一篇可以继续深入如何把 Python 函数导入 Excel像普通 Excel 公式一样在单元格中调用。返回顶部