如何编写代码来测试特定数据的单元格,如果存在该数据,请不要 运行 宏。如果不存在,那么 运行 宏?

How to write code to test a cell for specific data, and if that data is present, don't run the macro. If not present, then run macro?

我正在尝试测试一个单元格的特定数据。如果它包含该数据,我不希望我的代码 运行(因为那会使我的工作 sheet 和工作簿不受保护)。如果单元格包含与测试细节不匹配的数据,那么我希望代码为 运行。我的代码是取消保护活动工作簿,然后取消保护活动工作sheet,然后将单元格N41的值填充为“sheet名称”,然后保护活动工作sheet,然后保护活动工作簿。我想将测试添加到代码的顶部以避免安全故障。

我要测试单元格的数据是:

如果单元格中有上述 data/characters 中的任何一项,我希望代码不 运行 并为受保护的工作 sheet 和受保护的工作簿保留密码保护.

如果单元格包含少于 31 个字符(包括空格),不包含任何不需要的字符,并且其中至少有 1 个字符(不是空白单元格),那么我希望代码为 运行.任何帮助将不胜感激。

Private Sub CommandButton16_Click()
    ThisWorkbook.Unprotect Password:="Password1"
    ActiveSheet.Unprotect Password:="Password2"
    ActiveSheet.Name = Range("N41").Value
    ActiveSheet.Protect Password:="Password2"
    ThisWorkbook.Protect Password:="Password1"
End Sub

我想真正的问题是 “如何检查某个值是否是工作表的正确名称?” 为了尽量减少文档不受保护的时间,并消除重命名时的错误。

the full list of naming conventions我们可以学到另外两条规则。名称不应为“History”,也不应以撇号 ' 开头或结尾。另外,不应该有同名的其他工作表。

在我看来,完成主要任务的最简单方法是用 On Error 语句包装重命名。

Private Sub CommandButton_Click()
Const BookPass = "Password1"
Const SheetPass = "Password2"
Dim NewName as String
Dim ErrCode&, ErrDesc$, ErrMessage$

    NewName = Range("N41").Value

    With ThisWorkbook
        .Unprotect BookPass
        With ActiveSheet
            .Unprotect SheetPass
            On Error Resume Next
            ' ------ Main Part -------
            .Name = NewName
            ' ------------------------
            ErrCode = Err.Number
            ErrDesc = Err.Description
            On Error GoTo 0
            .Protect SheetPass
        End With
        .Protect BookPass
    End With
    If ErrCode <> 0 Then
        ErrMessage = "NewName=" & NewName & vbNewLine & _
                     "Error=" & ErrCode & vbNewLine & _
                     "Description: " & ErrDesc
        MsgBox ErrMessage, vbCritical
    End If
End Sub

p.s。我想,这段代码将放在工作表对象模块中。在这种情况下,为了便于阅读,最好将 ActiveSheet 替换为 Me

如果您准备弱化Workbook保护,可以在保护Workbook时添加使用此代码。
然后,您的代码可以更改 sheet 名称而无需取消对 WorkBook 的保护,但您的用户也可以。

ActiveWorkbook.Protect Password:="Password1", Structure:=False

可以保护 WorkSheet 以允许更改您的代码,但不允许您的用户更改。
这样您就可以保护 WorkSheet 而永远不必取消保护。

ActiveSheet.Protect Password:="Password2", UserInterfaceOnly:=True

在您的代码中,如果测试通过,您可以将布尔值设置为 true,如果测试失败,则可以使用自定义消息退出子程序。然后测试布尔值,如果为真,取消保护工作簿,进行更新并重新保护工作簿。

Option Explicit

Private Sub ProtectAll()
 
    ActiveWorkbook.Protect Password:="Password1"
'    ActiveWorkbook.Protect Password:="Password1", Structure:=False
'Optional: Allow changes to sheet names and order, not ideal
'but allows you to not have to protect and unprotect the workbook
 
    ActiveSheet.Protect Password:="Password2", UserInterfaceOnly:=True
'Allow changes to the active worksheet by VBA code, remains protected via the UI

End Sub

Private Sub UnprotectAll()

    ActiveSheet.Unprotect Password:="Password2"
    ThisWorkbook.Unprotect Password:="Password1"

End Sub

Private Sub ProtectWB()
 
    ActiveWorkbook.Protect Password:="Password1"

End Sub

Private Sub UnprotectWB()

    ThisWorkbook.Unprotect Password:="Password1"

End Sub

Private Sub Change()
  
Dim CellValue As String
Dim OKtoChange As Boolean
Dim ErrorMessage As String
  
CellValue = vbNullString
OKtoChange = False
  
    CellValue = ActiveSheet.Range("N41").Value
    
    If Len(CellValue) < 32 Then
        OKtoChange = True
    Else
        ErrorMessage = "The WorkSheet name is more than 31 characters."
        GoTo ErrorHandler
    End If
    'Other tests here to set the OKtoChange variable based on results
'If any test fails the code exits
    
    If OKtoChange = True Then
        Call UnprotectWB
            ActiveSheet.Name = CellValue
        Call ProtectWB
    End If

Exit Sub

ErrorHandler:
    MsgBox "Invalid name for the WorkSheet" & vbLf & ErrorMessage, vbCritical, "Invalid name"

End Sub