删除行时无限循环?

时间:2016-06-20 10:49:38

标签: vba excel-vba excel

我有一个大型的csv文件,我按列排序。现在我想删除另一列中不包含某个sring的行。 到目前为止,我的代码看起来像这样:

Private Sub sortcsvfile(filename)
    Workbooks.OpenText filename, Origin:=65001, StartRow:=1 _
        , DataType:=xlDelimited, TextQualifier:=xlDoubleQuote, _
        ConsecutiveDelimiter:=False, Tab:=True, Semicolon:=True, Comma:=False, _
        Space:=False, Other:=False, FieldInfo:=Array(Array(1, 1), Array(2, 1), Array( _
        3, 1), Array(4, 1), Array(5, 1), Array(6, 1), Array(7, 1), Array(8, 1), Array(9, 1), Array(10 _
        , 1), Array(11, 1), Array(12, 1), Array(13, 1), Array(14, 1), Array(15, 1), Array(16, 1), _
        Array(17, 1), Array(18, 1), Array(19, 1), Array(20, 1), Array(21, 1), Array(22, 1), Array( _
        23, 1), Array(24, 1), Array(25, 1), Array(26, 1), Array(27, 1), Array(28, 1), Array(29, 1), _
        Array(30, 1), Array(31, 1), Array(32, 1), Array(33, 1), Array(34, 1), Array(35, 1), Array( _
        36, 1), Array(37, 1), Array(38, 1), Array(39, 1), Array(40, 1), Array(41, 1), Array(42, 1), _
        Array(43, 1), Array(44, 1), Array(45, 1), Array(46, 1), Array(47, 1)), _
        TrailingMinusNumbers:=True
    x = Cells(Rows.Count, 1).End(xlUp).Row
    Cells.Select
    ActiveWorkbook.Worksheets("merged").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("merged").Sort.SortFields.Add Key:=Range("D2:D" & x _
        ), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    With ActiveWorkbook.Worksheets("merged").Sort
        .SetRange Range("A1:AT" & x)
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With

    For y = 0 To x
        If (Range("J2").Offset(y, 0) <> "condition") Then
            Range("J2").Offset(y, 0).EntireRow.Delete
            y = y - 1
        End If
    Next
End Sub

但是,在我要删除行的部分

For y = 0 To x
    If (Range("J2").Offset(y, 0) <> "condition") Then
        Range("J2").Offset(y, 0).EntireRow.Delete
        y = y - 1
    End If
Next
它看起来像是无休止的循环。这是为什么? 当我尝试For y = 0 To LastRow时,它不会删除任何内容,如果我尝试一个绝对值(如60),它会完美地运行直到第60行。

4 个答案:

答案 0 :(得分:2)

您需要在调整for循环计数器(y)的同时调整最后一行变量(x)。您的代码当前尝试执行,直到y = x,但只有在所有行都满足指定的条件时才会执行(因此不会删除任何内容)。

答案 1 :(得分:1)

以下是您的代码的外观:

Option Explicit 'This is a must

Private Sub sortcsvfile(filename)
Dim x&, y& 'declare variables

With Application 'make things a bits faster
    .Screenupdating=false
    .Calculation = xlCalculationManual
    .EnableEvents = False ' EDIT 3 : This event can trigger infinite loop too, if =True
End With

'your other code

For y = x To 2 step -1 'Go Backwards , impossible to infinite loop, impossible to miss rows
    with Cells(y, 7) 'Use a with. "J" is 7.
        if .value2 <> "condition" Then .EntireRow.Delete '.value2 is slightly faster, do not use it with dates or currency...
    End with
Next y 'add the variable name, in multi loops it's easier to read, and good practice

With Application 'reset to normal
    .Screenupdating= True
    .Calculation = xlCalculationAutomatic
    .EnableEvents = True
End With

End Sub

编辑: Shai Rondo的想法应该可以运作,但也许你的代码很慢并且看起来很无限(取决于x的值)......

EDIT2:更快的方法是将“Bad”单元格添加到范围(名为Rg),并在循环后添加Rg.entireRow.delete。我也试了一下阵列:

Option Explicit 'This is a must
'Please make a copy of your sheet before tring someone else's code.

Private Sub sortcsvfile(filename)
Dim x&, y& 'declare variables
Dim DATA() 'as Variant
Dim Rg As Range

With Application 'make things a bits faster
    .ScreenUpdating = False
    .Calculation = xlCalculationManual
    .EnableEvents = False
End With

'your other code
' ...
'

With ActiveSheet 'reference the sheet you are working with , change this line as needed.
    x = .Cells(.Rows.Count, 1).End(xlUp)
    DATA = .Range(.Cells(1, 7), .Cells(x, 7)).Value2 'write the Array with the Worksheet's contents without loop.

    For y = 2 to x ' For y=x To 2 Step -1 ' EDIT 4 : with the RG/DATA approach you can Go Backwards or upwards, both do the same result...
        If DATA(y, 7) <> "condition" Then
            '2 cases possible
            If Not Rg Is Nothing Then ' i explain the use of "Not" in the folowing line's comment
                Set Rg = Union(Rg, .Cells(y, 7)) 'in a "If" , always do the "Often Used" option, and the lesser used in the "Else"
            Else
                Set Rg = .Cells(y, 7) 'the "lesser used option"
        End If
    Next y 'add the variable name, in multi loops it's easier to read, and good practice

    Rg.EntireRow.Delete 'do only one Delete

End With 'this with refers to the worksheet

Erase DATA 'free memory
Set Rg = Nothing

With Application 'reset to normal
    .ScreenUpdating = True
    .Calculation = xlCalculationAutomatic
    .EnableEvents = True
End With

End Sub

答案 2 :(得分:0)

除了y之外,你需要引入一个变量(t)。

t = x

For y = 0 To x

    If (Range("J2").Offset(y, 0) <> "condition") Then
        Range("J2").Offset(y, 0).EntireRow.Delete
        y = y - 1
        t = t - 1
    End If

    If t < 0 Then
        y = x
    End If

Next y

答案 3 :(得分:0)

有几件事。首先,在使用if语句检查单元格值时,需要使用.value命令。其次,您应该在子例程的开头Dim变量(即Dim x as integerDim y as integer),然后再进行其他操作。

以下是使用.value的代码:

For y = 0 To x
    If (Range("J2").Offset(y, 0).value <> "condition") Then
        Range("J2").Offset(y, 0).EntireRow.Delete
        y = y - 1
    End If
Next

你也可以使用cells()命令,这样你就不必偏移(col 10是col J):

For y = 0 To x
    If (Cells(2 + y,10).value <> "condition") Then
        Cells(2 + y,10).EntireRow.Delete
        y = y - 1
    End If
Next