我的实习生和我写了一个VBA块,该块遍历数据集并在应用分析之前清除了不需要的行。循环在一天之内起作用,然后在第二天起作用,这将做最奇怪的事情:它看起来似乎要执行,但随后结束子程序,之后不执行任何代码。我们找到了一个通常可以使用更好的编码的解决方案,该解决方案有效,但是我不明白为什么原始代码不起作用以及为什么要终止子代码。它并没有吐出任何错误,只是假装就像完成了一样,没有任何中断会阻止它在执行中。
这是断块-
LastRow = wb_Audit.Sheets("Data Sheet").Cells(Rows.Count, "AN").End(xlUp).Row
For iRow = 2 To LastRow
If wb_Audit.Sheets("Data Sheet").Cells(iRow, "AQ").Value = "Dead Deal" Then
wb_Audit.Worksheets("Data Sheet").Range("AM" & iRow & ":AW" & iRow).Delete Shift:=xlShiftUp
iRow = iRow - 1
LastRow = LastRow - 1
If iRow > LastRow Then End
Else: End If
If wb_Audit.Sheets("Data Sheet").Cells(iRow, "AQ").Value = "Closed" Then
wb_Audit.Worksheets("Data Sheet").Range("AM" & iRow & ":AW" & iRow).Delete Shift:=xlShiftUp
iRow = iRow - 1
LastRow = LastRow - 1
If iRow > LastRow Then End
Else: End If
If wb_Audit.Sheets("Data Sheet").Cells(iRow, "AM").Value = "" Then
wb_Audit.Worksheets("Data Sheet").Range("AM" & iRow & ":AW" & iRow).Delete Shift:=xlShiftUp
iRow = iRow - 1
LastRow = LastRow - 1
If iRow > LastRow Then End
Else: End If
If wb_Audit.Sheets("Data Sheet").Cells(iRow, "AM").Value = "HOLD" Then
wb_Audit.Worksheets("Data Sheet").Range("AM" & iRow & ":AW" & iRow).Delete Shift:=xlShiftUp
iRow = iRow - 1
LastRow = LastRow - 1
If iRow > LastRow Then End
Else: End If
Next iRow
这是我们现在将其替换为可以正常工作的块。
For iRow = 2 To LastRow
If iRow > LastRow Then Exit For
If wb_Audit.Sheets("Data Sheet").Cells(iRow, "AQ").Value = "Dead Deal" Then
wb_Audit.Worksheets("Data Sheet").Range("AM" & iRow & ":AW" & iRow).Delete Shift:=xlShiftUp
iRow = iRow - 1
LastRow = LastRow - 1
Else: End If
If wb_Audit.Sheets("Data Sheet").Cells(iRow, "AQ").Value = "Closed" Then
wb_Audit.Worksheets("Data Sheet").Range("AM" & iRow & ":AW" & iRow).Delete Shift:=xlShiftUp
iRow = iRow - 1
LastRow = LastRow - 1
Else: End If
If wb_Audit.Sheets("Data Sheet").Cells(iRow, "AM").Value = "" Then
wb_Audit.Worksheets("Data Sheet").Range("AM" & iRow & ":AW" & iRow).Delete Shift:=xlShiftUp
iRow = iRow - 1
LastRow = LastRow - 1
Else: End If
If wb_Audit.Sheets("Data Sheet").Cells(iRow, "AM").Value = "HOLD" Then
wb_Audit.Worksheets("Data Sheet").Range("AM" & iRow & ":AW" & iRow).Delete Shift:=xlShiftUp
iRow = iRow - 1
LastRow = LastRow - 1
Else: End If
Next iRow
我们有有效的代码,我只想了解第一个代码块出了什么问题。
答案 0 :(得分:3)
仅向您显示代码的替代方法:
Sub NewSub()
Dim lr As Long, irow As Long
With ThisWorkbook.Sheets("Data Sheet")
lr = .Cells(Rows.Count, "AN").End(xlUp).Row
For irow = lr To 2 Step -1
If .Cells(irow, "AQ").Value = "Dead Deal" Or .Cells(irow, "AQ").Value = "Closed" Or .Cells(irow, "AM").Value = "" Or .Cells(irow, "AM").Value = "HOLD" Then
.Range("AM" & irow & ":AW" & irow).Delete Shift:=xlShiftUp
End If
Next irow
End With
End Sub
答案 1 :(得分:0)
从End statement的帮助页面开始:
当我们到达这一行时,如果End语句突然停止执行代码,而无需调用 卸载,QueryUnload或终止事件,或任何其他Visual Basic 代码
If iRow > LastRow Then End
, iRow > LastRow
将立即终止宏。 For iRow = 2 To LastRow
循环之后的任何代码将永远不会执行,因为宏将终止。
如果您要做的只是摆脱End
循环,请使用Exit For
,而不要使用For
答案 2 :(得分:0)
您的问题并未从下至上删除,而是尝试解决您遇到的问题。从上到下删除时会发生什么?当您测试一行然后删除数据时,下面的行将移动到当前行,然后您的循环向下移动到下一行,从而使您跳过向上移动的行。就像JvdV所示,您可以将所有条件组合成一个If
语句。您的代码可以大大缩短...
Dim ws As Worksheet, lastRow As Long
Set ws = ThisWorkbook.Sheets("Data Sheet") 'Or Workbooks("wb_Audit").Sheets("Data Sheet")
lastRow = ws.Cells(ws.Rows.Count, "AN").End(xlUp).Row
For iRow = lastRow To 2 Step -1 'when deleting rows you need to start from the bottom
If ws.Cells(iRow, "AQ").Value = "Dead Deal" Or ws.Cells(iRow, "AQ").Value = "Closed" Or _
ws.Cells(iRow, "AM").Value = "" Or ws.Cells(iRow, "AM").Value = "HOLD" Then
ws.Range("AM" & iRow & ":AW" & iRow).Delete Shift:=xlShiftUp
Next iRow