Vba 保护时宏抛出错误

Vba 保护时宏抛出错误,vba,excel,Vba,Excel,我试图通过调用另一个宏来解锁工作表,让RFID读卡器扫描和输入数据,然后再次保护文档,使其不被编辑,从而让宏运行 Private Sub Worksheet_Change(ByVal Target As Range) ' call another macro Call UnProtect ' End Sub ' Dim i As Integer ' MsgBox (Target.Row & ":" & Target.Column) ' For i = 8 To 200 If

我试图通过调用另一个宏来解锁工作表,让RFID读卡器扫描和输入数据,然后再次保护文档,使其不被编辑,从而让宏运行

Private Sub Worksheet_Change(ByVal Target As Range)
' call another macro
 Call UnProtect
' End Sub
' Dim i As Integer
' MsgBox (Target.Row & ":" & Target.Column)

' For i = 8 To 200
If Target.Column = 3 And Target.Row <= 12 Then
  If Cells(Target.Row, Target.Column).Value <> "" And Cells(Target.Row, "E").Value = "" Then

    ' Cells(Target.Row, "E").Value = Now()
    ' Cells(Target.Row, "E").NumberFormat = "h:mm AM/PM"
  End If
End If
' Next
' Range("E:E").EntireColumn.AutoFit
' End Sub

' Private Sub Worksheet_Change(ByVal Target As Range)
' Dim i As Integer
' MsgBox (Target.Row & ":" & Target.Column)

' For i = 8 To 200
If Target.Column = 1 And Target.Row <= 17 Then
  If Cells(Target.Row, Target.Column).Value <> "" And Cells(Target.Row, "B").Value = "" Then

    Cells(Target.Row, "B").Value = Now()
    ' Cells(Target.Row, "F").NumberFormat = "h:mm AM/PM"
  End If
End If
' Next
' Range("F:F").EntireColumn.AutoFit
' End Sub

' Private Sub Worksheet_Change(ByVal Target As Range)
' Dim i As Integer
' MsgBox (Target.Row & ":" & Target.Column)

' For i = 8 To 200
If Target.Column = 3 And Target.Row >= 15 Then
  If Cells(Target.Row, Target.Column).Value <> "" And Cells(Target.Row, "D").Value = "" Then
        Cells(Target.Row, "D").Value = Now()
        Cells(Target.Row, "D").NumberFormat = "mm/dd/yyy"
  End If
End If
' Next
Range("D:D").EntireColumn.AutoFit
' End Sub
' call another macro
    Call Protect
End Sub

但是,当我只包含unlock宏时,代码将正常工作。但是当我添加protect宏时,会出现一个错误代码

运行时错误“1004”: 无法设置Range类的NumberFormat属性

它指向

Cells(Target.Row, "D").NumberFormat  = "mm/dd/yyyy"

任何关于到底发生了什么的想法

我看不出有任何规定,当Target不止是一个单元格时,很有可能工作表的更改试图在其自身之上运行

循环遍历目标中的每个范围对象并禁用事件触发器

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)

    On Error GoTo safe_exit
    Application.EnableEvents = False
    Call Unprotect
    Dim t As Range

    If Not Intersect(Target, Range("A1:A17")) Is Nothing Then
        For Each t In Intersect(Target, Range("A1:A17"))
            If t.Value <> vbNullString And t.Offset(0, 1).Value <> vbNullString Then
                t.Offset(0, 1) = Now
                t.Offset(0, 1).NumberFormat = "h:mm AM/PM"
            End If
        Next t
    End If

    If Not Intersect(Target, Range("C1:C12")) Is Nothing Then
        For Each t In Intersect(Target, Range("C1:C12"))
            If t.Value <> vbNullString And t.Offset(0, 2).Value <> vbNullString Then
                t.Offset(0, 2) = Now
                t.Offset(0, 2).NumberFormat = "h:mm AM/PM"
            End If
        Next t
        'I don't understand why column F comes into play here
        ' Range("F:F").EntireColumn.AutoFit
    End If

    If Not Intersect(Target, Range("C15:C999999")) Is Nothing Then
        For Each t In Intersect(Target, Range("C15:C999999"))
            If t.Value <> vbNullString And t.Offset(0, 1).Value <> vbNullString Then
                t.Offset(0, 1) = Now
                t.Offset(0, 1).NumberFormat = "mm/dd/yyy"
            End If
        Next t
        Range("D:D").EntireColumn.AutoFit
    End If

    Call Protect
