Vba 如果单元格为空,则删除整行
在Excel中,如果单元格为空,我希望删除整行。 这应该算作17:1000。 运行脚本将返回错误: 运行时1004错误Vba 如果单元格为空,则删除整行,vba,excel,Vba,Excel,在Excel中,如果单元格为空,我希望删除整行。 这应该算作17:1000。 运行脚本将返回错误: 运行时1004错误 对象全局的方法范围失败 如果我用A替换A17:A1000,它会删除一些行 Sub DeleteBlanks() Dim r As Long Dim m As Long Application.ScreenUpdating = False m = Range("A17:A1000" & Rows.Count).End(xlUp).Row
对象全局的方法范围失败 如果我用A替换A17:A1000,它会删除一些行
Sub DeleteBlanks()
Dim r As Long
Dim m As Long
Application.ScreenUpdating = False
m = Range("A17:A1000" & Rows.Count).End(xlUp).Row
For r = m To 1 Step -1
If Range("A17:A1000" & r).Value = "" Or Range("A17:A1000" & r).Value = 0 Then
Range("A17:A1000" & r).EntireRow.Delete
End If
Next r
Application.ScreenUpdating = True
End Sub
代码中的主要问题是计数错误。
“A17:A1000”&r
不计算行数,而是将数字r
附加到该字符串。因此,例如,如果r=500
,它将导致“A17:A1000500”
,但不会像您预期的那样导致“A17:A1500”
要删除列A有空白单元格的所有行,可以使用
Option Explicit
Public Sub DeleteRowsWithBlankCellsInA()
Worksheets("Sheet1").Range("A17:A1000").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
End Sub
这一个一次删除所有空行,因此速度相当快。此外,它不需要禁用屏幕更新
,因为这只是一个操作
或者,如果需要删除空白单元格和零单元格,请使用
Option Explicit
Public Sub DeleteRowsWithBlankOrZeroCellsInA()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1") 'define which worksheet
Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim iRow As Long
For iRow = LastRow To 1 Step -1
If ws.Cells(iRow, "A").Value = vbNullString Or ws.Cells(iRow, "A").Value = 0 Then
ws.Rows(iRow).Delete
End If
Next iRow
End Sub
这一行逐行删除。每个删除操作都需要时间,因此删除的行越多,所需时间就越长。另外,它可能需要禁用屏幕更新
,否则您将看到逐行操作
另一种方法是使用Union()
收集所有要删除的行,然后立即删除它们
Option Explicit
Public Sub DeleteRowsWithBlankOrZeroCellsInA()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1") 'define which worksheet
Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim DeleteRange As Range
Dim iRow As Long
For iRow = LastRow To 1 Step -1 'also forward looping is possible in this case: For iRow = 1 To LastRow
If ws.Cells(iRow, "A").Value = vbNullString Or ws.Cells(iRow, "A").Value = 0 Then
If DeleteRange Is Nothing Then
Set DeleteRange = ws.Rows(iRow)
Else
Set DeleteRange = Union(DeleteRange, ws.Rows(iRow)) 'collect rows to delete
End If
End If
Next iRow
DeleteRange.Delete 'delete all at once
End Sub
这也是相当快的,因为您再次只有一个删除操作。此外,它不需要禁用屏幕更新
,因为这只是一个操作
在这种情况下,也没有必要向后循环
步骤-1
,因为它只收集循环中的行并立即删除(在循环之后)。因此,从iRow=1的循环到LastRow也会起作用。代码中的主要问题是计数错误。
“A17:A1000”&r
不计算行数,而是将数字r
附加到该字符串。因此,例如,如果r=500
,它将导致“A17:A1000500”
,但不会像您预期的那样导致“A17:A1500”
要删除列A有空白单元格的所有行,可以使用
Option Explicit
Public Sub DeleteRowsWithBlankCellsInA()
Worksheets("Sheet1").Range("A17:A1000").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
End Sub
这一个一次删除所有空行,因此速度相当快。此外,它不需要禁用屏幕更新
,因为这只是一个操作
或者,如果需要删除空白单元格和零单元格,请使用
Option Explicit
Public Sub DeleteRowsWithBlankOrZeroCellsInA()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1") 'define which worksheet
Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim iRow As Long
For iRow = LastRow To 1 Step -1
If ws.Cells(iRow, "A").Value = vbNullString Or ws.Cells(iRow, "A").Value = 0 Then
ws.Rows(iRow).Delete
End If
Next iRow
End Sub
这一行逐行删除。每个删除操作都需要时间,因此删除的行越多,所需时间就越长。另外,它可能需要禁用屏幕更新
,否则您将看到逐行操作
另一种方法是使用Union()
收集所有要删除的行,然后立即删除它们
Option Explicit
Public Sub DeleteRowsWithBlankOrZeroCellsInA()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1") 'define which worksheet
Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim DeleteRange As Range
Dim iRow As Long
For iRow = LastRow To 1 Step -1 'also forward looping is possible in this case: For iRow = 1 To LastRow
If ws.Cells(iRow, "A").Value = vbNullString Or ws.Cells(iRow, "A").Value = 0 Then
If DeleteRange Is Nothing Then
Set DeleteRange = ws.Rows(iRow)
Else
Set DeleteRange = Union(DeleteRange, ws.Rows(iRow)) 'collect rows to delete
End If
End If
Next iRow
DeleteRange.Delete 'delete all at once
End Sub
这也是相当快的,因为您再次只有一个删除操作。此外,它不需要禁用屏幕更新
,因为这只是一个操作
在这种情况下,也没有必要向后循环步骤-1
,因为它只收集循环中的行并立即删除(在循环之后)。因此,从iRow=1的循环到LastRow也会起作用。代码中存在多个错误
首先,您的过程应该声明其范围。
大概在您的情况下Private
您错误地定义了范围()
请查看
Range.Value=0
与Range=”“
不同,或者更好的是IsEmpty(Range)
删除单个行时自始至终循环将导致复杂情况(考虑到它们的索引[indexes(?)]的变化)-或者更好地说,我自己-这是一种有效的做法,但您应该知道如何使用索引。在你的情况下,按照后进先出的顺序对他们来说似乎容易得多李>
最后但并非最不重要的一点是,使用某些声明会使代码变得不必要的复杂化(可以说这不是一个错误,但需要改进)
考虑到所有这些因素,您的代码应该如下所示:
Option Explicit
Private Sub remove_empty_rows()
Dim ws as Worksheet: Set ws = Sheets("Your Sheet Name")
Dim lr as Long
lr = ws.Cells(Rows.Count, 1).End(xlUp).Row
Dim i as Long
For i = lr to 1 Step -1
If IsEmpty(ws.Cells(i, 1)) Then
ws.Rows(i).Delete
End If
Next i
End Sub
一般来说,听起来没有居高临下的意思,但在编码实践中似乎存在一些学习差距。我建议您在亲自编写这样的代码之前,先阅读一些文档或教程。您的代码中存在多个错误
首先,您的过程应该声明其范围。
大概在您的情况下Private
您错误地定义了范围()
请查看
Range.Value=0
与Range=”“
不同,或者更好的是IsEmpty(Range)
删除单个行时自始至终循环将导致复杂情况(考虑到它们的索引[indexes(?)]的变化)-或者更好地说,我自己-这是一种有效的做法,但您应该知道如何使用索引。在你的情况下,按照后进先出的顺序对他们来说似乎容易得多李>
最后但并非最不重要的一点是,使用某些声明会使代码变得不必要的复杂化(可以说这不是一个错误,但需要改进)
考虑到所有这些因素,您的代码应该如下所示:
Option Explicit
Private Sub remove_empty_rows()
Dim ws as Worksheet: Set ws = Sheets("Your Sheet Name")
Dim lr as Long
lr = ws.Cells(Rows.Count, 1).End(xlUp).Row
Dim i as Long
For i = lr to 1 Step -1
If IsEmpty(ws.Cells(i, 1)) Then
ws.Rows(i).Delete
End If
Next i
End Sub
一般来说,听起来没有居高临下的意思,但在编码实践中似乎存在一些学习差距。我建议您在亲自编写这样的代码之前,先正确阅读一些文档或教程。考虑到A17
单元格是一个标题,您可以使用AutoFilter
而不是在单元格上迭代:
Sub FastDeleteMethod()
Dim rng As Range, rngFiltered As Range
Set rng = Range("A17:A" & Cells(Rows.Count, "A").End(xlUp).Row)
With rng
.AutoFilter Field:=1, Criteria1:=0, Operator:=xlOr, Criteria2:="="
On Error Resume Next
Set rngFiltered = rng.SpecialCells(xlCellTypeVisible)
If Err = 0 Then rngFiltered.EntireRow.Delete
On Error GoTo 0
End With
End Sub
考虑到A17
单元格是一个标题,您可以使用AutoFilter
而不是在单元格上迭代:
Sub FastDeleteMethod()
Dim rng As Range, rngFiltered As Range
Set rng = Range("A17:A" & Cells(Rows.Count, "A").End(xlUp).Row)
With rng
.AutoFilter Field:=1, Criteria1:=0, Operator:=xlOr, Criteria2:="="
On Error Resume Next
Set rngFiltered = rng.SpecialCells(xlCellTypeVisible)
If Err = 0 Then rngFiltered.EntireRow.Delete
On Error GoTo 0
End With
End Sub
Rows(i).EntireRow.Delete
应该是ws.Rows(i)。Delete
我认为,因为Rows(i)
已经是整行了。另外,i
应声明为Dim i as Long
@Pᴇʜ我认为两者都应该起作用,但从技术上讲,。EntireRow
在这里是过度的。至于i
声明,我的代码没有Opt