【问题标题】:Excel VBA - Insert Username ONLY when cell is changedExcel VBA - 仅在更改单元格时插入用户名
【发布时间】:2016-07-13 00:42:53
【问题描述】:

这是我的问题:当用户在一行中的任何位置进行更改时,我有工作代码可以插入用户名和时间戳。伟大的!所以我的代码有效,我回答了我自己的问题,对吧?没有!有一个小问题,虽然它不会破坏代码,但确实会导致用户输入的用户名在未进行更改时进行了更改。

这是我的代码:

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

它是这样发生的:用户决定要对单元格进行更改,因此他们双击该单元格。现在,如果他们按下 Escape 键,什么都不会发生,一切都是笨拙的。但是,如果他们双击该单元格,然后在该单元格外部单击另一个单元格以离开该单元格,即使没有进行任何更改并且用户的用户名已输入,系统也会将其记录为更改第 62 列。这不是 bueno,因为如果某人被错误地列为最后一个更改该行中某些内容的人,则某人可能要对另一个人所犯的错误负责。

相反 - 在用户更改的单元格中创建评论可能是值得的,但我认为双击单元格时我会遇到同样的问题,所以我仍然需要考虑它.

想法?

编辑:完全公开,我在别处找到了这段代码,并根据我的目的对其进行了修改。

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    您可以测试一下旧值和新值是否相同。我松散地使用“新”,意思是单元格被编辑的excel,所以它是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
    

    【讨论】:

    • 太棒了。谢谢。我想我明白你在这里做什么。您将新值复制到 sNew 中,然后撤消更改操作并将旧值复制到 sOld 中并进行比较。由于“Application.EnableEvents = False”行,“撤消”不会发生。我说的对吗?
    • @jtrousd - 实际的撤消确实发生,但它使用此Target.Value = sNew 将值设置回撤消之前。 EnableEvents = False 会在每次对工作表进行更改时停止宏触发。
    • 啊哈。我现在明白了!谢谢,斯科特。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多