Prevent user from deleting a particular sheet

前端 未结 6 1261
春和景丽
春和景丽 2020-12-10 06:54

Protecting workbook structure will prevent a user from deleting sheets. But how could I (using VBA) prevent a user from deleting a particular sheet I designate? I\'

相关标签:
6条回答
  • 2020-12-10 07:09

    I can prevent a sheet from being deleted via the Worksheet_BeforeDelete Event as follows:

    Private Sub Worksheet_BeforeDelete()
    
        Call ThisWorkbook.Protect("password")
    
        Call MsgBox("This sheet cannot be deleted.", vbExclamation)
    
    End Sub
    

    This protects all sheets from being deleted, however if you add some event code on the ThisWorkbook module like the following :

    Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    
        Call ThisWorkbook.Unprotect("password")
    
    End Sub
    

    I will then be able to delete any other sheet as soon as it is selected.

    Bear in mind, you will lose copy and paste functionality between pages due to the page unlocking when it is selected.

    0 讨论(0)
  • 2020-12-10 07:10

    I found this solution, similar to Dan's, on ExtendOffice.com. Put this code on the Worksheet's module:

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

    When you activate the sheet in question, the whole workbook is protected, and the "Delete" option is grayed out. When you switch to any other sheet, the workbook is free again. It's subtle because you only notice the change when you go to the "safe" sheet.

    0 讨论(0)
  • 2020-12-10 07:11

    "there isn't an event that can be used to detect when a sheet is about to be deleted"

    Since Office 2013, it is possible with the SheetBeforeDelete event.

    0 讨论(0)
  • 2020-12-10 07:20

    You cannot stop users to delete a particular sheet but you could use the Workbook_BeforeSave() event to prevent the workbook from being saved if a particular sheet is missing. The documentation on this event precisely shows how to allow saving a workbook only when certain conditions are met. See http://msdn.microsoft.com/en-us/library/office/ff840057(v=office.14).aspx

    0 讨论(0)
  • 2020-12-10 07:22

    Answer is by adding the following code to each of the protected sheets:

    Private Sub Worksheet_Deactivate()
        ThisWorkbook.Protect , True
        Application.OnTime Now, "UnprotectBook"
    End Sub
    

    And the following to a Module:

    Sub UnprotectBook()
        ThisWorkbook.Unprotect
    End Sub
    

    Check https://www.top-password.com/blog/prevent-excel-sheet-from-being-deleted/ for credits accordingly.

    0 讨论(0)
  • 2020-12-10 07:23

    As far as I can tell, it isn't possible to natively tag a single sheet as non-deletable; and there isn't an event that can be used to detect when a sheet is about to be deleted so the workbook can be protected preventively.

    However, here is one potential workaround:

    1. Protect workbook structure: this will, as you indicate, prevent all sheets from being deleted.
    2. Create a "Controls" sheet. On this sheet, maintain a list of all sheet names (except those you don't want to be deletable).
    3. If users want to delete a sheet, they will have to select its name on the Controls sheet (e.g. in a data validation drop-down menu) and press a "Delete" button. This button will call a macro that temporarily unprotects the workbook, deletes the selected sheet, and then reprotects the workbook.

    Of course, the users will have to get used to this way of deleting sheets (as opposed to just right-click > Delete on the sheet's tab). Still, this isn't crazy complicated.

    As for how to achieve #2 i.e. maintaining that list of sheet names, I suppose you could make use of a UDF like this one (must be called as an array formula):

    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
    
    0 讨论(0)
提交回复
热议问题