如何使用 Python 添加和编辑 Excel VBA 宏(无需安装 Excel)

有些时候,我们需要在 Linux、容器或云环境中修改 Excel 文件中的 VBA 宏。传统的 openpyxl 无法写入宏代码,而 win32com 又只能在 Windows 下运行。本文将介绍一种脱离 Excel 运行环境的免安装方案:直接在 Python 中实现 VBA 宏代码的添加、修改和删除,主要涵盖内容如下:

  • 环境准备

  • 理解 4 种 VBA 模块类型

  • 使用 Python 给 Excel 文件添加 VBA 宏

  • 使用 Python 修改 Excel 中已有的 VBA 代码

  • 使用 Python 删除 Excel VBA 宏

  • 总结

环境准备

要在不调用 Office COM 接口的前提下解析 .xlsm 或 .xlsb 的二进制结构,需要借助能直接读写 VBA Project 的底层库。 本文使用 Spire.XLS for Python,它是一个独立的 Excel 处理引擎,完全脱离 Office 依赖,非常适合部署在 Linux、云环境或 Docker 容器中。

你可以直接通过 PyPI 安装该库:

复制代码
pip install Spire.XLS

注意: 这里操作的是 Excel 文件中的 VBA 代码,并不会实际执行 VBA 宏。要运行宏,仍然需要 Microsoft Excel 等支持执行 VBA 的环境。

理解 4 种 VBA 模块类型

通过代码添加 VBA 时,需要根据用途选择合适的模块类型。在 Excel 中,不同类型的 VBA 模块适用于不同的代码组织方式和执行场景。

  • 标准模块(Standard Module)

    用于存放通用 VBA 代码。普通宏、可复用的 Sub 过程以及不依赖特定工作簿对象的自定义函数(UDF),通常都放在标准模块中。

  • 文档模块(Document Module)

    与具体 Excel 对象直接关联,例如 ThisWorkbook 或某个工作表。通常用于编写事件代码,例如工作簿打开时自动执行的代码,或者工作表内容发生变化时触发的 Worksheet_Change 事件。

  • 类模块(Class Module)

    用于定义自定义 VBA 类,可以创建包含属性、方法和事件的可复用对象。

  • 用户窗体(UserForm)

    与 VBA 自定义界面相关。除了保存窗体本身的界面设计,还包含按钮单击、下拉框选择等控件事件的处理代码。

对于普通的通用宏,通常使用标准模块 即可。如果代码需要响应工作簿或工作表事件,则应放在相应的文档模块中。

使用 Python 给 Excel 文件添加 VBA 宏

向 Excel 工作簿添加 VBA 宏的流程主要分为 3 步:

  1. 在工作簿 Modules 集合中添加新模块,并通过 VbaModuleType 枚举指定模块类型。

  2. 将 VBA 源代码以多行字符串的形式赋值给模块的 SourceCode 属性。

  3. 将工作簿保存为支持宏的 Excel 格式。

下面的示例演示了如何在一个 Excel 文件中新建一个标准模块,并添加一段自动填充样式与数据的 VBA 脚本:

python 复制代码
from spire.xls import Workbook, VbaModuleType, FileFormat

# 创建工作簿
workbook = Workbook()

# 初始化 VBA 项目
vba_project = workbook.VbaProject
vba_project.Name = "SampleVBAMacro"

# 添加一个标准模块
vba_module = vba_project.Modules.Add("SampleModule", VbaModuleType.Module)

# 写入 VBA 源代码
vba_module.SourceCode = """Sub ExampleMacro()
    Dim ws As Worksheet
    Dim i As Integer

    ' 获取当前活动工作表
    Set ws = ActiveSheet
    ws.Cells.Clear

    With ws
        ' 写入表头
        .Range("A1:C1").Value = Array("序号", "项目名称", "金额")

        ' 填充示例数据
        For i = 1 To 10
            .Cells(i + 1, 1).Value = i
            .Cells(i + 1, 2).Value = "项目 " & i
            .Cells(i + 1, 3).Value = i * 100
        Next i

        ' 自动调整列宽与样式
        .Columns("A:C").AutoFit
        With .Range("A1:C1")
            .Font.Bold = True
            .Interior.Color = RGB(200, 220, 255)
        End With
        .Range("C2:C11").NumberFormat = "$#,##0.00"
    End With

    MsgBox "数据填充完成!", vbInformation, "操作提示"
End Sub"""

# 必须保存为支持宏的格式
workbook.SaveToFile("AddVBAMacro.xlsm", FileFormat.Xlsm)
workbook.Dispose()

这里将文件保存为 .xlsm 格式。如果保存为普通的 .xlsx 文件,VBA 代码将无法保留。除了 .xlsm 外,还可以保存为其他支持 VBA 宏的 Excel 格式,例如:

  • .xlsb --- Excel 二进制工作簿

  • .xls --- 旧版 Excel 工作簿

  • .xltm --- 启用宏的 Excel 模板

对于目前常见的启用宏的 Excel 工作簿,.xlsm 仍然是最常用的格式。

使用 Python 修改 Excel 中已有的 VBA 代码

如果需要修改已有宏,首先要访问工作簿中的 VBA 项目,然后找到目标模块,并修改它的 SourceCode 属性。

以下代码加载刚才生成的 AddVBAMacro.xlsm 文件,找到名为 SampleModule 的标准模块,然后通过字符串替换方法,修改金额计算方式和宏执行完成后的提示信息。

