代码之家  ›  专栏  ›  技术社区  ›  Greedo

为什么一个范围显然是一个数组?

  •  2
  • Greedo  · 技术社区  · 6 年前

    在Excel VBA中

    IsArray(Range("A1:A5"))
    

    会回来的 True 对于包含多个单元格的任何范围(据我所知)。

    这是为什么?同样的情况也不适用于其他可迭代对象,如 Collection ArrayList . 如何修改数组检查代码以返回 真的 仅用于数组,而不是类似数组的对象?

    2 回复  |  直到 6 年前
        1
  •  4
  •   Mathieu Guindon    6 年前

    一个 Range 是一个物体。

    Debug.Print TypeName(Range("A1:A5")) ' prints "Range"
    

    你所做的是 隐式默认成员调用 ,调用 Range.[_Default] ,这可以归结为调用 Range.Value ,返回二维数组 多单元 范围。

    object  browser showing hidden default member of Excel.Range

    Debug.Print IsArray(Range("A1").Value)    ' prints "False"
    Debug.Print IsArray(Range("A1:A2").Value) ' prints "True"
    

    默认的成员调用是“在背后”进行的,因为VBA“很有帮助”,并且看到您正在调用 IsArray(someObjectReference) ,转到该界面 someObjectReference ,看到它有一个默认成员,并计算 IsArray(someObjectReference.DefaultMember) 而不是 IsArray(someObjectReference) ,这将不有用(对象引用 明显地 不是数组。。。对吧?).

    对于其他公开 默认成员 . 是 Application String ?

    Debug.Print Application ' prints "Microsoft Excel"
    

    object browser showing hidden default member of Excel.Application

    当然不是-它是一个对象,但是有一个默认成员,当被调用时,可以归结为调用 Name 属性getter。

    当指定对象引用时 Set 关键字是必需的:

    Dim foo As Variant
    Set foo = Range("A1")
    

    没有 关键字,相同的代码将分配给返回对象的 默认成员 :

    Dim foo As Variant
    foo = Range("A1") '.Value is implicit
    

    编写代码 言行一致,言行一致 -尽可能避免隐式默认成员调用。

        2
  •  0
  •   JNevill    6 年前

    你可以使用 TypeOf 确定这一点的功能:

    Function arrayIsRange(arr As Variant) As Boolean
        arrayIsRange = TypeOf arr Is Excel.Range
    End Function
    

    使用中:

    Sub test()
        'prints "True"
        Debug.Print arrayIsRange(Range("A1:C3"))
    
    
        arr = Array(1, 2, 3)
        'prints "False"
        Debug.Print arrayIsRange(arr)
    End Sub