【问题标题】:Selecting row and deleting doesn't delete row选择行并删除不会删除行
【发布时间】:2014-04-16 00:42:58
【问题描述】:

我编写了一些简单的代码,将一个工作表中的单元格与另一个工作表中的单元格匹配,然后如果单元格相等则删除整行。

代码正确选择行,但由于某种原因拒绝实际删除我的工作表中的行。编辑:一些行删除。其他人则没有,即使它们具有与删除的值完全相同的值。如果有人可以提供帮助,将不胜感激。

Sub delFunds()
Dim fCell As Range 'Fund cell
Dim fRng As Range 'Fund range
Dim wCell As Range 'Working sheet cell
Dim wRng As Range 'Working sheet range
Dim n As Long

Set fRng = Worksheets("Funds").Range("C2:C117")
Set wRng = Worksheets("Working sheet").Range("I3:I7483")

For Each fCell In fRng.Cells 'Loop through all funds
    For Each wCell In wRng.Cells 'Loop through all working cells
        If StrComp(wCell.Value, fCell.Value, vbTextCompare) = 0 Then 'If equal then delete
            n = wCell.Row
            Rows(n & ":" & n).Select
            Selection.Delete Shift:=xlUp
        End If
    Next wCell
Next fCell 'Go to next fund

End Sub

【问题讨论】:

  • 您需要对行本身进行操作,还是只使用wCell 范围? wCell.EntireRow.Delete 会在整个脚本的上下文中工作吗?
  • 我需要删除实际的行。执行 wCell.EntireRow.Delete 并不会实际删除单元格所在的行。

标签: vba excel


【解决方案1】:

我会使用没有嵌套循环的代码:

Sub delFunds()
    Dim rngToDel As Range 
    Dim fRng As Range 'Fund range
    Dim wCell As Range 'Working sheet cell
    Dim wRng As Range 'Working sheet range

    Set fRng = Worksheets("Funds").Range("C2:C117")
    Set wRng = Worksheets("Working sheet").Range("I3:I7483")

    For Each wCell In wRng 'Loop through all working cells
        ' if wCell found in Fund range then delete row
        If Not IsError(Application.Match(Trim(wCell.Value), fRng, 0)) Then
            If rngToDel Is Nothing Then
                Set rngToDel = wCell
            Else
                Set rngToDel = Union(rngToDel, wCell)
            End If
        End If
    Next wCell

    If Not rngToDel Is Nothing Then rngToDel.EntireRow.Delete
End Sub

【讨论】:

  • 出于某种原因,您的解决方案有效。知道为什么吗?
  • 我可以解释为什么 your 解决方案不起作用:) 问题是当您在循环中删除行时,您的循环会出现倾斜。例如。如果您 在循环中 删除第 3 行,则 1) 第 4 行将向上移动并在下一次迭代中变为第 3 行 2) 您的 wCell 将“递增”并引用第 4 行,但是不要到第 3 行(这第 3 行以前是第 4 行,你还没有检查过)
【解决方案2】:

我知道@simoco 的答案有效并且已经被接受,但我喜欢一个很好的问题,所以我想使用autofilter 来整合一个解决方案,以一次杀死大部分工作表。我想你的设计可能是这样的:

从那里,您可以循环浏览简明基金列表并过滤每个基金的工作表:

Option Explicit
Sub EliminateWorkingDuplicates()

Dim WorkingSheet As Worksheet, FundSheet As Worksheet
Dim FundRange As Range, WorkingRange As Range, _
    Fund As Range
Dim LastRow As Long, LastCol As Long, _
    WorkingFundCol As Long

'assign sheets and ranges for easy reference
Set WorkingSheet = ThisWorkbook.Worksheets("Working sheet")
Set FundSheet = ThisWorkbook.Worksheets("Funds")
Set FundRange = FundSheet.Range("C2:C117")
WorkingFundCol = 9 'column I on working sheet

'determine the bounds of the data block on the working sheet
LastRow = WorkingSheet.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
LastCol = WorkingSheet.Cells.Find("*", SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column
Set WorkingRange = Range(WorkingSheet.Cells(2, 1), WorkingSheet.Cells(LastRow, LastCol))

'start working through the funds and calling the autofilter function
For Each Fund In FundRange
    Call FilterAndDeleteData(WorkingRange, WorkingFundCol, Fund.Value)
    Call ClearAllFilters(WorkingSheet)
Next Fund

End Sub

'**********
'blow away rows
Sub FilterAndDeleteData(DataBlock As Range, TargetColumn As Long, Criteria As String)

'make sure some joker didn't pass in an empty range
If DataBlock Is Nothing Then Exit Sub

'execute the autofilter with the supplied column and criteria
With DataBlock
    .AutoFilter Field:=TargetColumn, Criteria1:=Criteria
    .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With

End Sub

'**********
'safely clear filters
Sub ClearAllFilters(TargetSheet As Worksheet)

With TargetSheet
    .AutoFilterMode = False
    If .FilterMode = True Then
        .ShowAllData
    End If
End With

End Sub

【讨论】:

  • +1 用于自动过滤器,但在我看来,在这种特殊情况下,此解决方案可能会 非常 慢。您应该对 7500 行的范围应用过滤器 115 次。如果 OP 的工作表包含很多公式,自动过滤器会更慢,因为它每次应用都会触发工作表重新计算
  • 好点——我没有考虑每个autofilter 应用程序的诱导计算。副手,您知道是否可以通过旧的备用Application.Calculation = xlCalculationManual 来缓解这种情况?
猜你喜欢
  • 2017-12-08
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 2018-01-18
  • 1970-01-01
  • 2018-11-13
  • 2014-02-28
  • 2023-03-23
相关资源
最近更新 更多