创建范围时,xlCellTypeVisible不起作用

时间:2019-04-05 14:44:43

标签: excel vba

我正在尝试在Excel 2010中使用VBA创建仅适用于可见行的范围。我已经过滤掉了不需要的值,并且正在使用关键字xlCelltypeVisible,但是,当我对其进行测试时,范围仍显示该范围内的字段,应该将其隐藏。 / p>

我尝试了创建范围的几种不同方式,但似乎没有任何效果。看来xlCellTypevisible无效。

这不是我正在使用的实际工作表,但是出于演示目的,这恰好总结了我的问题所在:

Sub create_range()

    ActiveSheet.Range("$A$3:$C$8").AutoFilter Field:=3, Criteria1:="North"
    Set a = Range("A3", Range("A" & Rows.Count).End(xlUp)).SpecialCells(xlCellTypeVisible)

    MsgBox (a(3))



End Sub

在这种情况下,我有三列,A3 =“选择A”,B3 =“选择B”,C3 =“选择C”。

在选项A下,我有A,B,C,D,E 在选项B下,我有1,2,3,4,5 在选项C下,我有北,东,西,南,北

如您在上面的代码中所见,我已经在选项C的字段中过滤了“北方”的值。因此,在AI列中看到了“选项A”,“ A”,“ E”。

我的期望是,当我创建范围时,我可以选择这些选项,并且只能选择这些选项。但这是行不通的。如果选择a(1),我会正确地看到“ Opt A”为A3,这是我所期望的。但是当我选择第三个,并且应该是a(3)范围内的最终值时,我看到的是“ B”而不是“ E”。

Before filter

After filter

2 个答案:

答案 0 :(得分:1)

最佳做法是始终限定VBA中的所有对象。否则,可能会发生意外结果。

尝试一下:

Option Explicit 'always include this at top of your modules; it forces variable declaration and saves you from massive headaches :)

Sub create_range()

    Dim mySheet as Worksheet
    Set mySheet = Worksheets("Sheet1") 'change as needed

    With mySheet

       .Range("$A$3:$C$8").AutoFilter Field:=3, Criteria1:="North"

        Dim a as Range 'you need to declare as a range, since you are setting it to a range object
        Set a = .Range("A3", .Range("A" & Rows.Count).End(xlUp)).SpecialCells(xlCellTypeVisible)

       MsgBox a.Areas.Item(1).Cells(1,1).Value 'first cell

       Dim lastA as Range 'in case the last area is contiguous
       Set lastA = a.Areas.Item(a.Areas.Count)
       Msgbox lastA.Cells(lastA.Rows.Count,1) 'last cell

   End With

End Sub

答案 1 :(得分:1)

此问题是由Excel处理2种事物的方式引起的:超出定义范围的单元格和不连续的范围

首先:如果我定义rng = Range("A1:B2"),然后调用MsgBox rng.Cells(3,3).Address,它将给我“ C3”-即使这不是该范围的 部分。 Excel会自动查找超出范围的

第二个例子:在您的示例中,MsgBox a.Address将给出“ A3:A4,A8”-范围为2 areasA3:A4A8)。当您尝试没有指定区域时,它默认使用 first 区域(A3:A4)-然后,按照第一点,扩大范围找到一个值。

这是一个粗糙的函数,用于在不连续的列中返回 n th 单元格:

Function NthCellInColumn(ByRef Target As Range, ByRef Cell As Long) As Range
    Dim DiscardedCells As Long, WhichArea As Long

    DiscardedCells = 0
    For WhichArea = 1 To Target.Areas.Count
        'Is the cell in this area?
        If Cell <= DiscardedCells + Target.Areas(WhichArea).Cells.Count Then
            'Yes, so let's find it
            Set NthCellInColumn = Target.Areas(WhichArea).Cells(Cell - DiscardedCells, 1)
            Exit For 'Stop looping through areas
        Else
            'No, so Discard the Cells
            DiscardedCells = DiscardedCells + Target.Areas(WhichArea).Cells.Count
        End If
    Next WhichArea
End Function

像这样使用它:MsgBox NthCellInColumn(a,3).Value