safe_exit:
    Application.EnableEvents = True
End Sub
选项显式
私有子工作表_更改(ByVal目标作为范围)
错误转到安全出口
Application.EnableEvents=False
呼叫取消保护
调光范围
如果不相交(目标,范围(“A1:A17”))则为零
对于相交的每个t(目标,范围(“A1:A17”))
如果t.值vbNullString和t.偏移量(0,1).Value vbNullString,则
t、 偏移量(0,1)=现在
t、 偏移量(0,1).NumberFormat=“h:mm AM/PM”
如果结束
下一个t
如果结束
如果不相交(目标,范围(“C1:C12”))则为零
对于相交的每个t(目标,范围(“C1:C12”))
如果t.值vbNullString和t.偏移量(0,2).Value vbNullString,则
t、 偏移量(0,2)=现在
t、 偏移量(0,2).NumberFormat=“h:mm AM/PM”
如果结束
下一个t
我不明白为什么F栏在这里起作用
'范围(“F:F”)。全自动装配
如果结束
如果不相交(目标,范围(“C15:C999999”))则为零
对于相交中的每个t(目标,范围(“C15:C99999”))
如果t.值vbNullString和t.偏移量(0,1).Value vbNullString,则
t、 偏移量(0,1)=现在
t、 偏移量(0,1)。NumberFormat=“mm/dd/yyy”
如果结束
下一个t
范围(“D:D”)。全自动装配
如果结束
呼叫保护
安全出口:
Application.EnableEvents=True
端接头

您考虑过了吗?我看不出有任何条款规定目标单元格多于一个单元格,而且工作表更改很有可能会自动运行。@jeeped这很有效,谢谢。它是否必须在每次打开文档时运行?这样,即使某个范围受到保护,我也可以允许对其进行编辑。a)否,您只能使用UserInterfaceOnly:=true参数对其进行一次保护,但如果您出于某种原因取消了对其的保护,则需要使用UserInterfaceOnly:=true参数再次对其进行保护。b) 这就是cells Locked属性的用途。
Cells(Target.Row, "D").NumberFormat  = "mm/dd/yyyy"
Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)

    On Error GoTo safe_exit
    Application.EnableEvents = False
    Call Unprotect
    Dim t As Range

    If Not Intersect(Target, Range("A1:A17")) Is Nothing Then
        For Each t In Intersect(Target, Range("A1:A17"))
            If t.Value <> vbNullString And t.Offset(0, 1).Value <> vbNullString Then
                t.Offset(0, 1) = Now
                t.Offset(0, 1).NumberFormat = "h:mm AM/PM"
            End If
        Next t
    End If

    If Not Intersect(Target, Range("C1:C12")) Is Nothing Then
        For Each t In Intersect(Target, Range("C1:C12"))
            If t.Value <> vbNullString And t.Offset(0, 2).Value <> vbNullString Then
                t.Offset(0, 2) = Now
                t.Offset(0, 2).NumberFormat = "h:mm AM/PM"
            End If
        Next t
        'I don't understand why column F comes into play here
        ' Range("F:F").EntireColumn.AutoFit
    End If

    If Not Intersect(Target, Range("C15:C999999")) Is Nothing Then
        For Each t In Intersect(Target, Range("C15:C999999"))
            If t.Value <> vbNullString And t.Offset(0, 1).Value <> vbNullString Then
                t.Offset(0, 1) = Now
                t.Offset(0, 1).NumberFormat = "mm/dd/yyy"
            End If
        Next t
        Range("D:D").EntireColumn.AutoFit
    End If

    Call Protect
safe_exit:
    Application.EnableEvents = True
End Sub