python 复制代码
from spire.xls import Workbook, FileFormat

workbook = Workbook()
workbook.LoadFromFile("AddVBAMacro.xlsm")

vba_project = workbook.VbaProject

# 按名称获取目标模块
vba_module = vba_project.Modules["SampleModule"]

# 提取源码并使用 Python 字符串操作进行替换
source_code = vba_module.SourceCode
source_code = source_code.replace("i * 100", "i * 150")
source_code = source_code.replace("数据填充完成!", "数据已更新!")

# 重新写回模块
vba_module.SourceCode = source_code

workbook.SaveToFile("ModifyVBAMacro.xlsm", FileFormat.Xlsm)
workbook.Dispose()

这种字符串替换方式适合只修改宏中的某个公式、常量、提示信息或少量代码。如果需要大幅调整宏逻辑,也可以直接为 SourceCode 赋值新的完整 VBA 代码,而不必逐段替换。

补充:如何修改文档模块?

上面的 Modules["名称"] 方法适用于获取标准模块。如果你想修改的 VBA 代码位于某个工作表关联的文档模块中,例如 Worksheet_ChangeWorksheet_Activate 等工作表事件,则需要先获取对应的工作表对象,通过 GetWorksheetModule() 获取它的 VBA 模块,再通过 SourceCode 属性修改代码:

python 复制代码
# 获取第一个工作表对应的 VBA 文档模块
worksheet = workbook.Worksheets[0]
vba_module = vba_project.Modules.GetWorksheetModule(worksheet)

# 同样通过 vba_module.SourceCode 即可读取或重写

使用 Python 删除 Excel VBA 宏

删除 Excel 宏有 3 种方式,具体选择哪种方法取决于你是否只想删除某一个 VBA 模块,还是希望清除整个工作簿中的所有宏。

删除指定 VBA 模块

如果只需要删除某个特定模块,可以根据模块名称将其从 Modules 集合中移除。

python 复制代码
from spire.xls import *

workbook = Workbook()
workbook.LoadFromFile("Sample.xlsm")

vba_project = workbook.VbaProject

vba_project.Modules.Remove("SampleModule") # 按名称精准删除

workbook.SaveToFile("RemoveModule.xlsm", FileFormat.Xlsm)

workbook.Dispose()

这种方式适合工作簿中包含多个 VBA 模块,而只需要删除其中某个不再使用的模块的情况。

清除所有宏但保留 .xlsm 格式

有时业务流程要求输出文件必须保持 .xlsm 扩展名,但出于安全考虑又不希望里面带任何可执行代码。这种情况下,可以将工作簿的 HasMacros 属性设置为 False。设置后,所有宏代码将被移除

python 复制代码
from spire.xls import *

workbook = Workbook()
workbook.LoadFromFile("Sample.xlsm")

# 直接将宏标记设为 False,内部所有代码将被清空
workbook.HasMacros = False

workbook.SaveToFile("RemoveAllMacros.xlsm", FileFormat.Xlsm)

转换为不支持宏的 .xlsx 格式

如果文件处理完后只需要供普通用户查看、编辑或共享,并且后续不再需要运行 VBA,直接转存为 .xlsx 即可。由于 .xlsx 格式本身不支持 VBA 项目,因此在转换后宏内容会自动被移除:

python 复制代码
from spire.xls import *

workbook = Workbook()
workbook.LoadFromFile("Sample.xlsm")

# 转存为标准 XLSX,宏自动丢失
workbook.SaveToFile("MacroFreeWorkbook.xlsx", FileFormat.Version2016)
workbook.Dispose()

总结

本文介绍了如何使用 Python 直接操作 Excel 文件中的 VBA 项目,包括添加新的 VBA 模块、修改已有宏代码、访问工作表对应的文档模块,以及删除指定模块或清除整个工作簿中的宏。

这种方式不依赖 Microsoft Excel,也不需要通过 Windows COM 接口进行自动化,因此可以应用于 Linux、服务器、容器和云环境中的 Excel 文件处理流程。

需要注意的是,这里的重点是插入、读取或修改工作簿中保存的 VBA 代码,而不是执行宏本身。宏的实际运行仍需要 Microsoft Excel 等支持 VBA 运行的环境。

相关推荐
2601_962295991 小时前
Python+Appium 自动化测试:从基础语法到 PO 模式设计,构建稳定测试框架
自动化测试·python·appium·测试框架·po模式
开源量化GO1 小时前
先确认策略想法能不能变成规则
人工智能·python
拜托多多指教1 小时前
【Pytest框架学习】分层架构
python·pytest
zhanghaha13141 小时前
Python进阶教程:24_Markdown 转 HTML 零基础超详细教程
开发语言·python·html
2601_962299881 小时前
python脚本如何单元测试
python·单元测试·pytest·unittest·mock对象
女神下凡1 小时前
PyCharm 2026破解激活
ide·python·pycharm
似水এ᭄往昔1 小时前
【QT】--常用控件(QWidget的核心属性)
服务器·开发语言·qt
DeepVisionary1 小时前
视频生成首次按秒收费:Gemini Omni 1.1 Flash 4K 每秒 0.3 美元,360p 到 4K 全档位定价
python·自动化
吴声子夜歌1 小时前
Guava——反射
java·开发语言·guava