Excel文件中的VBA脚本,在文件使用WPS编辑保存后无法执行
前文:团队有一个老项目,有一些配置内容使用 Excel 维护,里边有一些 VBA 基于配置的项目内容生成一系列的 sql 脚本; 该文件的创建和更新一直使用的是Microsoft Office,团队中有小伙伴使用了 WPS 对该文件进行编辑保存,并且未按要求执行VBA, 等到配置管理员去获取 sql 脚本时才发现问题,这里,记录一下对文件的修复。
🧩 原因分析:WPS 修改文件内部结构导致 Excel 无法识别对象引用
WPS 打开并保存 .xlsm
文件时,常见破坏点包括:
破坏类型 | 说明 |
---|---|
VBA Project 结构损坏 | 导致 Excel 无法初始化 VBProject ,从而在任何 ThisWorkbook / Sheets 引用时出错 |
ActiveX 控件标识丢失 | Excel 打开时尝试加载控件失败,报 ActiveX component can't create object |
XML 关系 (rels) 文件被改写 | Excel 文件是 ZIP 包结构,WPS 重新生成内部链接关系,VBA 模块无法被正确绑定到 Workbook |
Workbook 类型降级 | 被保存为普通 .xlsx 或伪 .xlsm (扩展名有宏但内部未启用 VBA 模块) |
🔧 解决方案(推荐做法)
✅ 方案一:导出并重新导入 VBA 模块(最安全的修复方式)
打开 能正常运行 VBA 的旧版本文件。
在 VBA 编辑器中(
Alt + F11
):右键项目 → 导出文件 (Export File...)
导出所有模块、表单、类模块(
.bas
/.frm
/.cls
文件)。
打开 被 WPS 保存过的文件(当前损坏的那个)。
在 VBA 编辑器中:
删除所有现有模块(右键 → 移除模块 → “是否导出” 选否)
然后使用 文件 → 导入文件 (Import File...) 把刚才导出的模块重新导入。
保存为新文件(例如
Fixed.xlsm
)。关闭并重新打开,测试。
⚠️ 注意:一定要用 Excel 自己打开
.xlsm
文件,而不是再用 WPS。
✅ 方案二:新建空白 Excel 文件并迁移工作表 + 宏
在 Excel 中创建一个全新的
.xlsm
文件。打开旧文件(被 WPS 改过的那个)。
将工作表复制粘贴到新文件中(**不要使用“移动或复制”**命令,手动复制内容)。
在新文件的 VBA 编辑器中,导入之前导出的模块。
保存并测试运行宏。
这样可以彻底避开损坏的内部引用结构。
✅ 方案三:检查文件结构(可选进阶)
如果你想确认是否真被 WPS 破坏:
将
.xlsm
文件扩展名改成.zip
。解压缩后查看内部:
正常文件应有
xl/vbaProject.bin
如果缺失或文件大小为 0 KB,则说明 VBA 项目已损坏。
🚫 避免再次发生
永远不要用 WPS 打开或编辑带 VBA 的 Excel 文件(特别是
.xlsm
/.xls
)。如果团队成员需要查看内容,请导出为
.xlsx
或 PDF 版本。建议在 Office 中打开前先右键 → 属性 → 勾选 “解除锁定 (Unblock)”。
🧠 小结
状态 | 结论 |
---|---|
旧文件正常 | Excel 环境正常 |
WPS 编辑后出错 | 文件结构损坏 |
报错位置在 ThisWorkbook.Worksheets(...) | VBA 项目引用丢失 |
“导出 + 重新导入 VBA 模块”的自动脚本.
这个脚本可以帮你自动导出所有模块,然后导入到新的干净工作簿,从而修复被 WPS 修改导致的 VBA 结构异常。分成两个步骤来给出脚本,确保操作安全。
🧩 一、导出模块脚本(在“旧文件”中运行)
这个脚本用于从原始可运行或部分损坏的文件中导出全部模块。
操作步骤:
打开有宏的工作簿(即出错或旧文件)。
按下
Alt + F11
打开 VBA 编辑器。插入一个新模块(菜单栏:插入 → 模块)。
将以下代码完整复制进去。
修改导出目录(如
C:\Temp\VBAExport
)。运行
ExportAllVbaModules
宏。
Sub ExportAllVbaModules()Dim vbComp As ObjectDim exportPath As String' 导出目录,请修改为你自己的路径exportPath = "C:\Temp\VBAExport\"' 若文件夹不存在则创建If Dir(exportPath, vbDirectory) = "" ThenMkDir exportPathEnd If' 导出所有模块、类模块、窗体For Each vbComp In ThisWorkbook.VBProject.VBComponentsSelect Case vbComp.TypeCase 1 ' 标准模块vbComp.Export exportPath & vbComp.Name & ".bas"Case 2 ' 类模块vbComp.Export exportPath & vbComp.Name & ".cls"Case 3 ' 表单vbComp.Export exportPath & vbComp.Name & ".frm"Case Else' 忽略文档模块(如 Sheet1, ThisWorkbook)End SelectNext vbCompMsgBox "模块已导出到: " & exportPath, vbInformation
End Sub
💡 导出完后,文件夹下会看到
.bas
,.cls
,.frm
文件。
🧩 二、导入模块脚本(在新文件中运行)
打开一个新的空白 Excel 文件。
按
Alt + F11
→ 插入模块。复制以下脚本进去。
修改
importPath
为你刚刚导出模块所在目录。运行
ImportAllVbaModules
。
Sub ImportAllVbaModules()Dim fso As ObjectDim folder As ObjectDim file As ObjectDim importPath As StringimportPath = "C:\Temp\VBAExport\" ' ← 修改为你的导出路径Set fso = CreateObject("Scripting.FileSystemObject")Set folder = fso.GetFolder(importPath)For Each file In folder.FilesIf LCase(fso.GetExtensionName(file.Name)) Like "bas" Or _LCase(fso.GetExtensionName(file.Name)) Like "cls" Or _LCase(fso.GetExtensionName(file.Name)) Like "frm" ThenThisWorkbook.VBProject.VBComponents.Import file.PathEnd IfNext fileMsgBox "模块导入完成!", vbInformation
End Sub
⚠️ 确保在信任中心中 勾选了:
“信任对 VBA 项目对象模型的访问”
否则 Excel 不允许自动导入模块。
✅ 完成后
保存新文件为
Fixed.xlsm
。关闭并重新打开。
测试你的主宏是否正常执行(
teacherfunctionalityjpSQL
等)。
🧠 小结
阶段 | 操作 | 文件 |
---|---|---|
导出 | ExportAllVbaModules | 旧文件 |
导入 | ImportAllVbaModules | 新 .xlsm 文件 |
保存 | 另存为 Fixed.xlsm | 新结构、干净引用 |