2017-01-02 64 views
1

這是爲了遍歷兩列並確認L列中的值低於另一個工作表中單元格中的特定(單個)值。它還檢查列M中同一行的單元格中是否存在「#N/A」錯誤。如果這些錯誤是真的,那麼將刪除整行。下面的代碼似乎工作,但是,我必須多次運行For循環才能完全刪除所有行。我的直覺是,當一行被刪除時,它不會檢查它下面的一行,並繼續前進。我怎樣才能避免這種情況?任何幫助表示讚賞。如何防止在檢查並刪除前一行時跳過行檢查?

Sub removerows() 

Dim wsOut As Worksheet 
Dim wsPrev As Worksheet 
Dim r As Long 
Dim Lastrow As Long 

Set wsOut = Worksheets("Output") 
Set wsPrev = Worksheets("Previous") 
Lastrow = wsOut.UsedRange(wsOut.UsedRange.Cells.Count).Row 

For r = 2 To Lastrow 
    If wsOut.Cells(r, "L").Value < wsPrev.Cells(2, "L").Value And _ 
     Application.WorksheetFunction.IsNA(wsOut.Cells(r, "M").Value) Then 
       wsOut.Cells(r, "L").EntireRow.Delete 
     Else 
      wsOut.Cells(r, "L").Interior.ColorIndex = 20 
    End If 
Next 

End Sub 
+3

當你刪除一行時,你是「推動」下一行到第r位置(替換當前行),所以當你增加到下一個r時,它自然會跳過你碰到的行向上。它看起來好像在底部會出現問題,因爲即使刪除了行,Lastrow(總行數)也保持不變。 – vknowles

回答

2

運行反向循環。

更改For r = 2 To LastrowFor r = Lastrow to 2 Step -1

沒有測試它,因爲我在手機上,但這應該可以解決您的問題。

+0

就是這樣。謝謝! – lookininward

1
Sub removerows() 

    Dim wsOut As Worksheet 
    Dim wsPrev As Worksheet 
    Dim r As Long 
    Dim Lastrow As Long 

    Set wsOut = Worksheets("Output") 
    Set wsPrev = Worksheets("Previous") 
    Lastrow = wsOut.UsedRange(wsOut.UsedRange.Cells.Count).Row 

    For r = Lastrow To 2 step -1 
     If wsOut.Cells(r, "L").Value < wsPrev.Cells(2, "L").Value And _ 
      Application.WorksheetFunction.IsNA(wsOut.Cells(r, "M").Value) Then 
        wsOut.Cells(r, "L").EntireRow.Delete 
      Else 
       wsOut.Cells(r, "L").Interior.ColorIndex = 20 
     End If 
    Next 

End Sub 

這個想法是讓循環向後,如果你刪除。

0

你可以加速這一過程,並通過使用AutoFilter()避免循環:

Option Explicit 

Sub removerows() 
    Dim prevValue As Double 

    prevValue = Worksheets("Previous").Range("L2") 
    With Worksheets("Output") '<--| reference your "output" sheet 
     With .Range("M1", .Cells(.Rows.count, "L").End(xlUp)) '<--| reference its columns "L:M" range from row 1 (header) down to column "L" last not empty row 
      .AutoFilter Field:=1, Criteria1:="<" & prevValue '<--| 1st filter on column "L" with values lower than sheet "previous" sheet "L2" cell 
      .AutoFilter Field:=2, Criteria1:="#N/A" '<--| '<--| 2nd filter on column "M" with values "#N/A" values 
      If Application.WorksheetFunction.Subtotal(103, .Resize(, 1)) > 1 Then .Resize(.Rows.count - 1).Offset(1).SpecialCells(xlCellTypeVisible).EntireRow.Delete '<--| if any filtered cells then delete their row 
      .AutoFilter '<--| remve filters 
      .AutoFilter Field:=1, Criteria1:=">=" & prevValue '<--| filter on column "L" with values greater or equal than sheet "previous" sheet "L2" cell 
      If Application.WorksheetFunction.Subtotal(103, .Resize(, 1)) > 1 Then .Resize(.Rows.count - 1, 1).Offset(1).SpecialCells(xlCellTypeVisible).Interior.ColorIndex = 20 '<--| if any filtered celld then color them 
     End With 
    End With 
End Sub 
0

只需添加R = R - 1的行被刪除了。

Sub removerows() 

Dim wsOut As Worksheet 
Dim wsPrev As Worksheet 
Dim r As Long 
Dim Lastrow As Long 

Set wsOut = Worksheets("Output") 
Set wsPrev = Worksheets("Previous") 
Lastrow = wsOut.UsedRange(wsOut.UsedRange.Cells.Count).Row 

For r = 2 To Lastrow 
    If wsOut.Cells(r, "L").Value < wsPrev.Cells(2, "L").Value And _ 
     Application.WorksheetFunction.IsNA(wsOut.Cells(r, "M").Value) Then 
       wsOut.Cells(r, "L").EntireRow.Delete 
    *****  r = r -1 'Done! it will recheck the same cell after 
     Else 
      wsOut.Cells(r, "L").Interior.ColorIndex = 20 
    End If 
Next 

End Sub