为什么我可以引用不存在的范围内的单元格,以及如何找到最后一个单元格?

时间:2013-11-17 19:30:44

标签: excel excel-vba excel-2003 vba

这可能有点难以解释,所以我写了一些代码来演示。它应该粘贴并运行...

但简而言之,如果我设置一个分割范围(示例中为“A1:A5,A7:A11”)并按索引引用单元格,则该范围内不应存在单元格。即A6和细胞A12及以后。

任何人都可以解释为什么会这样,以及如何获得范围内的最后一个单元格? (在这种情况下应该是11澳元)

Public Sub RangeTest()

Dim ws As Worksheet
Dim rangeString As String
Dim testRange As Range

Dim count As Integer

Set ws = Sheet1

rangeString = "A1:A5,A7:A11"

Set testRange = ws.Range(rangeString)

Debug.Print "testRange.Range is " & testRange.Address
Debug.Print ""

For Each cell In testRange
count = count + 1
Debug.Print "Cell no:" & count & " address: " & cell.Address

    If count = 6 Then
    Debug.Print ""
    Debug.Print "No cell $A$6$ in testRange"
    Debug.Print ""
    End If

Next cell

Debug.Print ""
Debug.Print "count is equal to range.Count: " & (count = testRange.count)
Debug.Print ""
Debug.Print "rng.Count is " & testRange.count
Debug.Print ""

count = 0

Dim str As String

'why doesn't this give me subscript out of range???
    For i = 1 To testRange.count + 10
        count = count + 1
        str = "Cell no: " & count & " address: " & testRange(i).Address

        If count = 6 Then
        Debug.Print ""
        Debug.Print "Now cell $A$6$ is in the testRange"
        Debug.Print ""
        End If

        If i > testRange.count Then str = str & " ??? (the range only has " & testRange.count & " cells)"
        Debug.Print str
    Next i

Debug.Print
Debug.Print "Cell number 6 = " & testRange(6).Address
Debug.Print ""
Debug.Print "doesn't matter if we use .Cells: " & testRange.Cells(6).Address

Debug.Print testRange.Cells(6).Address & " shouldn't exist in range " & testRange.Address
Debug.Print ""
Debug.Print "using testRange.Count as index we get " & testRange(testRange.count).Address


Debug.Print ""
Debug.Print "And using SpecialCells(xlCellTypeLastCell)"
Debug.Print "the last cell of the range is......"
Debug.Print ""
Debug.Print testRange.SpecialCells(xlCellTypeLastCell).Address & " ???"


End Sub

这给我的计算机的下面输出让我挠头了......我在excel 2003上,但我有兴趣知道excel的后续版本是否会给出相同的结果。

testRange.Range is $A$1:$A$5,$A$7:$A$11

Cell no:1 address: $A$1
Cell no:2 address: $A$2
Cell no:3 address: $A$3
Cell no:4 address: $A$4
Cell no:5 address: $A$5
Cell no:6 address: $A$7

No cell $A$6$ in testRange

Cell no:7 address: $A$8
Cell no:8 address: $A$9
Cell no:9 address: $A$10
Cell no:10 address: $A$11

count is equal to range.Count: True

rng.Count is 10

Cell no: 1 address: $A$1
Cell no: 2 address: $A$2
Cell no: 3 address: $A$3
Cell no: 4 address: $A$4
Cell no: 5 address: $A$5

Now cell $A$6$ is in the testRange

Cell no: 6 address: $A$6
Cell no: 7 address: $A$7
Cell no: 8 address: $A$8
Cell no: 9 address: $A$9
Cell no: 10 address: $A$10
Cell no: 11 address: $A$11 ??? (the range only has 10 cells)
Cell no: 12 address: $A$12 ??? (the range only has 10 cells)
Cell no: 13 address: $A$13 ??? (the range only has 10 cells)
Cell no: 14 address: $A$14 ??? (the range only has 10 cells)
Cell no: 15 address: $A$15 ??? (the range only has 10 cells)
Cell no: 16 address: $A$16 ??? (the range only has 10 cells)
Cell no: 17 address: $A$17 ??? (the range only has 10 cells)
Cell no: 18 address: $A$18 ??? (the range only has 10 cells)
Cell no: 19 address: $A$19 ??? (the range only has 10 cells)
Cell no: 20 address: $A$20 ??? (the range only has 10 cells)

Cell number 6 = $A$6

doesn't matter if we use .Cells: $A$6
$A$6 shouldn't exist in range $A$1:$A$5,$A$7:$A$11

using testRange.Count as index we get $A$10

And using SpecialCells(xlCellTypeLastCell)
the last cell of the range is......

$C$20 ???

2 个答案:

答案 0 :(得分:1)

一种方法是遍历范围:

Public Function LastCell(rng As Range) As String
    Dim s As String
    For Each r In rng
        s = r.Address(0, 0)
    Next r
    LastCell = s
End Function

Sub MAIN()
    Dim rangeString As String, testRange As Range
    rangeString = "A1:A5,A7:A11"
    Set testRange = Range(rangeString)
    MsgBox LastCell(testRange)
End Sub

可能有更有效的解决方案。

答案 1 :(得分:1)

您需要使用For Each...Next循环来遍历范围中的每个单元格。当您按照代码中的方式使用计数器时,实际上并不是将其限制为testrange。当你考虑计数器应该做什么时,你真的只是给它一个起点。你基本上是告诉它从testrange开始,然后走到这一步。

这就是我们可以使用不同循环的原因。每一个都略有不同,可以做一些略有不同的事情。 For Each...Next循环允许您将循环限制为您指定范围内的单元格。但是,当你使用计数器时,它不想跳过任何东西(比如单元格$ A $ 6),而不是转到范围内的第六个单元格(因为看起来你打算用你的代码说),它会去到第六个单元来自范围的起点。