Excel VBA:如果要复制/粘贴到新工作表中的语句,则删除已复制内容的行

时间:2018-09-02 01:13:15

标签: excel vba excel-vba

今天就开始学习VBA,以使我的新工作变得更加轻松。我实质上是在尝试查找列E具有字母“ a”副本的每个实例,并将其粘贴到新创建的名为“ Aton”的工作表中,然后删除带有“ a”的原始行。

我尝试修改此处找到的解决方案:VBA: Copy and paste entire row based on if then statement / loop and push to 3 new sheets

当我更改上述解决方案以使此行为“ If wsSrc.Cells(i,“ E”)。Value =“ a”然后“时,这就是我遇到的问题。

    Sub Macro3()
        'Need "Dim"
        'Recommend "Long" rather than "Integer" for referring to rows and columns
        'i As Integer
        Dim i As Long
        'Declare "Number"
        Dim Number As Long
        'Declare a variable to refer to the sheet you are going to copy from
        Dim wsSrc As Worksheet
        Set wsSrc = ActiveSheet
        'Declare a variable to refer to the sheet you are going to copy to
        Dim wsDest As Worksheet
        'Declare three other worksheet variables for the three potential destinations
        Dim wsEqualA As Worksheet
        'Create the three sheets - do this once rather than in the loop
        Set wsEqualA = Worksheets.Add(After:=Worksheets(Worksheets.Count))
        'Assign the worksheet names
        wsEqualA.Name = "Aton"

        'Determine last row in source sheet
        Number = wsSrc.Cells(wsSrc.Rows.Count, "C").End(xlUp).Row

        For i = 1 To Number


        'Determine which destination sheet to use
        If wsSrc.Cells(i, "E").Value = "a" Then
            Set wsDest = wsEqualA
        Else

        End If

        'Copy the current row from the source sheet to the next available row on the
        'destination sheet
        With wsDest

            wsSrc.Rows(i).Copy .Cells(.Rows.Count, "A").End(xlUp).Offset(1, 0)
        End With

        'Delete row if column E has an a
        If wsSrc.Cells(i, "E").Value = "a" Then
            Selection.EntireRow.Delete
        Else

        End If

    Next i
End Sub

3 个答案:

答案 0 :(得分:0)

您需要确定原始值所在的工作表。将Sheet行上的Set ws = ThisWorkbook.Sheets("Sheet1")更改为您的工作表名称。


  1. 创建新工作表并设置对象
  2. 创建要遍历的范围,LoopRange(E2向下到列的最后一行)
  3. 遍历LoopRange。如果满足条件,则将单元格MyCell添加到单元格集合(TargetRange
  4. 如果TargetRange不为空(表示您的条件至少满足一次),则将标头从ws复制到ns
  5. TargetRangews复制到ns
  6. TargetRange删除ws

如果使用Union来收集单元格的好处是可以避免copy/paste/delete的许多迭代。如果您的范围内有50个符合条件的单元格,则copy/paste/delete上将有50个实例,总共 150个操作

使用Union方法,每个动作只有1个实例,总共 3个动作,这将增加运行时间。


Option Explicit

Sub Learning()

Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
Dim ns As Worksheet: Set ns = Worksheets.Add(After:=(ThisWorkbook.Sheets.Count)) 'ns = new sheet
ns.Name = "Aton"

Dim LoopRange As Range, MyCell As Range, TargetRange As Range

Set LoopRange = ws.Range("E2:E" & ws.Range("E" & ws.Rows.Count).End(xlUp).Row)

For Each MyCell In LoopRange 'Loop through column E
    If MyCell = "a" Then
        If TargetRange Is Nothing Then 'If no range has been set yet
            Set TargetRange = MyCell
        Else 'If a range has already been set
            Set TargetRange = Union(TargetRange, MyCell)
        End If
    End If
Next MyCell

Application.ScreenUpdating = False
    If Not TargetRange Is Nothing Then 'Make sure you don't try to copy a empty range
        ws.Range("A1").EntireRow.Copy ns.Range("A1") 'copy header from original sheet
        TargetRange.EntireRow.Copy ns.Range("A2")
        TargetRange.EntireRow.Delete
    Else
        MsgBox "No cells were found in Column E with value of 'a'"
    End If
Application.ScreenUpdating = True

End Sub

答案 1 :(得分:0)

首先,不要使用ActiveSheet,它可能会导致多种问题。如果sheet1不是您的源工作表,请对其进行更改以满足您的需求。我更喜欢使用过滤器,如urdearboy建议的那样,它不需要循环并且速度更快。我总是尝试使代码保持简单,因此请尝试...

Sheets.Add(After:=Sheets(Sheets.Count)).Name = "Aton"

    With Sheet1.UsedRange
        .AutoFilter Field:=5, Criteria1:="a", Operator:=xlFilterValues
        .Offset(1).SpecialCells(xlCellTypeVisible).Copy Sheets("Aton").Range("A1")
        .Offset(1).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible).EntireRow.Delete
        .AutoFilter
    End With

答案 2 :(得分:0)

注意您的代码,您遇到了三个问题

  • 在删除行时,您必须向后循环并避免跳过行

  • 您要复制(并尝试)删除'If wsSrc.Cells(i,“ E”)。Value =“ a”'块之外的行,因此无论当前行“ i”列E值

  • 您不想删除当前选中的范围行,但是当前循环“ i”行

将所有内容放在一起这里是正确的相关代码段;

Set wsDest = wsEqualA 'set target sheet once and for all outside the loop
For i = Number To 1 Step -1 'Loop backwards 
    If wsSrc.Cells(i, "E").Value = "a" Then
        'Copy the current row from the source sheet to the next available row on the destination sheet
        With wsDest
            wsSrc.Rows(i).Copy .Cells(.Rows.Count, "A").End(xlUp).Offset(1, 0)   'Copy wsSrc current “i” row and paste it to wsDest
            wsSrc.Rows(i).Delete   'Delete wsSrc current “i” row
        End With
    End If
Next

作为一种可能的增强,您可以在“ With ... End With”块中交换图纸引用,因为引用大多数“用过的”图纸更为有效:

        With wsSrc
            .Rows(i).Copy wsDest.Cells(.Rows.Count, "A").End(xlUp).Offset(1, 0)   'Copy wsSrc current “i” row and paste it to wsDest
            .Rows(i).Delete   'Delete wsSrc current “i” row
        End With