Excel VBA:SaveAs,然后查杀旧文件有权限错误

我已经分配了Excel VBA代码来生成一些报告。 该代码有错误,我现在已经修复它们。 我想更新最终用户。

假设代码在macros工作簿“software.xlsm”中,就像他们input的任何数据一样。

我所做的是创build“软件v1.0.1.xlsm”。 它检查是否存在“software.xlsm”,并将其中的所有数据和参数复制到自身。 然后将“software.xlsm”重命名为“software v1.0.0.xlsm.old”,并保存为“software.xlsm”。 在这一点上,Excel很高兴这是工作簿的新名称。

剩下的就是删除“更新”。 但这是我遇到许可错误 – Excel不会让我杀了它。 它没有在其他地方使用,似乎Excel不放弃原来的文件名。

这是我的代码:

set newWb = ActiveWorkbook thisName = newWb.FullName ' get full name of updater newWb.SaveAs newWb.Path & "\software.xlsm" ' save updater as code file Kill thisName ' delete updater <!! FAILS 

我在这里把头发撕掉 我在网上查了一下,我在做什么应该可以工作 – 但是不行!

谢谢。

编辑:我应该提到,我也试过SetAttr的文件,这也没有效果。

编辑2:我不确定我正在清楚我想做什么。 我想摆脱更新一旦运行,以免混淆用户。 所以我用“另存为”保存更新程序的新名称,在磁盘上留下两个文件,并在Excel中打开一个文件。 然后,我试图杀死/删除Excel中不再打开的文件(即更新之前,我保存一个新的名称)。

newWb.Close (你必须closures它,然后才能删除它)

你也可以尝试设置variables为空。

Set newWb = Nothing

您遇到的错误是因为您正在尝试访问工作簿的完整名称,该工作簿已在“ SaveAs之后进行了更改。 例如。 如果我有一个FullName "SomeFilePath.foo"的工作簿,并且我用FullName & ".old" FullName "SomeFilePath.foo"做了SaveAs ,那么FullName现在是"SomeFilePath.foo.old"

这是有道理的,但你被绊倒的部分是你的thisnamevariables。 例如:

 Dim thisName as String thisName = ActiveWorkbook.FullName Debug.Print thisName ' EG "SomeFilePath.Foo" ActiveWorkbook.SaveAs ActiveWorkbook.FullName & ".old" Debug.Print thisname ' Still "SomeFilePath.Foo" 

老名字的工作簿根本不存在了。 它已被更改为新名称。

我们如何解决这个问题? 你可以find新的名字,然后Kill它,但是你不经常看到Kill的原因,这是一个不好的习惯。

理想的做法是正确地主持和参考你的工作手册。 例如:

 thisName = thisWorkbook.FullName thisWorkbook.SaveAs thisWorkbook.FullName & ".old" thisWorkbook.Close(False) 

我们就快到了。 我们正在保存工作簿并closures当前的工作簿,但这实际上并不是我们想要的。 我们需要的是:

 thisWorkbook.SaveCopyAs thisWorkbook.FullName & ".old" thisWorkbook.Close(False) 

而不是更改更新工作簿的FilePath,只需复制它。 它不仅更清洁,而且使我们无需担心当代码正在运行时,如果我们弄乱了一个文件,可能会发生这样的事情。

但是请注意,您将希望将输出文件path提升到您实际打算的path。 ".old"纯粹是例如。 同样, ThisWorkbook.Close(False)并不理想,但如果您必须在完成后立即closures,那么这将工作得最好。

TLDR:权限被拒绝的错误是由引用工作簿(按名称)在进程中不再存在引起的。