【问题标题】:vba delete rows based on multiple criteria - code is missing some of the criteriavba 根据多个条件删除行 - 代码缺少一些条件
【发布时间】:2015-11-05 09:48:05
【问题描述】:

我有一个 vba 代码,可以根据多个条件删除行。它工作得很好,我喜欢代码的简短和简单。但是,我注意到它以某种方式错过了一些包含标准的单元格。通常我想删除的列出标准中只有三个左右。任何线索为什么会发生这种情况??

代码如下:

Sub DeleteMyRows()

Dim Rng As Range, Cell As Range
Set Rng = Range(Range("B2"), Range("B" & Rows.Count).End(xlUp))
With Application
    .ScreenUpdating = False
    .EnableEvents = False
For Each Cell In Rng

If Cell = "ADD" Or Cell = "ANFR" Or Cell = "CADV" Or Cell = "DEF" Or Cell = "DEFD" Or Cell = "OIL" Or Cell = "PROP" Or Cell = "STAX" Or Cell = "UREA" Or Cell = "WWFL" Or Cell = "NGAS" Then
    Cell.EntireRow.Delete
End If

Next Cell
End With
End Sub

谢谢!

【问题讨论】:

  • 我的猜测是您的一个单元格包含,例如,“Add”,它不像 ADD 那样全部大写;因此它不被认为与您的搜索词“相同”。请参阅下面的答案,它消除了文本值之间一些常见的“不可见”差异。

标签: vba excel criteria delete-row


【解决方案1】:

[此处取自上一个问题的答案:IF-THEN w/ strings in VBA]

这两个字符串有多“相同”?一个是大写的,另一个不是吗?是否有前导/尾随零?是否有不可打印的字符?

试试这个,在用作比较之前将 Cell 变成 CleanedCell:

CleanedCell = AllCleanedUp(Cell)

If CleanedCell = "ADD" Or CleanedCell = "ANFR" Or CleanedCell = "CADV" Or CleanedCell = "DEF" Or CleanedCell = "DEFD" Or CleanedCell = "OIL" Or CleanedCell = "PROP" Or CleanedCell = "STAX" Or CleanedCell = "UREA" Or CleanedCell = "WWFL" Or CleanedCell = "NGAS" Then
    Cell.EntireRow.Delete
End If

...

指的是以下函数:

Function AllCleanedUp (DirtyString byVal) As String

    AllCleanedUp = Trim(Application.Clean(Ucase(DirtyString)))

End Function

【讨论】:

    【解决方案2】:

    可能是 Cell 中的值大小写不同,或者有前导或尾随空格。 (我在手动输入数据时经常发现这个问题)

    尝试使用:

    If UCase(Trim(Cell.Value)) = "ADD" Or UCase(Trim(Cell.Value)) = "ANFR" Or ....... Then
    

    【讨论】:

    • 请注意,也可能存在不可打印的字符(例如换行符),它们不被视为尾随空格并且不能被“修剪”。相反,您还需要应用额外的“清洁”功能。详情见我的回答。
    【解决方案3】:

    这可能是其他答案之一,但我的猜测是问题在于,当您删除一行时,“单元格”成为下一个,然后您点击“下一个”并完全跳过该行。 例如,如果你这样做:

    Sub test()
    Dim cell
    For Each cell In Range("A1", "A10")
        cell.EntireRow.Delete
    Next cell
    End Sub
    

    您只会删除第 1、3、5、7、9 行

    您应该反向循环,据我所知,对于 range(...) 循环中的每个单元格,这是不可能的,但可以通过像这样迭代数字来完成:

    for i=cells(rows.count,"B").end(xlup).row to 2 step -1
        If Cells(i,"B") = "ADD" Or Cells(i,"B") = "ANFR" Or Cells(i,"B") = "CADV" Or Cells(i,"B") = "DEF" Or Cells(i,"B") = "DEFD" Or Cells(i,"B") = "OIL" Or Cells(i,"B") = "PROP" Or Cells(i,"B") = "STAX" Or Cells(i,"B") = "UREA" Or Cells(i,"B") = "WWFL" Or Cells(i,"B") = "NGAS" Then
            Cell.EntireRow.Delete
        End If
    next i
    

    【讨论】:

    • 我完全同意你的 cmets,但我只补充一点,你实际上可以使用 For 循环向后工作,通过使用 For 语句: For x = MAX_VALUE to MIN_VALUE Step - 1 [Step + 1 is假定;您也可以执行 Step + 2 以仅循环每隔一个等]
    • 哦,那是我的错,我对此的评论不是很清楚,我的意思是(据我所知)如果您使用范围内的每个单元格(... ),但是如果您遍历数字,则可以。我会澄清的,谢谢!
    • 啊,对,你的意思是'For Each'不能倒退。据我所知,这是不可能的,所以我再次同意你的看法。
    【解决方案4】:

    我喜欢做:

    If Cell LIKE "*ADD*" Or Cell LIKE "*ANFR*" Or Cell LIKE "*CADV*" Or Cell LIKE "*DEF*" Or Cell LIKE "*DEFD*" Or Cell LIKE "*OIL*" Or Cell LIKE "*PROP*" Or Cell LIKE "*STAX*" Or Cell LIKE "*UREA*" Or Cell LIKE "*WWFL*" Or Cell LIKE "*NGAS*" Then
        Cell.EntireRow.Delete
    End If
    

    星号 (*) 表示任何字母、数字、空格...可以在您给定值之前或之后(在我的示例中)。

    • 这是不区分大小写的,这就是我喜欢它的原因!

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2014-11-09
      • 1970-01-01
      • 1970-01-01
      • 2017-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多