运行时 1004 解决方法 - Worksheet_Change 中的 Protect/Unprotect

Runtime 1004 Workaround - Protect/Unprotect in Worksheet_Change

我读过一些其他文章,它们部分解决了我的问题,但作为一个完整的 VB 业余爱好者,我无法让它发挥作用。有问题的工作表受到保护,因此尝试在代码中添加 protect/unprotect 命令。它会在开始时很好地解除保护,但随后会遇到问题。任何帮助将不胜感激。

Private Sub Worksheet_Change(ByVal Target As Range)

    Sheet1.Unprotect Password:="mypassword"

    If Target.Cells.Count > 1 Then Exit Sub

        If Not Intersect(Target, Range("B11")) Is Nothing Then
        Select Case Target.Value
            Case Is = ""
                Target.Value = "Product Name (IE Product123)"
                Target.Font.ColorIndex = 15
            Case Else
                Target.Font.ColorIndex = 1

        End Select
    End If

    If Not Intersect(Target, Range("B12")) Is Nothing Then
        Select Case Target.Value
            Case Is = ""
                Target.Value = "Version "
                Target.Font.ColorIndex = 15
            Case Else
                Target.Font.ColorIndex = 1

        End Select
    End If

    Sheet1.Protect Password:="mypassword"

End Sub

您没有关闭 Application.EnableEvents property but there is a chance that you will write something to the worksheet. This would retrigger the event handler and the Worksheet_Change 事件宏会尝试 运行 在其自身之上。

没有什么能阻止某人同时清除 B11 和 B12 的内容。如果目标中有两个单元格,则不要放弃处理,而是适应可能性并处理两个单元格。

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)

    If Not Intersect(Target, Range("B11:B12")) Is Nothing Then
        On Error GoTo bm_Safe_Exit
        'turn off event handling 'cause we might write something
        Application.EnableEvents = False
        'why this unprotect necessary??
        'Me.Unprotect Password:="mypassword"
        Dim rng As Range
        For Each rng In Intersect(Target, Range("B11:B12"))
            Select Case rng.Value2
                Case vbNullString
                    If rng.Address(0, 0) = "B11" Then
                        rng = "Product Name (IE Product123)"
                    Else
                        rng = "Version "  '<~~ why the trailing space??
                    End If
                    rng.Font.ColorIndex = 15
                Case Else
                    rng.Font.ColorIndex = 1
            End Select
        Next rng
    End If

bm_Safe_Exit:
    'if unprotect is not necessary, neither is protect
    'Me.Protect Password:="mypassword"
    Application.EnableEvents = True

End Sub

您可能还想查看 Worksheet.Protect methodUserInterfaceOnly 参数。将此设置为 true 允许您在 VBA 中做任何您想做的事情,而无需取消保护工作表。

附录:

如果用户可以更改 B11:B12 的内容,则不得锁定这些单元格。如果它们未被锁定,则无需在(可能)更改其内容之前取消对工作表的保护。