Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.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,在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

在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
    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