首页 > 解决方案 > 由 ThisWorkbook.Close 调用时,Excel 取消保护 BeforeClose 脚本中的工作表

问题描述

我有一个 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 上的工作簿之间可能存在差异,但没有找到任何关于为什么脚本不会取消保护工作表的见解。任何帮助将不胜感激。

标签: excelvba

解决方案


首先,我不会将该代码放在 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 的编码修改。


推荐阅读