Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.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
Excel VBA-自动筛选行计数始终返回1_Vba_Excel_Range_Autofilter - Fatal编程技术网

Excel VBA-自动筛选行计数始终返回1

Excel VBA-自动筛选行计数始终返回1,vba,excel,range,autofilter,Vba,Excel,Range,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

我目前正在使用自动筛选对两列进行筛选。如果只有可见单元格的自动筛选结果为空,则会添加新行。如果找到除标题以外的任何行,它将显示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

如果范围对象是非连续的,则than.Rows.Count将只返回范围第一个区域中的行数,在本例中为标题行。注意:如果您的筛选器使第一行数据可见,而第二行数据不可见,则结果为2

使用过滤范围时,需要迭代范围中的区域

    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
跟进你的评论,因为这是一个用户界面,我会使用两者。显然,您希望自动筛选向用户显示数据,所以请保留该选项。但是,与其尝试对过滤数据的各个区域进行黑客攻击,不如使用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

检查可见行的单元格数,而不是检查行数。 像这样试试

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

谢谢你的回复。我选择使用autofilter进行此操作的部分原因是为了显示使用工具的个人,该工具中的记录已作为匹配项存在。如果需要,我可能会添加用新条目覆盖的功能。@Sedako当然,这是有意义的!如果答案已经解决了你的问题,请考虑这个解决方案也很好,有点干净。谢谢