基于单元格内容的Excel VBA删除行
我几乎没有vba的经验,我正在尝试编写一个Excelmacros,它将检查列Q中单元格的内容,并删除该列中具有0的行(列Q中的单元格为空,包含文本,或包含0以外的数字,都应保持不变)。 macros应该开始检查Q单元格Q中的单元格,并在遇到包含文本“END”的单元格时停止。 完成后,应该select电子表格左上angular的单元格,这通常是A1,但是我有一个合并的单元格,所以它是A1:K2。
我花了几个小时在本网站和其他网站上查看类似的编码问题。 用我学到的东西写了许多不同版本的这个macros,但是他们要么根本不工作,要么按照预期工作。 这里是我最近的两个最有前景的版本:
'My second to last attempt Sub DeleteRowMacro1() Dim i As Integer i = 11 Do Cells(i, 17).Activate If ActiveCell.Value = 0 Then ActiveCell.EntireRow.Delete End If i = i + 1 Loop Until ActiveCell.Value = "END" Range("A1:K2").Select End Sub 'My last attempt Sub DeleteRowMacro2() Dim i As Integer i = 11 GoTo Filter Filter: Cells(i, 17).Activate If ActiveCell.Value = "END" Then GoTo EndingCondition If ActiveCell.Value = "" Then GoTo KeepCondition If ActiveCell.Value = 0 Then GoTo DeleteCondition If ActiveCell.Value > 0 Then GoTo KeepCondition EndingCondition: Range("A1:K2").Select KeepCondition: i = i + 1 GoTo Filter DeleteCondition: ActiveCell.EntireRow.Delete i = i + 1 GoTo Filter End Sub
DeleteRowMacro1()所执行的操作:
DeleteRowMacro1()有点作品。 如果在Q列中存在文本或数目大于0的数字,则它将离开该行,但会删除具有0 AND空白单元格的单元格的行。 我想保留与空白单元格的行。
另外,这个macros似乎不能在一次运行中用“END”来检查Q11和单元之间的450个左右的单元。 它每次只删除大约一半的行,但不会以任何有意义的方式。 这不像应该被删除的行的前半部分被删除。 这很奇怪,因为前10行左右的行总是正确的,但是之后就会随机地select列Q中有零或空白的行来删除。 为了澄清,它永远不会删除一个文本或0以外的数字(这是正确的,我想要的)的行,但它删除的单元格,它永远不会删除所有的一次,它也不会删除它们(除了前面提到的前10个之外)。
如果我运行macros7或8次,它最终将删除所有行0(不幸的是也是空白的),但我希望它完全做一个运行的工作,而不是删除行与空白单元格。
注意:检查单元格以确定一行是否需要删除并不重要,但是对我来说这似乎很奇怪,所以我想我应该提及它,以防万一它为什么必须运行7或8次来完成它的工作。
DeleteRowMacro2()做什么:
DeleteRowMacro2()的工作方式与前一个很相似,但它不会像其他人那样停止在“结束”,即使它应该。 但是,它确实留下Q列中的单元格为空白的行。 我无法得到以前的macros来做到这一点。
当我运行DeleteRowMacro2()时,最终结果几乎与DeleteRowMacro1()完全相同,我必须运行它7或8次才能完全清除Q列中所有具有0的行。以前的macros,它也似乎随机检查细胞删除(除了前10个左右,再次)。
除了这个问题之外,因为它在我运行的时候并没有真正结束,所以我的屏幕上电子表格变黑的区域和所有我能看到的都是绿色的选中的单元格在Q列的随机位置上下闪烁直到达到32,000s的行数。 之后,我的屏幕返回显示正常的白色电子表格,并出现一个框,说运行时错误“6”:溢出。
请注意:尽pipe我确实遇到了运行时错误,但在错误框中单击“结束”之后,我可以到电子表格的顶部,看到macros已经工作了(而且我已经描述了它到底是什么做了以上)。
对不起。 我知道这很多,但我希望我的macros做一些非常具体的事情,我遇到了非常具体的问题。 我认为更详细的我是更好的人可以帮助我。 谢谢任何回复并试图帮助我解决这些问题的人。
试试看,
Option Explicit Sub DeleteRowMacro3() Dim rwend As Variant With Worksheets("Sheet5") If .AutoFilterMode Then .AutoFilterMode = False rwend = Application.Match("end", .Range(.Cells(11, "Q"), .Cells(.Rows.Count, "Q")), 0) If Not IsError(rwend) Then With .Range(.Cells(10, "Q"), .Cells(rwend + 10, "Q")) .AutoFilter Field:=1, Criteria1:=0, Operator:=xlOr, Criteria2:=vbNullString With .Resize(.Rows.Count - 1, 1).Offset(1, 0) If CBool(Application.Subtotal(103, .Cells)) Then .SpecialCells(xlCellTypeVisible).EntireRow.Delete End If End With End With End If .Activate .Range("A1:K2").Select If .AutoFilterMode Then .AutoFilterMode = False End With End Sub
我不知道你是专门为零还是零值,所以我包括空白单元格以及数字零。
首先,最好避免使用.Select
/ .Activate
。 一般在做循环/macros时会造成一些困惑和棘手的写法。
其次,避免GoTo
也是最好的select。
这个macros将从列Q的最后一行开始,向第11行的方向移动。如果一个单元格的值为0
,它将删除该行。 如果值是END
,它将select您的范围并退出For
循环,然后退出子。
Sub delRows() Dim lastRow As Long, i As Long Dim ws as Worksheet Set ws = Worksheets("Sheet1") ' CHANGE THIS AS NECESSARY lastRow = ws.Cells(ws.Rows.Count, 17).End(xlUp).Row For i = lastRow To 11 Step -1 If ws.Cells(i, 17).Value = "END" Then ws.Range("A1:K2").Select Exit For End If If ws.Cells(i, 17).Value = 0 or ws.Cells(i, 17).Value = "0" Then ws.Cells(i, 17).EntireRow.Delete End If Next i End Sub
试试你的第一个代码的这个变种:
Sub DeleteRowMacro1() Dim i As Integer i = 11 Do Cells(i, 17).Activate If IsEmpty(ActiveCell.Value) Then ActiveCell.EntireRow.Delete End If If ActiveCell.Value = "END" Then Exit Do End If i = i + 1 Loop Range("A1:K2").Select End Sub