Excel VBA - 自动过滤的行计数始终返回1

时间:2017-05-15 15:33:54

标签: excel vba excel-vba range autofilter

我目前正在使用自动过滤器来过滤两列。如果autofilter的结果仅对可见单元格为空,则会添加一个新行。如果找到除标题之外的任何行,它将显示一个MsgBox。问题是行数总是返回1.我尝试重新定义“rng”几种方法无济于事。

Dim ws As Worksheet
Dim rng As Range

Set ws = Sheets("Scored Items")

Worksheets("Scored Items").Activate

ws.AutoFilterMode = False

With ws

    .Range("A:D").AutoFilter Field:=1, Criteria1:=AssetBox.Text
    .Range("A:D").AutoFilter Field:=4, Criteria1:=PartBox.Text

    Set rng = .Range("A:A").SpecialCells(xlCellTypeVisible)

    If (rng.Rows.Count = 1) Then
        'Add new row based on VBA form
    Else
        MsgBox "Item has already been scored"
    End If
End With

ws.Cells.AutoFilter

2 个答案:

答案 0 :(得分:4)

如果范围对象是非连续的,那么.Rows.Count只会返回范围的第一个Area中的行数,在这种情况下,它将是"标题&# 34;行。 (注意:如果您的过滤器是第一个数据行可见,但第二行不可见,那么您将得到2

使用过滤范围时,您需要迭代范围内的Areas

    Dim aRange as Range
    For Each aRange in rng.Areas
        If (aRange.Rows.Count = 1) Then
            'Add new row based on VBA form
        Else
            MsgBox "Item has already been scored"
        End If
    Next

在这种情况下,如果Areas.Count > 2以及任何aRange.Rows.Count <> 1等等,您可能想要标记一些错误。

如果您仅仅使用AutoFilter来检查此范围内是否存在值(即,为了防止表格中出现重复的条目?),这是一种相当笨重的方法它可能会更好地使用COUNTIF函数。

If Application.WorksheetFunction.CountIf(.Range("A:A"),AssetBox.Text) = 1 And _
    Application.WorksheetFunction.CountIf(.Range("D:D"), PartBox.Text) = 1 Then
    'Add new row based on VBA Form
Else
    MsgBox "Item has already been scored"
End If

评论的后续行动,因为这是一个用户界面,我会使用两个。显然,您希望AutoFilter向用户显示数据,因此请保留该数据。但是,不要试图破解过滤数据的各种Areas,只需使用COUNTIF函数检查

'Filter data to display to the user
Dim dataRange As Range
Set dataRange = ws.Range("A:D")
With dataRange
    .AutoFilter Field:=1, Criteria1:=AssetBox.Text
    .AutoFilter Field:=4, Criteria1:=PartBox.Text

    'Check if part already been scored
    With Application.WorksheetFunction
    If .CountIf(.Columns(1), AssetBox.Text) = 1 And _
        .CountIf(.Columns(4), PartBox.Text) = 1 Then
        'Add new row based on VBA Form
    Else
        MsgBox "Item has already been scored"
    End If
End With
'unfilter the data
ws.Cells.AutoFilter

答案 1 :(得分:2)

不要检查Rows.Count,而是检查Cells.Count是否有可见的行。 试试吧......

Dim ws As Worksheet
Dim rng As Range
Dim lr As Long
Set ws = Sheets("Scored Items")
lr = ws.UsedRange.Rows.Count

Worksheets("Scored Items").Activate

ws.AutoFilterMode = False

With ws
    .Range("A1:D" & lr).AutoFilter Field:=1, Criteria1:=AssetBox.Text
    .Range("A1:D" & lr).AutoFilter Field:=4, Criteria1:=PartBox.Text
    Set rng = .Range("A1:A" & lr).SpecialCells(xlCellTypeVisible)

    If rng.Cells.Count = 1 Then
        'Add new row based on VBA form
    Else
        MsgBox "Item has already been scored"
    End If
End With
ws.AutoFilterMode = False