我的月度基数接近373,000行。其中,部分值较低或为空白。我想删除这一行。
我有部分代码删除那些没有的代码。如何以更灵活的方式创建连接空行条件(D列)的代码。
由于
Sub DelRowsZero()
Dim i As Long
For i = Cells(Rows.Count, "D").End(xlUp).Row To 2 Step -1
If Cells(i, "D") = 0 Then Rows(i).Delete
Next i
End Sub
答案 0 :(得分:2)
怎么样:
Sub ZeroKiller()
Dim N As Long, ToBeKilled As Range
Dim i As Long
N = Cells(Rows.Count, "A").End(xlUp).Row
For i = 1 To N
If Cells(i, "D").Value = 0 Or Cells(i, "D").Value = "" Then
If ToBeKilled Is Nothing Then
Set ToBeKilled = Cells(i, "D")
Else
Set ToBeKilled = Union(ToBeKilled, Cells(i, "D"))
End If
End If
Next i
If Not ToBeKilled Is Nothing Then
ToBeKilled.EntireRow.Delete
End If
End Sub
这假设 A 是最长的列。如果情况并非总是如此,请使用:
N = Range("A1").CurrentRegion.Rows.Count
答案 1 :(得分:2)
我担心375K线,谁知道这需要多长时间才能运行。
Sub Button1_Click()
Dim i As Long
For i = Cells(Rows.Count, "D").End(xlUp).Row To 2 Step -1
If Cells(i, "D") = 0 Or Cells(i, "D") = "" Then
Rows(i).Delete
End If
Next i
End Sub
我很想知道这是否适用于其他人,它只是使用"替换" 0值为空白,然后使用特殊单元删除空行。我对38K行的测试需要3秒钟。
Sub FindLoop()
Dim startTime As Single
startTime = Timer
'--------------------------
Columns("D:D").Replace What:="0", Replacement:="", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=True, SearchFormat:=False, _
ReplaceFormat:=False
Columns("D:D").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
'---------------------------------
Debug.Print Timer - startTime
End Sub
答案 2 :(得分:1)
There's apparently an argument to be made,在找到行时删除行会比一次删除行更快。
所以我在A和B列中运行了36000行=RANDBETWEEN(0, 10)
下面的代码(然后复制+粘贴特殊值/值),并在32秒内完成了三次并且灰尘。
取消注释currentValue
赋值并用currentValue
比较替换数组下标访问会增加2.5秒的开销;取消注释IsError
检查会增加另外3.5秒的开销 - 但如果选中的单元格稍有可能包含一些#REF!
或#VALUE!
错误,则代码不会爆炸。< / p>
每次我运行它时,大约有4000行被删除。
注意:
ActiveSheet
引用。该代码适用于Sheet2
,Worksheets("Sheet2")
的代码名称 - 一个全局范围的Worksheet
对象变量,您可以免费获得存在于此处的任何工作表编译时间。如果您在编译时运行此表单,则使用其代码名称(属性中的(Name)
属性> toolwindow / F4)。Public Sub SpeedyConditionalDelete()
Dim startTime As Single
startTime = Timer
'1. dump the contents into a 2D variant array
Dim contents As Variant
contents = Sheet2.Range("A1:B36000").Value2
'2. declare your to-be-deleted range
Dim target As Range
'3. iterate the array
Dim i As Long
For i = LBound(contents, 1) To UBound(contents, 1)
'4. get the interesting current value
'Dim currentValue As Variant
'currentValue = contents(i, 1)
'5. validate that the value is usable
'If Not IsError(currentValue) Then
'6. determine if that row is up for deletion
If contents(i, 1) = 0 Or contents(i, 1) = vbNullString Then
'7. append to target range
If target Is Nothing Then
Set target = Sheet2.Cells(i, 1)
Else
Set target = Union(target, Sheet2.Cells(i, 1))
End If
End If
'End If
Next
'8. delete the target
If Not target Is Nothing Then target.EntireRow.Delete
'9. output timer
Debug.Print Timer - startTime
End Sub
当然375K行的运行时间会比32-38秒长,但我无法想到更快的解决方案。