Excel VBA - 为什么这个宏会删除所有内容

时间:2016-06-07 14:42:46

标签: excel vba excel-vba for-loop macros

我需要一些关于这个宏的帮助。我有一个格式很差的工作簿,但每次打开它时都一直都是这样。除此之外,目标是在B列中找到非空白单元格并删除下面的整个2行和每个填充B单元格上方的第1行。

我在代码中的第一个循环就像我想要的那样工作,但是第二个循环似乎只能在填充的B单元格的第一个实例上工作,但是它会删除其上面的所有其他内容,比如500个单元格值得的数据。

有人可以向我解释为什么会发生这种情况,如果你能找到一种方法将两个for循环组合成1,那也会很好。

Sub test()

Dim currentSht As Worksheet
Dim startCell As Range
Dim lastRow As Long, lastCol As Long
Dim colNames As Variant
Dim i As Integer, j As Integer

Set currentSht = ActiveWorkbook.Sheets(1)
Set startCell = currentSht.Range("A1")
lastRow = startCell.SpecialCells(xlCellTypeLastCell).Row
lastCol = startCell.SpecialCells(xlCellTypeLastCell).Column

For i = lastRow To 1 Step -1
If currentSht.Cells(i, "B").Value <> "" Then
    currentSht.Cells(i, "B").Offset(1).EntireRow.Delete
End If
Next i

Range("D3").Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Delete Shift:=xlUp

currentSht.Rows("1:1").EntireRow.Delete
currentSht.Range("c:d, f:g, i:k").EntireColumn.Delete
currentSht.Range("A:D").Columns.AutoFit

For j = lastRow To 2 Step -1
If currentSht.Cells(j, "B").Value <> "" Then
    currentSht.Range(Cells(j, "B").Offset(-1), Cells(j, "B").Offset(-3)).EntireRow.Delete
End If
Next j
End Sub

谢谢

1 个答案:

答案 0 :(得分:2)

第二个循环删除所有内容,因为在删除行above找到的值后,所述值会向上移动并再次找到,从而触发另一个删除。要解决这个问题,最快捷的方法是通过修改j:

来跳过接下来的两行
For j = lastRow To 2 Step -1
    If currentSht.Cells(j, "B").Value <> "" Then
        currentSht.Range(Cells(j, "B").Offset(-1), Cells(j, "B").Offset(-3)).EntireRow.Delete
        j = j - 2
    End If
Next j

如果你从上到下循环,反之亦然,那真的不重要。唯一的区别是,如果B列中有两个条目彼此靠近。在这种情况下,搜索顺序将确定删除哪一个。但删除真的是你想要的吗?也许你可以.Clear行的内容而不是删除它们。

编辑:这里新代码有点清理

Sub test()
    Dim currentSht As Worksheet
    Dim startCell As Range
    Dim lastRow As Long, lastCol As Long
    Dim colNames As Variant
    Dim i As Integer, j As Integer

    Set currentSht = ActiveWorkbook.Sheets(1)
    Set startCell = currentSht.Range("A1")
    lastRow = startCell.SpecialCells(xlCellTypeLastCell).Row
    lastCol = startCell.SpecialCells(xlCellTypeLastCell).Column

    For i = lastRow To 1 Step -1
        If currentSht.Cells(i, "B").value <> "" Then
            'reference the row directly
            currentSht.Rows(i + 1).Delete
        End If
    Next i

    'Do not use selection if you can avoid it
    Range("D3", Range("D3").End(xlToRight)).Delete Shift:=xlUp

    currentSht.Rows(1).Delete
    currentSht.Range("C:D, F:G, I:K").Delete
    currentSht.Range("A:D").Columns.AutoFit

    For j = lastRow To 2 Step -1
        If currentSht.Cells(j, "B").value <> "" Then
            currentSht.Rows(j - 1).Delete
            currentSht.Rows(j - 2).Delete
            j = j - 2
        End If
    Next j
End Sub

如果你想组合循环,宏的行为会因为循环之间发生的删除而改变。