我正在尝试在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”。
答案 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 areas(A3:A4
和A8
)。当您尝试没有指定区域时,它默认使用 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