当由ThisWorkbook.Close调用时,Excel的BeforeClose脚本中的工作表解除保护不起作用

时间:2018-10-24 21:58:13

标签: excel vba excel-vba

我有一本excel工作簿,用于保护和隐藏所有工作表,但其中一个工作表在关闭之前。在该工作表上,应该取消保护工作表,清除一些单元格值,然后重新保护工作表。

当我关闭工作簿且X位于右上角时,子程序运行正常。当我尝试使用ThisWorkbook.Close时,实际上并未取消保护工作表的保护,因此在尝试清除单元格值时出现运行时错误'1004'。

我需要.Close方法来处理另一个脚本,该脚本将在x时间后关闭工作簿。

关闭脚本之前

Private Sub Workbook_BeforeClose(Cancel As Boolean)

ThisWorkbook.Unprotect Password:=pw
For Each Worksheet In ThisWorkbook.Worksheets
    Worksheet.Protect Password:=pw
    If Worksheet.Name = "Control Tab" Then
        With Worksheet
            .Unprotect Password:=pw
            .Cells(24, 4).Value = ""
            .Cells(24, 5).Value = ""
            .Cells(24, 6).Value = ""
            .Cells(24, 7).Value = ""
            .Cells(24, 8).Value = ""
            .Cells(24, 9).Value = ""
            .Cells(24, 10).Value = ""
            .Cells(24, 11).Value = ""
            .Cells(24, 12).Value = ""
            .Cells(24, 13).Value = ""
            .Cells(24, 14).Value = ""
            .Cells(24, 15).Value = ""
            .Cells(24, 16).Value = ""
            .Protect Password:=pw
        End With
    Else
        Worksheet.Visible = 0
    End If
Next
ThisWorkbook.Protect Password:=pw

ThisWorkbook.Save
End Sub

关闭工作簿(用于测试)的按钮

Sub Button1_Click()
    ThisWorkbook.Close
End Sub

我试图寻找一个问题,为什么在问题上与手动关闭google上的工作簿和stackoverflow之间可能存在差异,但还没有找到关于脚本为何无法解除保护工作表的见解。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

首先,我不会将该代码放入Workbook_BeforeClose;我会将其放在Workbook_BeforeSave中并使用,

Private Sub Workbook_BeforeClose(Cancel As Boolean)

    if not thisworkbook.saved then _
        ThisWorkbook.Save

End Sub

...作为关闭工作簿的方法。我不会写白皮书行话的段落,以说明原因。在我看来,这似乎是一个更好的方法,并且仍然允许您在关闭工作簿之前将其强制设置为特定条件。使用您的方法,理论上可以手动将工作簿保存为其他状态,然后通过文件资源管理器复制新保存的工作簿,而无需关闭工作簿。

最后,为什么控制标签工作表没有受到UserInterfaceOnly:=True参数的保护?这样一来,您就可以通过VBA进行任何所需的修改,而无需取消保护/修改/重新保护该特定工作表,而又仍然限制了用户。

运行此一次,然后删除所有VBA引用以取消保护/保护“控制选项卡”工作表(除非您特别想向用户打开它)。

sub RunOnce()
    with thisworkbook.worksheets("Control Tab")
        .Unprotect Password:=pw
        .Protect Password:=pw, UserInterfaceOnly:=True
    end with
end sub

任何会影响“控制选项卡”工作表的VBA编码都将运行。 注意事项:如果您想避免完全分散消息对话框的注意力,则可能需要进行一些编码修改,要求Application.DisplayAlerts = False。