在VBA中根据单元格的值删除多行

编程语言 2026-07-10

我正在尝试从我们的销售导出文件中删除部分零成本条目,但不是全部。

如果常规项被包含在一个“捆绑包”中,那么组成该捆绑包的项(依赖项)也会在报告中作为捆绑包下的零成本项列出。我需要仅在它们处于捆绑包中时,删除依赖项的每一条记录。我们还有其他需要计入的零成本项,而这些依赖项本身是单独销售的,必须保留。

我们有很多名为“Bundles”的捆绑包,因此我用一个演示示例来说明需求。共有两个捆绑包——Spaghetti有两个依赖项,Omelette有三个:

物品 成本
Orange 4
Spaghetti 12
Pasta 0
Sauce 0
Omelette 5
Eggs 0
Cheese 0
Ham 0
Pasta 2
Ham 0

我需要删除Spaghetti下方的2 行和Omelette下方的3 行,但不要删除最后两行。

这是我第一次尝试的代码,虽然没有成功,而且考虑到有多少条目和捆绑包,我知道它会非常慢:

Sub BundleSolution()

Range("A1").Select
Do While ActiveCell <> ""

' Check for first named bundle, delete the no cost dependents.
    If ActiveCell = "Spaghetti" Then
                Offset(1, 0, 2, 1).Select
                Selection.EntireRow.Delete
'  If the first named bundle is not found, check the second named bundle.
    ElseIf ActiveCell = "Omelette" Then
                Offset(A2, 1, 0, 3, 1).Select
                Selection.EntireRow.Delete

    End If

 ActiveCell.Offset(1, 0).Select
Loop

End Sub

但当我运行代码时,Offset被高亮显示,并出现编译错误:Sub或 Function未定义。

我本希望在遇到“Spaghetti”后,它会高亮接下来的两行并在移动到下一行之前将它们删除,下一行就会是“Omelette”。

解决方案

如果你的报表不是很大,这个方法应该可以正常工作。

它把删除行的操作延迟到最后,因为批量删除行速度更快,而在对一个范围进行循环时逐行删除会比较难以管理。

编辑:更新为在任何“bundle dependents”行中检查非零成本

Sub BundleSolution()

    Dim ws As Worksheet, c As Range, numDependents As Long, rngDel As Range
    Dim rngCost As Range, numZeros As Long

    Set ws = ActiveSheet 'or some specific sheet...
    For Each c In ws.Range("A2", ws.Cells(Rows.Count, "A").End(xlUp)).Cells
        'is this a bundle?
        Select Case c.Value
            Case "Spaghetti","Cereal": numDependents = 2 'can list multiple bundles here
            Case "Omelette": numDependents = 3
            Case Else: numDependents = 0 'not a bundle
        End Select

        If numDependents > 0 Then 'deleting any rows?
            Set rngCost = c.Offset(1, 1).Resize(numDependents) 'item cost(s)
            numZeros = Application.CountIf(rngCost, 0)         'count zeros
            If numZeros = numDependents Then 'all dependents have zero cost?
                AddToRange rngDel, rngCost
            Else
                MsgBox "Item '" & c.Value & "' (Row# " & c.Row & ") is a bundle with " & numDependents & _
                       " dependents, but one or more dependents have non-zero cost!", vbExclamation, _
                       "Report Data Issue"
                Exit Sub 'better to fix the report issue before deleting any rows...
            End If
        End If
    Next c
    'any rows to remove?
    If Not rngDel Is Nothing Then rngDel.EntireRow.Delete

End Sub

Sub AddToRange(AddTo As Range, AddThis As Range)
    If AddTo Is Nothing Then
        Set AddTo = AddThis
    Else
        Set AddTo = Application.Union(AddTo, AddThis)
    End If
End Sub

这可以通过创建一个表来改进,该表列出所有捆绑包及其各自相关联的行数,而不是在VBA中硬编码。

另外,如果你想进一步学习Excel VBA,一个普遍的原则是,在处理对象之前通常不需要先进行选择/激活。关于这一点的概览,请参考:How can I avoid using Select in Excel VBA?

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章