Python3写入xlsm文件后执行关联Excel宏报错如何解决?
问题根因
- 你用openpyxl加载xlsm格式文件时没有加
keep_vba=True参数,保存文件时会自动丢弃宏内容,导致后续xlwings打开时识别为格式无效的损坏文件 - 两种库操作同一个文件时没有预留文件句柄释放的时间,前一个操作的锁还没释放就发起下一个打开操作,引发冲突
- 不要使用
exec调用外部脚本,容易引发变量作用域、资源释放等不可预知的问题
可行实现方案
方案1:全程使用xlwings实现写入+宏执行(推荐,无兼容问题)
全程使用同一种库操作Excel,完全避免跨库文件冲突,不需要管理员权限,整合后的代码如下:
from datetime import date, timedelta import xlwings as xw file_path = r"C:/Users/project/file.xlsm" # 启动后台Excel实例,不显示窗口、不弹警告 with xw.App(visible=False, add_book=False) as app: app.display_alerts = False # 打开带宏的Excel文件 wb = app.books.open(file_path) sheet = wb.sheets["Sheet2"] # 计算目标日期 today = date.today() if today.weekday() == 0: # 周一取上周五日期 target_date = today - timedelta(days=3) else: # 其余时间取昨日日期 target_date = today - timedelta(days=1) # 格式化后写入A1单元格 sheet.range("A1").value = target_date.strftime("%x") # 执行指定宏 wb.macro('test_macro')() # 保存并关闭文件 wb.save() wb.close()
该方案会自动释放Excel进程,不会残留后台程序占用文件,兼容性最好。
方案2:保留openpyxl写入逻辑的修改方案
如果一定要使用openpyxl做写入操作,需要修改以下两点:
- 加载xlsm时必须加
keep_vba=True保留宏内容 - 写入完成后显式关闭工作簿,等待资源释放后再调用xlwings执行宏
修改后的代码如下:
from datetime import date, timedelta import openpyxl import time import xlwings as xw path = "C:/Users/project/file.xlsm" # 加载xlsm时加keep_vba=True保留宏 book = openpyxl.load_workbook(path, keep_vba=True) sheet = book["Sheet2"] a1 = sheet['A1'] print(book.sheetnames) print(a1.value) # 计算目标日期 today = date.today() if today.weekday() == 0: yesterday = today - timedelta(days=today.weekday()) + timedelta(days=4, weeks=-1) else: yesterday = today - timedelta(days = 1) yestFormat = yesterday.strftime("%x") sheet.cell(row=1,column=1,value=yestFormat) book.save(path) # 显式关闭工作簿释放资源 book.close() # 等待1秒确保文件句柄完全释放 time.sleep(1) # 调用宏 with xw.App(visible=False, add_book=False) as app: app.display_alerts = False wb = app.books.open(path) wb.macro('test_macro')() wb.save() wb.close()
运行前注意
先打开任务管理器,结束所有Excel.exe进程,避免之前异常操作残留的进程占用目标文件。
内容的提问来源于stack exchange,提问作者ssumme
相关产品推荐
相关产品推荐

