如何编写代码来测试特定数据的单元格,如果存在该数据,请不要 运行 宏。如果不存在,那么 运行 宏?
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,然后保护活动工作簿。我想将测试添加到代码的顶部以避免安全故障。
我要测试单元格的数据是:
- 单元格不超过 31 个字符(包括字符之间的空格)
- 该单元格不包含以下任何字符:\ / : ? * [ 或 ]
- 单元格不是空白(空)
如果单元格中有上述 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
我正在尝试测试一个单元格的特定数据。如果它包含该数据,我不希望我的代码 运行(因为那会使我的工作 sheet 和工作簿不受保护)。如果单元格包含与测试细节不匹配的数据,那么我希望代码为 运行。我的代码是取消保护活动工作簿,然后取消保护活动工作sheet,然后将单元格N41的值填充为“sheet名称”,然后保护活动工作sheet,然后保护活动工作簿。我想将测试添加到代码的顶部以避免安全故障。
我要测试单元格的数据是:
- 单元格不超过 31 个字符(包括字符之间的空格)
- 该单元格不包含以下任何字符:\ / : ? * [ 或 ]
- 单元格不是空白(空)
如果单元格中有上述 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