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