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
首先我要说的是,我在 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