Excel VBA 如何检测工作表中是否粘贴了某些内容

Excel VBA How to detect if something was pasted in a Worksheet

首先我要说的是,我在 Excel 和 VBA 方面的经验仅限于我在学校看到的内容。我有编程经验,但使用其他语言。

我每周都会收到一个文件。该文件的结构始终相同: ID、姓名、日期、1 到 4 之间的值、无关数据。

此数据是通过 'select all' 按钮(工作表左上角,MS excel 2013 中单元格名称下方的小三角形)选择的,然后复制到另一个重新处理数据的默认文件中根据 1-4 值和日期在不同的工作表中显示和过滤它。

我的问题: 如何检测数据 has/is 何时被粘贴?我试过 Worksheet.Change 事件,但粘贴命令 (CTRL+V) 不会触发 Change 事件。 另外,数据将如何复制?它会逐行更新,逐个单元格(哪个方向),......? 我知道一旦我可以检测到复制命令,我可以通过调试轻松找到最后一个问题的答案,但你永远不知道是否有人知道答案。

还有其他更简单(或更好)的方法吗?

如果需要,可以提供更多数据和信息。

感谢您的帮助。

编辑:“...has/is 正在被复制?”更改为应该粘贴的内容。

Worksheet_Change 如果您将公式添加到永远不会被覆盖的单元格中,事件将完成这项工作。假设您的数据粘贴到 A1 单元格中并占用 5 列。因此,将以下公式输入 6. 列和行 1.

=COUNTBLANK(A1:A1048576)

现在,您可以handle/detect粘贴活动 ;)

Private Sub Worksheet_Change(ByVal Target As Range)
  Dim UndoList As String

  '~~> Get the undo List to capture the last action performed by user
  UndoList = Application.CommandBars("Standard").Controls("&Undo").List(1)

  '~~> Check if the last action was not a paste nor an autofill
  If Left(UndoList, 5) = "Paste" Then
    'Do stuff
  End If
End Sub

这成功了。对于那些需要类似东西并且知道列表大小的人,@MaciejLos 的回答也可以。

我无法将其添加为评论,因此我将其作为答案发布。 当 excel 将“英语”设置为首选语言时,@Nahbyr 的回答有效, 不然不行。

因此,在使用直接 window 手动搜索后,我能够找到适用于每种语言的适当索引。

这是我写的函数,用来测试最后一个动作是粘贴动作,粘贴还是特殊粘贴。

Public Function LastActionPaste() As Boolean

' The function LastActionPaste checks if the last action made was a paste action, if so it returns TRUE
' Otherwise it returns FALSE

Dim UndoList As String

LastActionPaste = False
UndoList = Application.CommandBars(11).Controls(14).List(1)

'~~> Check if the last action was a paste or paste special
If UndoList = "Paste" Or UndoList = "Paste Special" Then
    
    LastActionPaste = True
    
End If

End Function

更新

很明显,Excel 的不同安装上的索引并不相同,无论是因为它们是不同的版本还是其他原因...

所以即使首选语言不是英语,CommandBars.Name 仍然是英语,但是 Controls.Caption 确实改变了...

现在我希望控件索引不要更改,否则这将不起作用。

所以我修改了这样的函数让它工作:

Public Function LastActionPaste() As Boolean

' The function LastActionPaste checks if the last action made was a paste action, if so it returns TRUE
' Otherwise it returns FALSE

Dim UndoList As String
Dim barFound As Boolean
Dim index As Long

LastActionPaste = False
index = 1
barFound = False

Do While barFound = False
    
    If Application.CommandBars(index).name = "Standard" Then
        
        barFound = True
        
        Else
        
        index = index + 1
        
    End If
    
Loop

UndoList = Application.CommandBars(index).Controls(14).List(1)

'~~> Check if the last action was a paste or paste special
If UndoList = "Paste" Or UndoList = "Paste Special" Then
    
    LastActionPaste = True
    
End If

End Function