[英]How to stop a macro from repeating when run multiple times?
I have a macro that I hashed together with the immense help with other users on here. 我有一个宏,在这里我与其他用户一起获得了巨大的帮助。 I then edited it slightly to fit my needs.
然后,我对其进行了略微编辑以适应我的需求。
Right now, running the macro will have Excel look for any numerical value above 0 in column V of Sheet2. 现在,运行宏将使Excel在Sheet2的V列中查找大于0的任何数值。 If a value above 0 exists, copy cells S:V of that same row.
如果存在大于0的值,则复制同一行的单元格S:V。 Then Excel will look for the last row that has data in it in column T and move to the next row after.
然后,Excel将在T列中查找包含数据的最后一行,然后移至下一行。 Excel will then paste the data from cell S:V into this row.
Excel然后将来自单元格S:V的数据粘贴到此行中。 Afterwards, it will go back to Sheet2 and continue to look in column V for the next value that exists and do it all over again until it reaches the end of the column.
然后,它将返回Sheet2并继续在V列中查找存在的下一个值,然后再次进行遍历,直到到达列末尾为止。
My issue is that when you run the macro twice, it will perform the actions as needed twice, resulting in duplicate values. 我的问题是,当您两次运行宏时,它将按需要执行两次操作,从而导致值重复。 I want Excel to perform the macro once and then if it is run again, have nothing happen.
我希望Excel执行一次宏,然后再次运行该宏,则什么也没有发生。 I'm trying to prevent human error in case someone accidentally runs the macro twice and doesn't notice it.
我正在尝试防止人为错误,以防有人不小心运行了两次宏而没有注意到它。 Is this possible?
这可能吗?
Sub CopyPaste()
Dim c As Range
Dim IRow As Long, lastrow As Long
Dim rSource As Range
Dim wsI As Worksheet, wsO As Worksheet
Dim endrow As Long
On Error GoTo Whoa
'~~> Sheet Where values needs to be checked
Set wsI = ThisWorkbook.Sheets("Sheet2")
'~~> Output sheet
Set wsO = ThisWorkbook.Sheets("Sheet1")
Application.ScreenUpdating = False
'Look for last row with data in column T and move to next
endrow = wsO.Cells(Rows.Count, "T").End(xlUp).Row + 1
With wsI
'~~> Find Last Row which has data in Col S to V
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lastrow = .Columns("S:V").Find(What:="*", _
After:=.Range("S1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lastrow = 1
End If
Set rSource = .Range("V1:V" & lastrow)
If IsNumeric(c.Value) Then
If c.Value > 0 Then
wsO.Cells(endrow + IRow, 20).Resize(1, 4).Value = _
.Range("S" & c.Row & ":V" & c.Row).Value
wsO.Cells(endrow + IRow, 25).Value = "ID#" & .Range("J" & c.Row).Value
IRow = IRow + 1
End If
End If
Next
End With
LetsContinue:
Application.ScreenUpdating = True
Application.CutCopyMode = False
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
Another solution to prevent human error (more like a band-aid solution): 防止人为错误的另一种解决方案(更像创可贴解决方案):
If MsgBox("Are you sure you want to run this macro? Running it a second time can result in duplicate values! Proceed?", vbYesNo + vbQuestion) = vbNo Then Exit Sub
Putting this at the start of your macro can warn the user against running it by accident. 将其放在宏的开头可以警告用户不要意外运行它。
As SJR mentioned why not clear the wsO before running the code again: 正如SJR所述,为什么在再次运行代码之前不清除wsO:
Sub CopyPaste()
Dim c As Range
Dim IRow As Long, lastrow As Long
Dim rSource As Range
Dim wsI As Worksheet, wsO As Worksheet
Dim endrow As Long
On Error GoTo Whoa
'~~> Sheet Where values needs to be checked
Set wsI = ThisWorkbook.Sheets("Sheet2")
'~~> Output sheet
Set wsO = ThisWorkbook.Sheets("Sheet1")
wsO.Rows("2:" & Rows.Count).ClearContents
'the above line will clear the sheet from Row 2 to the last (in case you have headers, if not then change 2 to 1
Application.ScreenUpdating = False
'Look for last row with data in column T and move to next
endrow = wsO.Cells(Rows.Count, "T").End(xlUp).Row + 1
With wsI
'~~> Find Last Row which has data in Col S to V
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lastrow = .Columns("S:V").Find(What:="*", _
After:=.Range("S1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lastrow = 1
End If
Set rSource = .Range("V1:V" & lastrow)
If IsNumeric(c.Value) Then
If c.Value > 0 Then
wsO.Cells(endrow + IRow, 20).Resize(1, 4).Value = _
.Range("S" & c.Row & ":V" & c.Row).Value
wsO.Cells(endrow + IRow, 25).Value = "ID#" & .Range("J" & c.Row).Value
IRow = IRow + 1
End If
End If
End With
LetsContinue:
Application.ScreenUpdating = True
Application.CutCopyMode = False
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.