很抱歉这个长标题。
我有几个共享大量代码的.xlsm文件,因此我将重复的部分移动到了一个addin .xlam文件中。我一直在使用.vbs脚本一个接一个地打开所有文件,并在每个文件中运行一个宏。
问题
我面临的问题是,在.vbs脚本的第二次运行中,excel崩溃并给出了一个非常普通的错误,here表示是“自动化错误”:
Script: C:\Users\~\Desktop\test\test.vbs
Line: 5
Char: 1
Error: The server threw an exception.
Code: 80010105
Source: (null)
令我惊讶的是,即使删除了99%的文件内容,我也能够重现此崩溃。
test.vbs:
Dim xlApp
Dim xlBook
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open("C:\Users\~\Desktop\test\test.xlsm")
xlApp.Run "Auto.Run" '<~~ error on this line
xlBook.Save
xlBook.Close (True)
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
test.xlsm:
test.xlam has a module Module1, test.xlsm has a Module Auto and a Reference to test.xlam
test.xlsm,Auto
:
Sub Run()
MsgBox "hello"
Test.Load
MsgBox "goodbye"
End Sub
test.xlam,Module1
Sub Load()
MsgBox "Load"
End Sub
Function Other()
End Function
将函数Other()
注释掉,代码工作正常(说好,加载和再见)。如果从excel中运行宏,它也可以正常工作。只有当Other()
存在且Run()
通过.vbs文件运行时才会出现错误(在问候之后)。
解决方法
如果我打开test.xlsm
,保存它,并在每次test.vbs
运行之间再次关闭它,就没有问题。我认为这与插件而不是电子表格有关,因为在我的原始脚本中,打开多个excel文件,只需要打开并保存一个文件。
我还注意到excel文件在“问题”状态下有点大,而且一旦我打开并保存它,它就会恢复到略小的原始大小。 (编辑:这至少部分是由vbaProject.bin
文件中的新缓存流__SRP_4和__SRP_5造成的,我使用this answer(哦,和this提取手动删除所有SRP条目后,我能够再次运行.vbs脚本而没有问题,虽然就像open-save-close策略一样,它只是临时的,然后会在第三次运行而不是第二次运行时崩溃。 )
问题
addins不适合共享代码吗?他们可能不包含功能吗?除了我现在正在做的事情之外,还有办法解决这次崩溃吗?
任何想法都表示赞赏。
答案 0 :(得分:0)
听起来像第一个实例在调用第二个实例之前没有被卸载/释放。也许在执行每次后续运行之前使用Application.Wait Method等待几秒钟可能有帮助吗?
'Open file1
'Run macro from file1
'Close file1
Application.Wait(Now + TimeValue("0:00:10")) 'wait 10 seconds
'Open file1
'Run macro from file1
...
...
So on
要通过vbscript将插件安装到Excel,您可以使用以下代码
'Launch Excel
set objExcel = createobject("Excel.Application")
strAddIn = "ESP Assistant.xlam"
'~~> Path where the XLAM resides
SourcePath = "Your source path\" & strAddIn
'Add the AddIn
On Error Resume Next
With objExcel
'Add Workbook
.Workbooks.Add
'Show Excel
objExcel.Visible = True
.AddIns.Add(SourcePath, False).Installed = True
End With
如果失败,您可能必须先清除注册表值,然后重新运行上面的脚本
'File to use just in case Add-In installation fails
'Refreshes Excel Registry Entries to allow for clean install of Add-In
Dim objFSO, objShell
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objShell = WScript.CreateObject ("WScript.shell")
objShell.Run "cmd /c ""C:\Program Files (x86)\Microsoft Office\Office14\excel.exe"" /unregserver && timeout /t 3 && tskill excel && ""C:\Program Files (x86)\Microsoft Office\Office14\excel.exe"" /regserver",1,True
Set objFSO = Nothing
Set objShell = Nothing
x=msgbox("Excel registry refreshed." ,0, "Registry Update")
wscript.quit
答案 1 :(得分:0)
不幸的是,我仍然不知道为什么会这样,但我找到了一个自动解决方案,我将会坚持下去。
正如我在我的问题中提到的那样,test.xlsm文件在它的问题中变得更大了#34;状态,至少部分归因于某种缓存,我只能找到一个官方提及here:
2.2.6 SRP Streams
指定特定于实现和版本的性能缓存的流。一定是 阅读时忽略了写作时不得出现。 每个流的名称由以下ABNF语法指定:
SRPStreamName = "__SRP_" 1*25DIGIT
我的解决方案是删除缓存,我首先使用this tool.手动执行此操作。当这似乎有效时,我编写了一个Java程序来自动执行(gist here)。它是java.util.zip和Apache POIFS之间的粘合剂。
我还在.vbs脚本的末尾添加了一行来调用Java:
CreateObject("WScript.Shell").Run "java -jar clear-excel-cache.jar C:\Users\~\Desktop\test\test.xlsm", 1, false
在我的实际.vbs文件中,它在循环中调用多个excel文件,这一行就在循环内部。每个文件运行后都会打开一个小cmd窗口,但在第二次运行时它不再崩溃,所以我称之为成功。
答案 2 :(得分:0)
您的问题可能与我尝试解决的问题相同 - 随机64位Excel 2013 VBA崩溃(VBE7.dll错误)。您可以检查应用程序事件日志中是否有VBE7.dll崩溃以确认这一点。
在我的情况下,各种XLSM文件通过手动使用会间歇性地损坏。
我的修复作为你的替代品是以下VBS(任何触发VBA“重新编译”的东西)。
navbar
答案 3 :(得分:0)
仅供参考 - Microsoft于2016年5月3日发布了一个修补Excel 2013中此问题的补丁。