简体   繁体   English

Excel VBA:另存为,然后杀死旧文件具有权限错误

[英]Excel VBA: SaveAs, then killing old file has permission error

I have Excel VBA code, which I have distributed, to produce some reports. 我已经分发了Excel VBA代码,以生成一些报告。 The code has errors, and I have now fixed them. 该代码有错误,我现在已修复它们。 I want to update the end users. 我想更新最终用户。

Assume that the code is in a macro workbook "software.xlsm", as is any data that they have entered. 假定代码和它们输入的任何数据一样都在宏工作簿“ software.xlsm”中。

What I have done is to create "software v1.0.1.xlsm". 我所做的是创建“软件v1.0.1.xlsm”。 It checks for the presence of "software.xlsm" and copies all the data and parameters from it to itself. 它检查“ software.xlsm”是否存在,并将所有数据和参数从其复制到自身。 It then renames "software.xlsm" as "software v1.0.0.xlsm.old", and saves itself as "software.xlsm". 然后,它将“ software.xlsm”重命名为“ software v1.0.0.xlsm.old”,并将自身保存为“ software.xlsm”。 At this point, Excel is quite happy that this is the new name for the workbook. 在这一点上,Excel非常高兴这是工作簿的新名称。

All that remains is to delete the "updater". 剩下的就是删除“更新程序”。 But this is where I run into permission errors - Excel won't let me kill it. 但这是我遇到权限错误的地方-Excel不会让我杀死它。 It is not in use anywhere else, and it seems as if Excel isn't letting go of the original file name. 它在其他任何地方都没有使用,似乎Excel并没有放弃原始文件名。

This is my code: 这是我的代码:

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

I'm tearing my hair out here. 我在这里扯头发。 I have checked here an online, and what I am doing should work - but it doesn't! 我已经在这里在线检查了一下,我在做什么应该可以工作-但是没有!

Thanks. 谢谢。

EDIT: I should mention that I have also tried SetAttr on the file, which also has no effect. 编辑:我应该提一下,我也在文件上尝试了SetAttr ,这也没有任何效果。

EDIT2: I am not sure I am being clear about what I want to do. EDIT2:我不确定我想做什么。 I want to get rid of the updater once it has run, so as to not confuse the users. 我想在更新程序运行后摆脱它,以免混淆用户。 So I used "SaveAs" to save the updater with a new name, which left TWO files on the disk, and ONE file open in Excel. 因此,我使用“另存为”以新名称保存了更新程序,该更新程序在磁盘上保留了两个文件,并在Excel中打开了一个文件。 I am then trying to kill / delete the file that IS NO LONGER open in Excel (ie the updater before I saved it with a new name). 然后,我试图杀死/删除在Excel中不再打开的文件(即,在使用新名称保存文件之前,更新程序)。

newWb.Close (you have to close it before you can delete it) newWb.Close (您必须先关闭它才能删除它)

You can also try setting the variable to nothing. 您也可以尝试将变量设置为空。

Set newWb = Nothing

The error you are encountering is because you are trying to access the FullName of the workbook which has since changed after the SaveAs . 您所遇到的错误是因为你试图访问的FullName ,其中后已经改变了工作簿的SaveAs For example. 例如。 If I have a workbook with the FullName "SomeFilePath.foo" and I do a SaveAs with FullName & ".old" the FullName is now "SomeFilePath.foo.old" . 如果我有一个具有FullName "SomeFilePath.foo"的工作簿,并且使用FullName & ".old"做一个SaveAs ,则FullName现在是"SomeFilePath.foo.old"

This makes sense, but the part you are getting tripped up on is your thisname variable. 这是有道理的,但您遇到的问题是thisname变量。 For example: 例如:

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"

The workbook by the old name simply doesn't exist anymore. 原来名称的工作簿根本不存在了。 It has been changed to the new name. 它已更改为新名称。

How do we fix this? 我们该如何解决? You could find the new name and still Kill it, but you dont see Kill often for a reason, it is a bad practice. 您可以找到新名称并仍然将其Kill ,但是由于某种原因您经常看不到Kill ,这是一个不好的做法。

The ideal would be to properly host, and reference, your workbook. 理想的做法是正确托管和引用您的工作簿。 For example: 例如:

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

We are almost there. 我们就快到了。 We are saving the workbook and closing the current workbook, but this isnt actually what we want. 我们正在保存工作簿并关闭当前工作簿,但这实际上不是我们想要的。 What we need instead is: 我们需要的是:

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

Instead of changing the FilePath of the updating workbook, just make a copy of it. 无需更改更新工作簿的FilePath,只需对其进行复制。 Not only is it cleaner, but it allows us to not have to worry about the funky things that can happen when we mess with a file when it has code currently running. 它不仅更清洁,而且还使我们不必担心当文件当前正在运行时弄乱文件时可能发生的时髦事情。

Note though, you will want to chance the output file path to the path you actually intend. 但是请注意,您将需要使输出文件路径到达您实际想要的路径。 The ".old" is purely for example. ".old"仅是示例。 Likewise, ThisWorkbook.Close(False) isn't ideal, but if you must close immediately after finishing then this will work best. 同样, ThisWorkbook.Close(False)也不理想,但是如果必须在完成后立即关闭,则效果最佳。

TLDR: The permission denied error is caused by referencing a workbook, by name, that no longer exists within the processes. TLDR:拒绝权限错误是由于按名称引用工作簿引起的,该工作簿在流程中不再存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM