遍历所有行并找到活动工作表VBA中的空行

时间:2018-07-13 11:04:14

标签: excel vba

我有一个Excel工作表,其中的不同“部分”用空行隔开。我想做的就是简单地获取行号以与它们一起使用。遗憾的是,代码没有执行For-循环(没有失败,只是没有输入),但是rowNumber变量设置正确。我在For-Loop上错过了什么吗?

Sub Foo()
    Dim currentSheet As Worksheet
    Set currentSheet = activeSheet
    emptyRows = FindAllEmptyRows(currentSheet)
End Sub

Function FindAllEmptyRows(sheet As Worksheet) As Variant
    Dim emptyRows() As Variant
    Dim i As Long, rowNumber As Long
    Dim rowCounter As Integer
    rowCounter = 1

    rowNumber = sheet.UsedRange.Rows.Count
    For i = rowNumber To 1
        If Cells(i, 1).End(xlToRight).Column = 16384 And Cells(i, 1) = "" Then
            emptyRows(rowCounter) = i
            rowCounter = rowCounter + 1
        End If
    Next

    FindAllEmptyRows = emptyRows
End Function

2 个答案:

答案 0 :(得分:0)

  • 如果要从最后一行迭代到第一行,则需要添加步骤-1。
  • emptyRows()的大小需要适合使用ReDim的数据
  • .Column = 16384应该更改为.Column = sheet.Columns.Count
  • 我更喜欢If WorksheetFunction.CountA(sheet.Rows(i)) = 0 Then
  • Cells必须符合sheet的条件:sheet.Cells(i, 1)

重构代码

Function FindAllEmptyRows(sheet As Worksheet) As Variant
    Dim emptyRows() As Variant
    Dim i As Long, rowNumber As Long
    Dim rowCounter As Integer

    rowNumber = sheet.UsedRange.Rows.Count
    For i = rowNumber To 1 Step -1
        If sheet.Cells(i, 1).End(xlToRight).Column = sheet.Columns.Count And Cells(i, 1) = "" Then
            If rowCounter = 0 Then
                ReDim emptyRows(0)
            Else
                ReDim Preserve emptyRows(rowCounter)
            End If

            emptyRows(rowCounter) = i
            rowCounter = rowCounter + 1
        End If
    Next

    FindAllEmptyRows = emptyRows
End Function

SpecialCells

Range.SpecialCells()可用于将Range划分为满足特定条件的单元格区域。

MSDN - Range.SpecialCells Method (Excel)

  

返回一个Range对象,该对象表示与指定类型和值匹配的所有单元格

OZ Grid

  

根据我的经验,Excel中最有益的方法之一是SpecialCells方法。使用时,它返回一个Range对象,该对象仅表示我们指定的那些类型的单元格。例如,可以使用SpecialCells方法返回仅包含公式的Range对象。实际上,如果愿意,我们甚至可以进一步缩小范围,以使我们的Range Object(仅包含公式)仅返回有错误的公式。

检查这段代码的输出应该为您提供有关如何使用SpecialCells的好主意。

Sub SpecialFoo()
    Dim rArea As Range, rBlanks As Range, rFormulas As Range, rConstants As Range, rUnion As Range
    Dim sheet As Worksheet

    Set sheet = ActiveSheet
    On Error Resume Next
    Set rBlanks = sheet.UsedRange.SpecialCells(xlCellTypeBlanks)
    On Error GoTo 0

    If Not rBlanks Is Nothing Then
        For Each rArea In rBlanks.Areas
            Debug.Print "rBlanks Areas: "; rArea.Address
        Next
    End If

    On Error Resume Next
    Set rFormulas = sheet.UsedRange.SpecialCells(xlCellTypeFormulas)
    On Error GoTo 0

    If Not rFormulas Is Nothing Then
        For Each rArea In rFormulas.Areas
            Debug.Print "rFormulas Areas: "; rArea.Address
        Next
    End If

    On Error Resume Next
    Set rConstants = sheet.UsedRange.SpecialCells(xlCellTypeConstants)
    On Error GoTo 0

    If Not rConstants Is Nothing Then
        For Each rArea In rConstants.Areas
            Debug.Print "rConstants Areas: "; rArea.Address
        Next
    End If

    If Not rFormulas Is Nothing And Not rConstants Is Nothing Then
        Set rFormulas = Union(rConstants, rFormulas)
        For Each rArea In rFormulas.Areas
            Debug.Print "rUnion Areas: "; rArea.Address
        Next
    End If

End Sub

答案 1 :(得分:0)

使用前,您必须先调整emptyRows()的大小

此外,您可以使用WorksheetFunction.Count()检查当前行中的任何值

最终

Function FindAllEmptyRows(sheet As Worksheet) As Variant
    Dim emptyRows() As Variant
    Dim i As Long, rowNumber As Long, rowCounter As Long

    With sheet.UsedRange ' reference passed sheet UsedRange
        rowNumber = .Rows.Count
        ReDim emptyRows(0 To rowNumber - 1) ' dim the array to the maximum possible size
        For i = rowNumber To 1 Step -1 ' step through reference range rows from the last baxkwards to the first
            If WorksheetFunction.Count(.Rows(i)) = 0 Then
                emptyRows(rowCounter) = i + .Rows(1).Row - 1 ' fill array in current index with current row index
                rowCounter = rowCounter + 1 ' update array index
            End If
        Next
    End With
    ReDim Preserve emptyRows(0 To rowCounter) ' redim the array according to the actual number of found empty rows

    FindAllEmptyRows = emptyRows
End Function

请注意:

emptyRows(rowCounter) = i + .Rows(1).Row - 1

正在存储绝对行索引,即工作表行索引,而

emptyRows(rowCounter) = i 

将存储相对行索引,即带有UsedRange的行索引,该行索引可以从与第1行不同的行开始