Excel VBA - 仅在更改单元格时插入用户名

时间:2016-07-12 16:29:13

标签: vba excel-vba excel

这是我的问题:当用户在一行中的任何地方进行更改时,我有工作代码来插入用户名和时间戳。大!所以我的代码工作,我回答了我自己的问题,对吗?不!这是一个很小的问题,虽然它没有破坏代码,但确实会导致用户输入用户名,因为当未做出更改时,用户输入已经做了更改。

这是我的代码:

Private Sub Worksheet_Change(ByVal Target As Excel.Range)
    ThisRow = Target.Row
    'protect Header row from any changes
    If (ThisRow = 1) Then
           Application.EnableEvents = False
           Application.Undo
           Application.EnableEvents = True
           MsgBox "Header Row is Protected."
           Exit Sub
    End If
    For i = 1 To 61
        If Target.Column = i Then
               ' time stamp corresponding to cell's last update
               Range("BK" & ThisRow).Value = Now
               ' Windows level UserName | Application level UserName
               Range("BJ" & ThisRow).Value = Environ("username")
           Range("BJ:BK").EntireColumn.AutoFit
        End If
    Next i
End Sub

以下是它的发生方式:用户决定要对单元格进行更改,因此双击该单元格。现在,如果他们按下逃生钥匙,没有任何事情发生,一切都是笨拙的。但是,如果他们双击单元格,然后单击单元格外部到另一个单元格离开该单元格,系统会将其记录为更改,即使没有进行任何更改也不会对用户进行更改用户名被放入第62栏。这不是bueno,因为有人可能会对另一个人犯了错误负责,如果他们被错误地放下作为最后一个人来改变该行中的某些内容。

相反 - 在用户更改的单元格中创建注释可能是值得的,但我认为双击一个单元格会有同样的问题,所以我仍然有解释它。

思想?

编辑:完全披露,我在其他地方找到了这个代码,并根据我的目的进行了调整。

1 个答案:

答案 0 :(得分:2)

您可以测试以查看旧值和新值是否相同。我松散地使用“new”,这意味着对单元格进行了编辑的优点,因此就Worksheet_Change事件理解而言,它是一个“新”值。

我也摆脱了你的For循环,因为它似乎非常不必要。如果我弄错了,我道歉。

Private Sub Worksheet_Change(ByVal Target As Excel.Range)

    Dim ThisRow As Long ' make sure to declare all the variables and appropiate types
    ThisRow = Target.Row

    'protect Header row from any changes
    If (ThisRow = 1) Then

           Application.EnableEvents = False
           Application.Undo
           Application.EnableEvents = True
           MsgBox "Header Row is Protected."
           Exit Sub

    End If

    If Target.Column >= 1 And Target.Column <= 61 Then

        Dim sOld As String, sNew As String
        sNew = Target.Value 'capture new value

        With Application
            .EnableEvents = False
            .Undo
        End With

        sOld = Target.Value 'capture old value
        Target.Value = sNew 'reset new value

        If sOld <> sNew Then

            ' time stamp corresponding to cell's last update
            Range("BK" & ThisRow).Value = Now
            ' Windows level UserName | Application level UserName
            Range("BJ" & ThisRow).Value = Environ("username")
            Range("BJ:BK").EntireColumn.AutoFit

        End If

        Application.EnableEvents = True

    End If

End Sub