在VBA中根据单元格的值删除多行
我正在尝试从我们的销售导出文件中删除部分零成本条目,但不是全部。
如果常规项被包含在一个“捆绑包”中,那么组成该捆绑包的项(依赖项)也会在报告中作为捆绑包下的零成本项列出。我需要仅在它们处于捆绑包中时,删除依赖项的每一条记录。我们还有其他需要计入的零成本项,而这些依赖项本身是单独销售的,必须保留。
我们有很多名为“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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。