我有一个大型的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行。
答案 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 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
你也可以使用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