Vba 防止用户删除特定工作表

Vba 防止用户删除特定工作表,vba,excel,Vba,Excel,保护工作簿结构将阻止用户删除工作表。但如何使用VBA防止用户删除我指定的特定工作表?我见过一些示例,其中通过 Set mymenubar = CommandBars.ActiveMenuBar mymenubar.Controls("Edit").Controls("Delete sheet").Visible = False 在它的工作表中,激活事件,但当然只有在工作表被激活时才起作用。 是否有方法防止删除工作表(无论是否处于活动状态)? 为了清楚起见:我同意用户删除一些工作表,只是不删除一

保护工作簿结构将阻止用户删除工作表。但如何使用VBA防止用户删除我指定的特定工作表?我见过一些示例,其中通过

Set mymenubar = CommandBars.ActiveMenuBar
mymenubar.Controls("Edit").Controls("Delete sheet").Visible = False
在它的工作表中,激活事件,但当然只有在工作表被激活时才起作用。 是否有方法防止删除工作表(无论是否处于活动状态)? 为了清楚起见:我同意用户删除一些工作表,只是不删除一些特定的工作表。
因此,保护工作簿结构将不起作用。

您不能阻止用户删除特定工作表,但可以使用“工作簿保存前”事件来防止在特定工作表丢失时保存工作簿。有关此事件的文档精确地显示了如何仅在满足某些条件时才允许保存工作簿。请参见

据我所知,不可能以本机方式将单个工作表标记为不可删除;而且没有一个事件可用于检测何时将要删除工作表,因此工作簿可以得到预防性保护

但是,这里有一个潜在的解决方法:

保护工作簿结构:如您所示,这将防止删除所有工作表。 创建控件工作表。在此工作表上,维护所有工作表名称的列表,但不希望删除的工作表名称除外。 如果用户想要删除工作表,他们必须在控制工作表上选择其名称,例如在数据验证下拉菜单中,然后按下删除按钮。此按钮将调用一个宏,该宏暂时取消工作簿的保护,删除选定的工作表,然后重新保护工作簿。 当然,用户必须习惯这种删除工作表的方式,而不是在工作表选项卡上单击鼠标右键>删除。不过,这并不复杂

至于如何实现2,即维护图纸名称列表,我想您可以使用这样一个UDF,它必须作为数组公式调用:

Function DeletableSheetNames() As String()
    Application.Volatile
    Dim i As Long
    Dim sn() As String
    With ThisWorkbook
        ReDim sn(1 To .Sheets.Count)
        For i = 1 To .Sheets.Count
            With .Sheets(i)
                If .Name = "DataEntry1" Or .Name = "DataEntry2" Then
                    'Don't include it in the list.
                Else
                    sn(i) = .Name
                End If
            End With
        Next i
    End With
    DeletableSheetNames = sn
End Function

我可以通过工作表\u BeforeDelete事件防止删除工作表,如下所示:

Private Sub Worksheet_BeforeDelete()

    Call ThisWorkbook.Protect("password")

    Call MsgBox("This sheet cannot be deleted.", vbExclamation)

End Sub
这可以保护所有工作表不被删除,但是,如果您在ThisWorkbook模块上添加以下事件代码:

Private Sub Workbook_SheetActivate(ByVal Sh As Object)

    Call ThisWorkbook.Unprotect("password")

End Sub
然后,我将能够删除任何其他工作表一旦被选中


请记住,选中页面时,由于页面解锁,您将失去页面间的复制和粘贴功能。

我在ExtendOffice.com上找到了类似于Dan的解决方案。将此代码放在工作表的模块上:

Private Sub Worksheet_Activate()
ThisWorkbook.Protect "yourpassword"
End Sub

Private Sub Worksheet_Deactivate()
ThisWorkbook.Unprotect "yourpassword"
End Sub

激活相关工作表时,整个工作簿将受到保护,“删除”选项将灰显。当您切换到任何其他工作表时,工作簿将再次空闲。这很微妙,因为您只在转到安全工作表时才注意到更改。

没有一个事件可用于检测何时将要删除工作表


从Office 2013开始,SheetBeforeDelete事件就可以使用。

答案是在每个受保护的工作表中添加以下代码:

Private Sub Worksheet_Deactivate()
    ThisWorkbook.Protect , True
    Application.OnTime Now, "UnprotectBook"
End Sub
并将以下内容添加到模块:

Sub UnprotectBook()
    ThisWorkbook.Unprotect
End Sub

相应地检查学分。

也许您可以在删除前尝试保护工作表中工作簿的结构。 参见我的示例:

Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    ThisWorkbook.Protect Structure:=False
End Sub

Private Sub Workbook_SheetBeforeDelete(ByVal Sh As Object)
    If Sh.Name = "Example" Then
        ThisWorkbook.Protect Structure:=True
    End If
End Sub

为什么不使用隐藏?你知道你可以隐藏床单吗?你也可以锁定它们。我需要用户查看这些工作表,但不能删除它们。它们是数据输入表,充满了工作表激活事件。删除它们将是一件非常痛苦的事情。我不知道从UI中删除一个工作表而不首先激活它的唯一方法是选择多个工作表是否有帮助?这是一个好问题。一旦你开始VBA开发,你迟早会遇到一个问题,那就是拿着几张纸,让用户处理其余的,甚至添加一些新的。不幸的是,答案是否定的,没有干净的解决办法。从这个角度来看,这里的两个解决方案都有不足之处。这是最简单最直接的解决方案。谢谢!!