4

我正在尝试编写一个宏来删除A列中所有具有“True”的行。

这是我到目前为止所拥有的:

Sub deleteBlankRows3()
Dim lastrow as Long
Dim x as Long

lastrow = 4650
For x=8 to x=lastrow
    If (Range("A1").Offset(x,0) = True) Then
    Range("A1").Offset(x,0).EntireRow.Delete
    x = x + 1
End if
Next x

End Sub

我说不出有什么问题!

4

5 回答 5

7

I know you have already got what you were looking for. However, still here is another method using Autofilter. This is much faster than looping through each row and checking for the value.

Sub Sample()
    Dim lastRow As Long

    With Sheets("Sheet1")

        lastRow = .Range("A" & Rows.Count).End(xlUp).Row

        '~~> Remove any filters
        .AutoFilterMode = False

        '~~> Filter, offset(to exclude headers) and delete visible rows
        With .Range("A1:A" & lastRow)
            .AutoFilter Field:=1, Criteria1:="TRUE"
            .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
        End With

        '~~> Remove any filters
        .AutoFilterMode = False
    End With
End Sub

HTH

于 2012-04-09T18:33:27.343 回答
4

这里可能有三件事在起作用。

首先,如果您正在测试基础值的等价性,您应该明确查看单元格的值:

If (Range("A1").Offset(x,0).Value = True) Then

不用说.Value,我认为默认情况下单元格返回它的 Text 属性,用于针对非范围属性的等价测试。

其次,您的单元格可能包含字符串“True”,而不是值True,因此请尝试使用

If (Range("A1").Offset(x,0).Value = "True") Then

最后,如果你真的找到了一行,然后删除了它,那么你实际上会跳过一行,因为被删除的行之后的所有行都会向下移动(第 5 行变成第 4 行,等等),但你只是增加了 x,因此您将在删除每一行之后立即跳过该行。要解决此问题,请按降序循环:

For x=lastrow to 8 step -1

或者如果您刚刚删除了一行,则不要增加 x:

If (Range("A1").Offset(x,0).Value = "True") Then
    Range("A1").Offset(x,0).EntireRow.Delete
Else
    x = x + 1
EndIf
于 2012-04-09T17:28:51.223 回答
2

如果没有测试,你最好这样:

    For x=lastrow to 8 step -1
        If (Range("A1").Offset(x,0) = True) Then 
           Range("A1").Offset(x,0).EntireRow.Delete 
        End if 
   Next

Counting up has an issue that if you delete one row all rows after it move up as well causing your loop not to look at all rows. And since you add 1 to the x in those cases you made it even worse. -1 would have been better except that then you still check 4650+number_of_deleted_rows in total which might lead to other problems. By starting at the end and move towards the start you prevent both those issues.

于 2012-04-09T17:29:24.073 回答
1

The problem is that the algorithm is incorrect. Classic case for the corrupted loop variable. The problem is that the variable that the loop is dependent on gets modified, as such it is wrong.

The correct way to do it is this way.

Dim x as integer
x = 8
do
   if (Range("a1").Offset(x, 0) = True) Then
       Range("a1").Offset(x, 0).EntireRow.Delete
   Else
       x = x + 1 'We only increase the row number in the loop when we encounter a row that is false for containing true in cell a1 and their offsets
   End If
Loop Until (x > 4650)
于 2012-04-09T18:02:00.533 回答
0

I had hidden lines and didn't want to unhide them which the filtering method does. Also didn't want to loop through every line so here's my 10c.....

Sub DelError()
    Dim i As Integer
    Dim rngErrRange As Range
    With ActiveSheet
        Do
            Set rngErrRange = .Columns("A:A").Find(What:="#REF!", _
                After:=.Cells(1), LookIn:=xlFormulas, _
                LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
                MatchCase:=False, SearchFormat:=False)
                If Not rngErrRange Is Nothing Then
                    rngErrRange.EntireRow.Delete
                Else
                    End
                End If
        Loop
    End With
End Sub
于 2013-07-16T18:08:48.040 回答