尝试通过VBA项目(1个用户窗体,5个类模块,1个标准模块)使用受保护的工作簿(我可以访问密码)
我对如何正确使用VBA中的受保护工作表感到非常困惑。
我尝试做
ActiveSheet.Unprotect PWD
在使用
进行方法调用之后ActiveSheet.protect PWD
也尝试过
ActiveSheet.protect PWD, UserInterfaceOnly:=True
来自Workbook_open子
问题是随机出现的,例如保护恢复为受保护,而我的VBA项目中正在对实际电子表格进行更改的部分却吓到了。
如果我暂停调试器,请过去并手动取消保护工作表并单击继续,一切都会顺利进行
那么这里发生了什么
在调用其他方法来更改工作表并在最后报告它的方法的开始时,保护工作表是否还不够?
还是我真的必须在前缀和后缀
ActiveSheet.Unprotect PWD
ActiveSheet.Protect PWD
每条更改工作表数据的行周围?
因为似乎保护不关心我的VBA项目仅在我尝试对工作表进行后续操作时在内部做的任何事情
如果需要的话,我可以在今天晚些时候回家时发布代码
答案 0 :(得分:1)
在调用其他方法对表单进行更改并在最后报告其结果的方法的开头取消保护表单是不够的吗?
这就是为什么整体状态如此令人痛苦的原因。就您的VBA项目而言,工作表保护状态是全局的。因此,如果您这样做:
Public Sub Procedure1()
Sheet1.Unprotect PWD
Procedure2
'do stuff on Sheet1
Sheet1.Protect PWD
End Sub
如果Procedure2
在退出Sheet1
之前重新保护了Sheet1
,那么当Procedure1
恢复到do stuff on Sheet1
时以及您遇到问题时,Application.Calculation
再次受到保护。 ,它不太喜欢。
是的,在尝试修改工作表之前,您需要确保该工作表不受保护。
还是我真的必须在更改工作表数据的每一行周围添加前缀和后缀[...]?
你不知道。我的意思是,您要做,但您不会,如果您以一种明智的方式管理全局状态。如果任何时候任何地方的任何人都可以进入并重新保护您刚刚未保护的工作表,则您的发誓缸可以很快装满。
类似地,xlCalculationAutomatic
是全局的;但是,如果您在认真xlCalculationManual
精心制作Application.ScreenUpdating
后努力将其设置回Procedure2
(对于Procedure1
也是一样),那么您最终会发现自己触发重新计算并引入非常明显的滞后。
全局状态很好(嘿,我可以从任何地方访问它!),但也有双重优势。如果您没有正确地构造事物,全局状态会迅速 spagghettify 并变成您不需要或不需要的来回切换的混乱混乱。
解决方案是为成功做好准备,并正确地分层您的代码。将所有工作表保护切换代码放在一个地方,并约束自己只能从一个层调用该逻辑-底层的所有内容都不关心工作表保护,这与它无关。如果要使用的工作表受到保护,那么这不是问题-上层代码中有错误。
在上面的示例中,do stuff on Sheet1
将是第2层,并且完全不允许切换工作表保护。让Procedure3
负责这一点,并将Sheet1Protection
部分移到新的Option Explicit
Private Sub Class_Initialize()
Sheet1.Unprotect PWD
End Sub
Private Sub Class_Terminate()
Sheet1.Protect PWD
End Sub
上,这就像粗心地假设已经处理了工作表保护一样。
您甚至可以将切换封装在一个类中,例如Public Sub Procedure1
With New Sheet1Protection 'unprotects sheet1
Procedure2
Procedure3
End With ' object terminates, sheet1 is protected again
End Sub
:
Sheet1Protection
现在您可以执行以下操作:
AsyncTask
请注意,工作表保护将在需要时在最后一刻切换,并包装所有需要在不受保护的工作表上运行的操作。
借助Rubberduck(我管理和协助的VBE的OSS外接程序项目)之类的工具,您可以轻松地找到在onPostExecute()
之外切换工作表保护的所有位置。 ,然后将其删除。