Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 删除行时执行无止境循环?_Vba_Excel - Fatal编程技术网

Vba 删除行时执行无止境循环?

Vba 删除行时执行无止境循环?,vba,excel,Vba,Excel,我有一个按列排序的大型csv文件。现在我想删除在另一列中不包含特定sring的行。 到目前为止,我的代码如下所示: Private Sub sortcsvfile(filename) Workbooks.OpenText filename, Origin:=65001, StartRow:=1 _ , DataType:=xlDelimited, TextQualifier:=xlDoubleQuote, _ ConsecutiveDelimiter:=F

我有一个按列排序的大型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
Private子sortcsvfile(文件名)
Workbooks.OpenText文件名,源代码:=65001,StartRow:=1_
,数据类型:=xlDelimited,文本限定符:=xlDoubleQuote_
ConcertiveDelimiter:=False,制表符:=True,分号:=True,逗号:=False_
空格:=False,其他:=False,FieldInfo:=数组(数组(1,1),数组(2,1),数组(_
3,1),数组(4,1),数组(5,1),数组(6,1),数组(7,1),数组(8,1),数组(9,1),数组(10_
数组(11,1)、数组(12,1)、数组(13,1)、数组(14,1)、数组(15,1)、数组(16,1)_
阵列(17,1)、阵列(18,1)、阵列(19,1)、阵列(20,1)、阵列(21,1)、阵列(22,1)、阵列(_
阵列(24,1)、阵列(25,1)、阵列(26,1)、阵列(27,1)、阵列(28,1)、阵列(29,1)_
数组(30,1)、数组(31,1)、数组(32,1)、数组(33,1)、数组(34,1)、数组(35,1)、数组(_
阵列(37,1)、阵列(38,1)、阵列(39,1)、阵列(40,1)、阵列(41,1)、阵列(42,1)_
阵列(43,1)、阵列(44,1)、阵列(45,1)、阵列(46,1)、阵列(47,1))_
TrailingMinusNumbers:=真
x=单元格(Rows.Count,1)。结束(xlUp)。行
单元格。选择
ActiveWorkbook.Worksheets(“合并”).Sort.SortFields.Clear
ActiveWorkbook.Worksheets(“合并”).Sort.SortFields.Add Key:=Range(“D2:D”)和x_
),SortOn:=xlSortOnValues,顺序:=xlAscending,数据选项:=xlSortNormal
使用ActiveWorkbook.Worksheets(“合并”).Sort
.SetRange范围(“A1:AT”&x)
.Header=xlYes
.MatchCase=False
.方向=xlTopToBottom
.SortMethod=xl拼音
.申请
以
对于y=0到x
如果(范围(“J2”).偏移量(y,0)“条件”),则
范围(“J2”)。偏移量(y,0)。EntireRow.Delete
y=y-1
如果结束
下一个
端接头
但是,在我要删除行的部分

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
y=0到x的

如果(范围(“J2”).偏移量(y,0)“条件”),则
范围(“J2”)。偏移量(y,0)。EntireRow.Delete
y=y-1
如果结束
下一个
这似乎是一个无止境的循环。为什么呢?
当我尝试将y=0转换为LastRow时,它不会删除任何内容,如果我尝试一个绝对值(如60),它会一直工作到第60行。

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

您需要在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
t=x
对于y=0到x
如果(范围(“J2”).偏移量(y,0)“条件”),则
范围(“J2”)。偏移量(y,0)。EntireRow.Delete
y=y-1
t=t-1
如果结束
如果t<0,则
y=x
如果结束
下一个y

有几件事。首先,在使用if语句检查单元格值时,需要使用
.value
命令。其次,您应该在子例程开始时将变量设置为
Dim
(即键入
Dim x as integer
Dim 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

以下是您的代码的外观:

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

尝试y=x到0的反向循环
,不幸的是,步骤-1
没有帮助。结束循环的唯一方法是使用任务管理器。您还可以在Windows上(或Mac上)使用键盘组合
Ctrl+break
,手动中断循环(除非您已设置
Application.EnableCancelKey=xlDisabled
)。在进入for循环之前,检查
x
的值是多少。使用
Debug.Print x
删除行时,最好将其向后循环。请尝试声明变量。什么是
单元格。选择
?是的,理论上这是正确的,但是,在循环中不能调整循环结束,因此即使调整x,也不能在@Sun点工作。因此,您需要另一行来计算计数器并退出子系统,例如
If(y>x),然后退出子系统
exit For
。谢谢!效果很好,但只有在阅读lonestorms的答案后才能理解。是的,你是对的,也许我应该多解释一点:)而不是范围和偏移量。使用
.cells()
会更好。要删除它,它总是向后的,否则你会有这种循环,你会错过一些要删除的行。现在来吧,即使这段代码“工作”,它只是太满了,你需要3个变量来完成一个变量的工作@PatrickLepelletier虽然你可能是对的,但问题是:
它似乎在无休止地循环。这是为什么?
@PatrickLepelletier此外,他没有遗漏任何要删除的行
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
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