Excel 宏将单个单元格视为范围

Excel 宏将单个单元格视为范围,excel,vba,Excel,Vba,在我的代码中,如果我每次将BX单元格值从unlocked更改为任何其他值,就会出现运行时错误1004,“无法设置Range类的Locked属性”。如果我将任何其他值更改为unlocked,代码运行良好。但是,即使C列单元格以前没有合并,也会发生错误。此外,即使是先前合并的C单元格,它们也应该通过调用函数中的第二个条件的Target.Offset(0,1).Value=“0”此行取消合并。为什么我会犯这个错误 Option Explicit Private Sub Workbook_SheetC

在我的代码中,如果我每次将BX单元格值从unlocked更改为任何其他值,就会出现运行时错误1004,“无法设置Range类的Locked属性”。如果我将任何其他值更改为unlocked,代码运行良好。但是,即使C列单元格以前没有合并,也会发生错误。此外,即使是先前合并的C单元格,它们也应该通过调用函数中的第二个条件的
Target.Offset(0,1).Value=“0”
此行取消合并。为什么我会犯这个错误

Option Explicit

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)

    Dim pass As String
    pass = "" 'set the password. Otherwise, protection/unprotection is done without a pass
    
    If Not Intersect(Target, Range("B14:B50")) Is Nothing And Sh.Name <> "Dane" Then
        If Target.Cells.Count > 1 Then Exit Sub
        ActiveSheet.Unprotect pass
        If Target.Value = "Unlocked" Then
            Target.Offset(0, 1).Locked = False
        Else
            Target.Offset(0, 1).Value = "0"
            Target.Offset(0, 1).Locked = True
        End If
        ActiveSheet.Protect pass
    End If
    
    If Not Intersect(Target, Range("C14:C50")) Is Nothing And Sh.Name <> "Dane" Then
        Dim i As Long
        Dim rng As Range
        Application.DisplayAlerts = False
        Application.EnableEvents = False
        ActiveSheet.Unprotect pass
        For i = 1 To 8 Step 1
            If i <> 6 And i <> 7 And Cells(Target.Row, i).MergeCells Then
                Cells(Target.Row, i).UnMerge
            End If
        Next i
        If Target.Value <> 0 Then
            Dim cf As Boolean
            If Target.Value > 1 Then
                For i = 1 To 8 Step 1
                    If i <> 6 And i <> 7 Then
                        Range(Cells(Target.Row, i), Cells(Target.Row + Target.Value - 1, i)).Merge
                    End If
                Next i
            End If
            For i = 14 To 50 Step 1
                If Not cf Then
                    Set rng = Range("A" & i).MergeArea.Resize(, 8)
                    With rng
                        .Borders.LineStyle = xlNone
                        .Interior.Color = RGB(217, 225, 242)
                        .BorderAround xlContinuous, xlThin, Color:=RGB(142, 169, 219)

                    End With
                Else
                    Range("A" & i).MergeArea.Resize(, 8).Interior.Color = xlNone
                End If
                
                i = (i + Range("A" & i).MergeArea.Cells.CountLarge) - 1
                cf = Not cf
            Next i
            
        End If
        ActiveSheet.Protect pass
        Application.EnableEvents = True
        Application.DisplayAlerts = True
    End If
    
End Sub 
选项显式
私有子工作簿(ByVal Sh作为对象,ByVal目标作为范围)
以字符串形式传递
pass=“”设置密码。否则,保护/取消保护将在没有通行证的情况下完成
如果不相交(目标,范围(“B14:B50”))为空,则将其命名为“Dane”
如果Target.Cells.Count>1,则退出Sub
ActiveSheet.Unprotect pass
如果Target.Value=“解锁”,则
Target.Offset(0,1).Locked=False
其他的
Target.Offset(0,1).Value=“0”
Target.Offset(0,1).Locked=True
如果结束
活动表。保护通行证
如果结束
如果不相交(目标,范围(“C14:C50”))为空,则将其命名为“Dane”
我想我会坚持多久
变暗rng As范围
Application.DisplayAlerts=False
Application.EnableEvents=False
ActiveSheet.Unprotect pass
对于i=1到8,步骤1
如果I6和I7与单元格(Target.Row,i).MergeCells合并,则
单元格(Target.Row,i).未合并
如果结束
接下来我
如果目标值为0,则
将cf设置为布尔值
如果Target.Value>1,则
对于i=1到8,步骤1
如果我6岁,我7岁
范围(单元格(Target.Row,i),单元格(Target.Row+Target.Value-1,i))。合并
如果结束
接下来我
如果结束
对于i=14到50,步骤1
如果不是,那么
设置rng=Range(“A”&i).MergeArea.Resize(,8)
带rng
.Borders.LineStyle=xlNone
.Interior.Color=RGB(217225242)
.边框xl连续,xlThin,颜色:=RGB(142169219)
以
其他的
范围(“A”&i).MergeArea.Resize(,8).Interior.Color=xlNone
如果结束
i=(i+范围(“A”&i).MergeArea.Cells.CountLarge)-1
cf=不是cf
接下来我
如果结束
活动表。保护通行证
Application.EnableEvents=True
Application.DisplayAlerts=True
如果结束
端接头

我认为,您的代码问题如下:

“C14:C50”范围的任何更改(即使由第一个事件部分完成,范围“B14:B50”的更改)都将触发第二个事件部分,该事件部分将根据需要合并/取消合并范围。我没有花太多时间去理解是否所有的逻辑都是正确的

问题是,第二个触发事件以
ActiveSheet.Protect pass
结束

第一个中断事件不是从头开始的。它从已停止的线路继续。这意味着,在您尝试锁定C:C列中的单元格时,工作表不会被解除保护

为了解决此问题,请插入下一行:

If ActiveSheet.ProtectContents Then ActiveSheet.Unprotect pass
就在之前:

Target.Offset(0, 1).Locked = True

在上述情况下,插入的行也将取消对工作表的保护。

activesheet
不一定是正在更改的工作表。您的代码应该改用
sh
。@Rory,谢谢您的关注。然而,这并不能解决问题。
单元格
实际上是一个
范围
。我无法理解上面的错误出现在哪一行。更改B列会触发C列的更改,并且该更改的代码会在您尝试锁定单元格之前重新保护工作表。假设您的意思是要运行C列代码,则在该部分的开头,检查工作表是否受保护,并且仅在其受保护时重新保护。