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

时间:2017-08-25 15:22:48

标签: excel vba excel-vba

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

假设代码位于宏工作簿“software.xlsm”中,就像他们输入的任何数据一样。

我所做的是创建“software 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:我不确定我是否清楚我想做什么。我想在它运行后摆脱更新程序,以免混淆用户。因此,我使用“SaveAs”来保存更新程序,使用新名称,将两个文件保留在磁盘上,并在Excel中打开一个文件。然后我试图杀死/删除在Excel中不再打开的文件(即我用新名称保存之前的更新程序)。

2 个答案:

答案 0 :(得分:0)

newWb.Close(您必须先关闭它才能删除它)

您也可以尝试将变量设置为空。

Set newWb = Nothing

答案 1 :(得分:0)

您遇到的错误是因为您尝试访问FullName之后已更改的工作簿的SaveAs。例如。如果我的工作簿中包含FullName "SomeFilePath.foo"而我SaveAs FullName & ".old" FullName现在"SomeFilePath.foo.old"

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

Dim thisName as String
thisName = ActiveWorkbook.FullName

Debug.Print thisName ' E.G "SomeFilePath.Foo"
ActiveWorkbook.SaveAs ActiveWorkbook.FullName & ".old" 

Debug.Print thisname ' Still "SomeFilePath.Foo"

旧名称的工作簿根本不存在。它已更改为新名称。

我们如何解决这个问题?您可以找到新名称并仍然Kill,但由于某种原因您经常看不到Kill,这是一种不好的做法。

理想的做法是妥善托管和引用您的工作簿。例如:

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

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

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

不要更改更新工作簿的FilePath,只需复制它即可。它不仅更干净,而且让我们不必担心当代码当前正在运行时弄乱文件时可能发生的时髦事情。

但是请注意,您可能希望输出文件路径到实际意图的路径。 ".old"纯粹是例如。同样地,ThisWorkbook.Close(False)并不理想,但如果你必须在完成后立即关闭,那么这将是最好的。

TLDR:权限被拒绝错误是由于在名称中引用了一个不再存在于进程中的工作簿而引起的。