如何解决VBA Entirerow.Delete 不会删除 For Each 中的最后一个单元格
我有一些代码可以删除 Excel 中的行,如果它们比选定的日期旧。该函数有效,但不会删除最后一个值。
如果我运行此代码,例如:
Dim count As Long
count = 0
Dim searchRng As Range: Set searchRng = Range("Q9:Q5000")
Dim Cell As Range
For Each Cell In searchRng
If ((Cell.Value < CDate(TextBoxDelete.Value)) And (Cell.Value <> "")) Then
count = count + 1
Debug.Print ("Cell " & count & ": " & Cell.Value & " txtBox: " & TextBoxDelete.Value)
'Cell.EntireRow.Delete ' This line deletes the Row
End If
Next Cell
Cell 1: 03.03.2021 txtBox: 04.03.2021
Cell 2: 03.03.2021 txtBox: 04.03.2021
Cell 3: 03.03.2021 txtBox: 04.03.2021
Cell 4: 03.03.2021 txtBox: 04.03.2021
这是正确的,这些是比 TextBox.Value 旧的 4 个单元格
现在,当我在 DELETE 部分中使用相同的函数和注释时,输出如下所示:
Cell 1: 03.03.2021 txtBox: 04.03.2021
Cell 2: 03.03.2021 txtBox: 04.03.2021
代码是一样的,但你可以看到它现在只能找到 2 个值 - 而不是 4 个!
找到的 2 个单元格被删除,但其他 2 个单元格没有被删除。
有没有人遇到过类似的行为?
编辑:在回答部分的所有帮助之后,我想出了这个:
For j = searchRng.count To 1 Step -1
If ((searchRng(j).Value < CDate(TextBoxDelete.Value)) And (searchRng(j).Value <> "")) Then
count = count + 1
Debug.Print ("Cell " & count & ": " & searchRng(j).Value & " txtBox: " & TextBoxDelete.Value)
searchRng(j).EntireRow.Delete ' Delete Call for the Row
End If
Next j
这是有效的代码还是有任何缺陷?运行它正是我需要的。
解决方法
您正在修改正在迭代的内容。所以一旦你删除了第一行,第二行就变成了你已经处理过的第一行,所以在原来的第 3 行继续迭代,现在是迭代中的第二个项目。
有同样的问题,但在 java 中有一些很好的答案 here。
,如果使用循环,一般需要使用For i = x to 1 Step -1
类型的循环来删除行。另一种方法是使用 Application.Union
建立一个删除范围,然后一次性删除所有内容。
您应该如何调整代码的示例如下(未经测试);
Sub ExampleDelete()
Dim SearchRng As Range: Set SearchRng = Range("Q9:Q5000")
Dim i As Long,Cell As Range
For i = SearchRng.Cells.count To 1 Step -1
Set Cell = Application.WorksheetFunction.Index(SearchRng,i)
If ((Cell.Value < CDate(TextBoxDelete.Value)) And (Cell.Value <> "")) Then
Debug.Print ("Cell " & i & ": " & Cell.Value & " txtbox: " & TextBoxDelete.Value)
'Cell.EntireRow.Delete ' This line deletes the Row
End If
Next Cell
End Sub
,
您可以通过收集单元格然后一次删除它们来从上到下遍历您的范围:
Option Explicit
Sub test1()
Dim toDel As Range,Cell As Range
Dim searchRng As Range: Set searchRng = Range("Q9:Q5000")
' debug var; remove it and replace it further with TextBoxDelete.Value
Dim txtBoxValue: txtBoxValue = #5/10/2021#
For Each Cell In searchRng
If Cell < CDate(txtBoxValue) And Not IsEmpty(Cell) Then
'collect matched cells into toDel
If toDel Is Nothing Then
Set toDel = Cell
Else
Set toDel = Union(toDel,Cell)
End If
Debug.Print ("Cell " & toDel.Cells.count & ": " & Cell.Text & " txtbox: " & txtBoxValue)
End If
Next Cell
' next statement deletes all the rows at once
If Not toDel Is Nothing Then toDel.EntireRow.Delete
End Sub
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。